From 90d942487e160d2d7d116825fb10431f13129cd7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 17 Dec 2023 23:20:41 +0100 Subject: [PATCH 001/356] Move REST API into sandbox --- .../ext/geocoder/GeocoderResource.java | 2 +- .../mapping/AbsoluteDirectionMapper.java | 4 +- .../ext/restapi}/mapping/AgencyMapper.java | 4 +- .../ext/restapi}/mapping/AlertMapper.java | 4 +- .../restapi}/mapping/BikeAccessMapper.java | 2 +- .../restapi}/mapping/BookingInfoMapper.java | 4 +- .../restapi}/mapping/BookingMethodMapper.java | 2 +- .../restapi}/mapping/BookingTimeMapper.java | 4 +- .../restapi}/mapping/ContactInfoMapper.java | 4 +- .../ext/restapi}/mapping/DirectionMapper.java | 2 +- .../ext/restapi}/mapping/ElevationMapper.java | 2 +- .../ext/restapi}/mapping/FareMapper.java | 16 +++--- .../ext/restapi}/mapping/FeedInfoMapper.java | 4 +- .../restapi}/mapping/FeedScopedIdMapper.java | 2 +- .../restapi}/mapping/I18NStringMapper.java | 2 +- .../ext/restapi}/mapping/ItineraryMapper.java | 4 +- .../ext/restapi}/mapping/LegMapper.java | 8 +-- .../ext/restapi}/mapping/LocalDateMapper.java | 2 +- .../ext/restapi}/mapping/ModeMapper.java | 2 +- .../ext/restapi}/mapping/PlaceMapper.java | 8 +-- .../mapping/RelativeDirectionMapper.java | 4 +- .../ext/restapi}/mapping/RouteMapper.java | 6 +-- .../ext/restapi}/mapping/RouteTypeMapper.java | 2 +- .../ext/restapi}/mapping/StopMapper.java | 6 +-- .../mapping/StopTimesInPatternMapper.java | 4 +- .../mapping/StreetNoteMaperMapper.java | 4 +- .../restapi}/mapping/SystemNoticeMapper.java | 4 +- .../ext/restapi}/mapping/TransferMapper.java | 4 +- .../ext/restapi}/mapping/TripMapper.java | 6 +-- .../restapi}/mapping/TripPatternMapper.java | 6 +-- .../ext/restapi}/mapping/TripPlanMapper.java | 4 +- .../mapping/TripSearchMetadataMapper.java | 4 +- .../ext/restapi}/mapping/TripTimeMapper.java | 6 +-- .../mapping/VehicleRentalStationMapper.java | 4 +- .../restapi}/mapping/VertexTypeMapper.java | 4 +- .../ext/restapi}/mapping/WalkStepMapper.java | 8 +-- .../WheelchairAccessibilityMapper.java | 2 +- .../restapi}/model/ApiAbsoluteDirection.java | 2 +- .../ext/restapi}/model/ApiAgency.java | 2 +- .../ext/restapi}/model/ApiAlert.java | 2 +- .../ext/restapi}/model/ApiBookingInfo.java | 2 +- .../ext/restapi}/model/ApiBookingTime.java | 2 +- .../ext/restapi}/model/ApiContactInfo.java | 2 +- .../ext/restapi}/model/ApiCurrency.java | 2 +- .../ext/restapi}/model/ApiFareComponent.java | 3 +- .../ext/restapi}/model/ApiFareProduct.java | 2 +- .../ext/restapi}/model/ApiFareQualifier.java | 2 +- .../ext/restapi}/model/ApiFeedInfo.java | 2 +- .../ext/restapi}/model/ApiItinerary.java | 2 +- .../ext/restapi}/model/ApiItineraryFares.java | 2 +- .../ext/restapi}/model/ApiLeg.java | 2 +- .../ext/restapi}/model/ApiLegProducts.java | 2 +- .../ext/restapi}/model/ApiMoney.java | 2 +- .../ext/restapi}/model/ApiPatternDetail.java | 2 +- .../ext/restapi}/model/ApiPatternShort.java | 2 +- .../ext/restapi}/model/ApiPlace.java | 2 +- .../ext/restapi}/model/ApiRealTimeState.java | 2 +- .../restapi}/model/ApiRelativeDirection.java | 2 +- .../ext/restapi}/model/ApiRoute.java | 2 +- .../ext/restapi}/model/ApiRouteShort.java | 2 +- .../ext/restapi}/model/ApiRouterInfo.java | 4 +- .../ext/restapi}/model/ApiRouterList.java | 2 +- .../ext/restapi}/model/ApiStop.java | 2 +- .../ext/restapi}/model/ApiStopShort.java | 2 +- .../restapi}/model/ApiStopTimesInPattern.java | 2 +- .../ext/restapi}/model/ApiSystemNotice.java | 2 +- .../ext/restapi}/model/ApiTransfer.java | 2 +- .../ext/restapi}/model/ApiTravelOption.java | 2 +- .../restapi}/model/ApiTravelOptionsMaker.java | 2 +- .../ext/restapi}/model/ApiTrip.java | 2 +- .../ext/restapi}/model/ApiTripPlan.java | 2 +- .../restapi}/model/ApiTripSearchMetadata.java | 2 +- .../ext/restapi}/model/ApiTripShort.java | 2 +- .../ext/restapi}/model/ApiTripTimeShort.java | 2 +- .../model/ApiVehicleParkingSpaces.java | 2 +- .../model/ApiVehicleParkingWithEntrance.java | 2 +- .../model/ApiVehicleRentalStation.java | 2 +- .../model/ApiVehicleRentalStationList.java | 2 +- .../ext/restapi}/model/ApiVertexType.java | 2 +- .../ext/restapi}/model/ApiWalkStep.java | 2 +- .../ext/restapi/model}/ElevationMetadata.java | 2 +- .../restapi/model}/TripPlannerResponse.java | 5 +- .../restapi}/model/error/PlannerError.java | 0 .../model/serverinfo/ApiConfigInfo.java | 0 .../model/serverinfo/ApiProjectVersion.java | 0 .../model/serverinfo/ApiServerInfo.java | 0 .../serverinfo/ApiVersionControlInfo.java | 0 .../ext/restapi/resources}/BikeRental.java | 8 +-- .../ext/restapi/resources}/IndexAPI.java | 52 +++++++++---------- .../restapi/resources}/PlannerResource.java | 11 ++-- .../RequestToPreferencesMapper.java | 2 +- .../ext/restapi/resources}/Routers.java | 6 +-- .../restapi/resources}/RoutingResource.java | 4 +- .../resources}/ValidateParameters.java | 2 +- .../ext/restapi/resources}/package-info.java | 2 +- .../ext/vectortiles/VectorTilesResource.java | 2 +- .../DigitransitStationPropertyMapper.java | 4 +- .../layers/stations/StationsLayerBuilder.java | 2 +- .../stops/DigitransitStopPropertyMapper.java | 4 +- .../layers/stops/StopsLayerBuilder.java | 2 +- ...nsitVehicleParkingGroupPropertyMapper.java | 4 +- ...gitransitVehicleParkingPropertyMapper.java | 4 +- ...StadtnaviVehicleParkingPropertyMapper.java | 4 +- .../VehicleParkingGroupsLayerBuilder.java | 2 +- .../VehicleParkingsLayerBuilder.java | 2 +- .../VehicleRentalLayerBuilder.java | 2 +- ...imeVehicleRentalStationPropertyMapper.java | 4 +- ...igitransitRentalVehiclePropertyMapper.java | 2 +- ...igitransitVehicleRentalPropertyMapper.java | 4 +- ...sitVehicleRentalStationPropertyMapper.java | 4 +- .../java/org/opentripplanner/api/package.md | 8 --- .../GraphInspectorVectorTileResource.java | 2 +- .../configuration => apis}/APIEndpoints.java | 10 ++-- .../support => apis/common}/SemanticHash.java | 2 +- .../{api/model => apis/common}/TileJson.java | 2 +- .../json/FeedScopedIdDeserializer.java | 2 +- .../json/FeedScopedIdKeyDeserializer.java | 2 +- .../common}/json/FeedScopedIdSerializer.java | 2 +- .../json/GraphQLResponseSerializer.java | 2 +- .../json/JSONObjectMapperProvider.java | 2 +- .../common}/mapping/PlannerErrorMapper.java | 2 +- .../common}/mapping/PropertyMapper.java | 2 +- .../apis/gtfs/GtfsGraphQLAPI.java | 2 +- .../apis/gtfs/GtfsGraphQLIndex.java | 2 +- .../apis/gtfs/datafetchers/LegImpl.java | 2 +- .../apis/gtfs/datafetchers/PatternImpl.java | 2 +- .../apis/gtfs/datafetchers/PlanImpl.java | 2 +- .../gtfs/datafetchers/RoutingErrorImpl.java | 2 +- .../apis/gtfs/datafetchers/TripImpl.java | 2 +- .../apis/gtfs/mapping/StreetNoteMapper.java | 2 +- .../model/plan/RoutingErrorType.java | 2 +- .../apis/transmodel/model/plan/TripType.java | 2 +- .../support/ExecutionResultMapper.java | 2 +- .../vector/AreaStopsLayerBuilder.java | 2 +- .../DebugClientAreaStopPropertyMapper.java | 4 +- .../inspector/vector/LayerBuilder.java | 2 +- .../inspector/vector/LayerParameters.java | 2 +- .../GeofencingZonesLayerBuilder.java | 2 +- .../GeofencingZonesPropertyMapper.java | 2 +- .../routing/error/PathNotFoundException.java | 4 +- .../standalone/server/OTPWebApplication.java | 6 +-- .../api/mapping/EnumMapperTest.java | 9 ++-- .../api/mapping/FareMapperTest.java | 1 + .../model/ApiApiTravelOptionsMakerTest.java | 2 + .../api/model/ApiWalkStepTest.java | 2 +- .../resources}/PlannerResourceTest.java | 3 +- .../algorithm/mapping/SnapshotTestBase.java | 4 +- 147 files changed, 245 insertions(+), 249 deletions(-) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/AbsoluteDirectionMapper.java (88%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/AgencyMapper.java (89%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/AlertMapper.java (92%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/BikeAccessMapper.java (86%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/BookingInfoMapper.java (88%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/BookingMethodMapper.java (94%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/BookingTimeMapper.java (71%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/ContactInfoMapper.java (80%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/DirectionMapper.java (83%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/ElevationMapper.java (92%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/FareMapper.java (89%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/FeedInfoMapper.java (84%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/FeedScopedIdMapper.java (95%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/I18NStringMapper.java (93%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/ItineraryMapper.java (94%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/LegMapper.java (96%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/LocalDateMapper.java (89%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/ModeMapper.java (97%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/PlaceMapper.java (94%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/RelativeDirectionMapper.java (91%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/RouteMapper.java (93%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/RouteTypeMapper.java (92%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/StopMapper.java (95%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/StopTimesInPatternMapper.java (86%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/StreetNoteMaperMapper.java (91%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/SystemNoticeMapper.java (87%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/TransferMapper.java (77%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/TripMapper.java (92%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/TripPatternMapper.java (88%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/TripPlanMapper.java (89%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/TripSearchMetadataMapper.java (85%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/TripTimeMapper.java (89%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/VehicleRentalStationMapper.java (88%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/VertexTypeMapper.java (83%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/WalkStepMapper.java (84%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/WheelchairAccessibilityMapper.java (87%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiAbsoluteDirection.java (79%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiAgency.java (93%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiAlert.java (83%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiBookingInfo.java (98%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiBookingTime.java (94%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiContactInfo.java (97%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiCurrency.java (71%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiFareComponent.java (76%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiFareProduct.java (91%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiFareQualifier.java (83%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiFeedInfo.java (93%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiItinerary.java (98%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiItineraryFares.java (92%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiLeg.java (99%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiLegProducts.java (88%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiMoney.java (56%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiPatternDetail.java (87%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiPatternShort.java (68%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiPlace.java (97%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiRealTimeState.java (96%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiRelativeDirection.java (90%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiRoute.java (95%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiRouteShort.java (85%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiRouterInfo.java (97%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiRouterList.java (75%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiStop.java (96%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiStopShort.java (92%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiStopTimesInPattern.java (74%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiSystemNotice.java (95%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTransfer.java (82%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTravelOption.java (97%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTravelOptionsMaker.java (98%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTrip.java (96%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTripPlan.java (90%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTripSearchMetadata.java (98%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTripShort.java (77%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiTripTimeShort.java (93%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiVehicleParkingSpaces.java (97%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiVehicleParkingWithEntrance.java (99%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiVehicleRentalStation.java (95%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiVehicleRentalStationList.java (78%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiVertexType.java (81%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/ApiWalkStep.java (98%) rename src/{main/java/org/opentripplanner/api/resource => ext/java/org/opentripplanner/ext/restapi/model}/ElevationMetadata.java (83%) rename src/{main/java/org/opentripplanner/api/resource => ext/java/org/opentripplanner/ext/restapi/model}/TripPlannerResponse.java (95%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/error/PlannerError.java (100%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/serverinfo/ApiConfigInfo.java (100%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/serverinfo/ApiProjectVersion.java (100%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/serverinfo/ApiServerInfo.java (100%) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/model/serverinfo/ApiVersionControlInfo.java (100%) rename src/{main/java/org/opentripplanner/api/resource => ext/java/org/opentripplanner/ext/restapi/resources}/BikeRental.java (91%) rename src/{main/java/org/opentripplanner/index => ext/java/org/opentripplanner/ext/restapi/resources}/IndexAPI.java (93%) rename src/{main/java/org/opentripplanner/api/resource => ext/java/org/opentripplanner/ext/restapi/resources}/PlannerResource.java (93%) rename src/{main/java/org/opentripplanner/api/common => ext/java/org/opentripplanner/ext/restapi/resources}/RequestToPreferencesMapper.java (99%) rename src/{main/java/org/opentripplanner/api/resource => ext/java/org/opentripplanner/ext/restapi/resources}/Routers.java (93%) rename src/{main/java/org/opentripplanner/api/common => ext/java/org/opentripplanner/ext/restapi/resources}/RoutingResource.java (99%) rename src/{main/java/org/opentripplanner/index => ext/java/org/opentripplanner/ext/restapi/resources}/ValidateParameters.java (96%) rename src/{main/java/org/opentripplanner/api/resource => ext/java/org/opentripplanner/ext/restapi/resources}/package-info.java (74%) delete mode 100644 src/main/java/org/opentripplanner/api/package.md rename src/main/java/org/opentripplanner/{api/configuration => apis}/APIEndpoints.java (93%) rename src/main/java/org/opentripplanner/{api/support => apis/common}/SemanticHash.java (99%) rename src/main/java/org/opentripplanner/{api/model => apis/common}/TileJson.java (97%) rename src/main/java/org/opentripplanner/{api => apis/common}/json/FeedScopedIdDeserializer.java (95%) rename src/main/java/org/opentripplanner/{api => apis/common}/json/FeedScopedIdKeyDeserializer.java (93%) rename src/main/java/org/opentripplanner/{api => apis/common}/json/FeedScopedIdSerializer.java (97%) rename src/main/java/org/opentripplanner/{api => apis/common}/json/GraphQLResponseSerializer.java (97%) rename src/main/java/org/opentripplanner/{api => apis/common}/json/JSONObjectMapperProvider.java (98%) rename src/main/java/org/opentripplanner/{api => apis/common}/mapping/PlannerErrorMapper.java (97%) rename src/main/java/org/opentripplanner/{api => apis/common}/mapping/PropertyMapper.java (96%) rename src/test/java/org/opentripplanner/{api/common => ext/restapi/resources}/PlannerResourceTest.java (95%) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java index d2eafc91e5c..39ed6da297c 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java @@ -14,7 +14,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.FeedScopedIdMapper; +import org.opentripplanner.ext.restapi.mapping.FeedScopedIdMapper; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.site.StopLocation; diff --git a/src/main/java/org/opentripplanner/api/mapping/AbsoluteDirectionMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/AbsoluteDirectionMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java index 59bb0d77955..8500323c032 100644 --- a/src/main/java/org/opentripplanner/api/mapping/AbsoluteDirectionMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AbsoluteDirectionMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiAbsoluteDirection; +import org.opentripplanner.ext.restapi.model.ApiAbsoluteDirection; import org.opentripplanner.model.plan.AbsoluteDirection; public class AbsoluteDirectionMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/AgencyMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/AgencyMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java index 9600400d373..4ea3ebb5209 100644 --- a/src/main/java/org/opentripplanner/api/mapping/AgencyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AgencyMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiAgency; +import org.opentripplanner.ext.restapi.model.ApiAgency; import org.opentripplanner.transit.model.organization.Agency; public class AgencyMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/AlertMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/AlertMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java index e01961a5dca..8fbfa71111f 100644 --- a/src/main/java/org/opentripplanner/api/mapping/AlertMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/AlertMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.Instant; import java.util.Collection; @@ -7,7 +7,7 @@ import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.routing.alertpatch.TransitAlert; public class AlertMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/BikeAccessMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/api/mapping/BikeAccessMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java index 43c00ef8227..3ceb86b4459 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BikeAccessMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BikeAccessMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.network.BikeAccess; diff --git a/src/main/java/org/opentripplanner/api/mapping/BookingInfoMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/BookingInfoMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java index 4f1eb0c6249..4aa8b4a46b1 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BookingInfoMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingInfoMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiBookingInfo; +import org.opentripplanner.ext.restapi.model.ApiBookingInfo; import org.opentripplanner.model.BookingInfo; public class BookingInfoMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/BookingMethodMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/api/mapping/BookingMethodMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java index b938c1813d2..9b61ff39543 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BookingMethodMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingMethodMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.EnumSet; import java.util.Set; diff --git a/src/main/java/org/opentripplanner/api/mapping/BookingTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java similarity index 71% rename from src/main/java/org/opentripplanner/api/mapping/BookingTimeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java index 3a779cbeed4..e40309e9137 100644 --- a/src/main/java/org/opentripplanner/api/mapping/BookingTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/BookingTimeMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiBookingTime; +import org.opentripplanner.ext.restapi.model.ApiBookingTime; import org.opentripplanner.model.BookingTime; public class BookingTimeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/ContactInfoMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java similarity index 80% rename from src/main/java/org/opentripplanner/api/mapping/ContactInfoMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java index d12a06f8e30..452e15a0cb5 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ContactInfoMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ContactInfoMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiContactInfo; +import org.opentripplanner.ext.restapi.model.ApiContactInfo; import org.opentripplanner.transit.model.organization.ContactInfo; public class ContactInfoMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/DirectionMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java similarity index 83% rename from src/main/java/org/opentripplanner/api/mapping/DirectionMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java index 22decc21f81..ea510b1fdc7 100644 --- a/src/main/java/org/opentripplanner/api/mapping/DirectionMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/DirectionMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.timetable.Direction; diff --git a/src/main/java/org/opentripplanner/api/mapping/ElevationMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/ElevationMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java index de5c9f46fdb..192848f04d6 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ElevationMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ElevationMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.model.plan.ElevationProfile; diff --git a/src/main/java/org/opentripplanner/api/mapping/FareMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/FareMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java index 4d682a1d32c..a6020c6bf37 100644 --- a/src/main/java/org/opentripplanner/api/mapping/FareMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import com.google.common.collect.Multimap; import java.util.AbstractMap.SimpleEntry; @@ -10,13 +10,13 @@ import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.opentripplanner.api.model.ApiCurrency; -import org.opentripplanner.api.model.ApiFareComponent; -import org.opentripplanner.api.model.ApiFareProduct; -import org.opentripplanner.api.model.ApiFareQualifier; -import org.opentripplanner.api.model.ApiItineraryFares; -import org.opentripplanner.api.model.ApiLegProducts; -import org.opentripplanner.api.model.ApiMoney; +import org.opentripplanner.ext.restapi.model.ApiCurrency; +import org.opentripplanner.ext.restapi.model.ApiFareComponent; +import org.opentripplanner.ext.restapi.model.ApiFareProduct; +import org.opentripplanner.ext.restapi.model.ApiFareQualifier; +import org.opentripplanner.ext.restapi.model.ApiItineraryFares; +import org.opentripplanner.ext.restapi.model.ApiLegProducts; +import org.opentripplanner.ext.restapi.model.ApiMoney; import org.opentripplanner.model.fare.FareMedium; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.model.fare.FareProductUse; diff --git a/src/main/java/org/opentripplanner/api/mapping/FeedInfoMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java similarity index 84% rename from src/main/java/org/opentripplanner/api/mapping/FeedInfoMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java index b8262d726fe..203ade5749e 100644 --- a/src/main/java/org/opentripplanner/api/mapping/FeedInfoMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedInfoMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiFeedInfo; +import org.opentripplanner.ext.restapi.model.ApiFeedInfo; import org.opentripplanner.model.FeedInfo; public class FeedInfoMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/FeedScopedIdMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/api/mapping/FeedScopedIdMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java index d33d7c53bc1..619c306fbbc 100644 --- a/src/main/java/org/opentripplanner/api/mapping/FeedScopedIdMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FeedScopedIdMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import jakarta.ws.rs.BadRequestException; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; diff --git a/src/main/java/org/opentripplanner/api/mapping/I18NStringMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/I18NStringMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/api/mapping/I18NStringMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/I18NStringMapper.java index 6b40a07b953..f7adef24108 100644 --- a/src/main/java/org/opentripplanner/api/mapping/I18NStringMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/I18NStringMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Locale; import javax.annotation.Nonnull; diff --git a/src/main/java/org/opentripplanner/api/mapping/ItineraryMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/api/mapping/ItineraryMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java index cf14eda73dd..d87cf33d71c 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ItineraryMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ItineraryMapper.java @@ -1,11 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiItinerary; +import org.opentripplanner.ext.restapi.model.ApiItinerary; import org.opentripplanner.model.plan.Itinerary; public class ItineraryMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/LegMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/api/mapping/LegMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java index cc139e5180d..91b41c8ff81 100644 --- a/src/main/java/org/opentripplanner/api/mapping/LegMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java @@ -1,14 +1,14 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import static org.opentripplanner.api.mapping.ElevationMapper.mapElevation; +import static org.opentripplanner.ext.restapi.mapping.ElevationMapper.mapElevation; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.model.ApiAlert; -import org.opentripplanner.api.model.ApiLeg; +import org.opentripplanner.ext.restapi.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiLeg; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.plan.Leg; diff --git a/src/main/java/org/opentripplanner/api/mapping/LocalDateMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/LocalDateMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java index 334efa8c6e8..940bcc13d54 100644 --- a/src/main/java/org/opentripplanner/api/mapping/LocalDateMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LocalDateMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.LocalDate; import org.opentripplanner.framework.time.ServiceDateUtils; diff --git a/src/main/java/org/opentripplanner/api/mapping/ModeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/api/mapping/ModeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java index 3276de080c3..49bd2619149 100644 --- a/src/main/java/org/opentripplanner/api/mapping/ModeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/ModeMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.Set; diff --git a/src/main/java/org/opentripplanner/api/mapping/PlaceMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java similarity index 94% rename from src/main/java/org/opentripplanner/api/mapping/PlaceMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java index e806c5615d2..3ebdc678f1e 100644 --- a/src/main/java/org/opentripplanner/api/mapping/PlaceMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -8,9 +8,9 @@ import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiPlace; -import org.opentripplanner.api.model.ApiVehicleParkingSpaces; -import org.opentripplanner.api.model.ApiVehicleParkingWithEntrance; +import org.opentripplanner.ext.restapi.model.ApiPlace; +import org.opentripplanner.ext.restapi.model.ApiVehicleParkingSpaces; +import org.opentripplanner.ext.restapi.model.ApiVehicleParkingWithEntrance; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.VehicleParkingWithEntrance; diff --git a/src/main/java/org/opentripplanner/api/mapping/RelativeDirectionMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java similarity index 91% rename from src/main/java/org/opentripplanner/api/mapping/RelativeDirectionMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java index 78c4495292c..a1bdd145a55 100644 --- a/src/main/java/org/opentripplanner/api/mapping/RelativeDirectionMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiRelativeDirection; +import org.opentripplanner.ext.restapi.model.ApiRelativeDirection; import org.opentripplanner.model.plan.RelativeDirection; public class RelativeDirectionMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/RouteMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java similarity index 93% rename from src/main/java/org/opentripplanner/api/mapping/RouteMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java index f64a350092c..374fad1e94b 100644 --- a/src/main/java/org/opentripplanner/api/mapping/RouteMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java @@ -1,10 +1,10 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiRoute; -import org.opentripplanner.api.model.ApiRouteShort; +import org.opentripplanner.ext.restapi.model.ApiRoute; +import org.opentripplanner.ext.restapi.model.ApiRouteShort; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Branding; diff --git a/src/main/java/org/opentripplanner/api/mapping/RouteTypeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/RouteTypeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java index af300b1d39a..9dede395e80 100644 --- a/src/main/java/org/opentripplanner/api/mapping/RouteTypeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteTypeMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.basic.TransitMode; diff --git a/src/main/java/org/opentripplanner/api/mapping/StopMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/api/mapping/StopMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java index 954584fd76f..7dc911120d5 100644 --- a/src/main/java/org/opentripplanner/api/mapping/StopMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java @@ -1,10 +1,10 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiStop; -import org.opentripplanner.api.model.ApiStopShort; +import org.opentripplanner.ext.restapi.model.ApiStop; +import org.opentripplanner.ext.restapi.model.ApiStopShort; import org.opentripplanner.transit.model.site.StopLocation; public class StopMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/StopTimesInPatternMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java similarity index 86% rename from src/main/java/org/opentripplanner/api/mapping/StopTimesInPatternMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java index 66da0071959..d917bac9203 100644 --- a/src/main/java/org/opentripplanner/api/mapping/StopTimesInPatternMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopTimesInPatternMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiStopTimesInPattern; +import org.opentripplanner.ext.restapi.model.ApiStopTimesInPattern; import org.opentripplanner.model.StopTimesInPattern; public class StopTimesInPatternMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/StreetNoteMaperMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java similarity index 91% rename from src/main/java/org/opentripplanner/api/mapping/StreetNoteMaperMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java index 9ee44d102bb..62926eb6e18 100644 --- a/src/main/java/org/opentripplanner/api/mapping/StreetNoteMaperMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java @@ -1,10 +1,10 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.street.model.note.StreetNote; public class StreetNoteMaperMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/SystemNoticeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java similarity index 87% rename from src/main/java/org/opentripplanner/api/mapping/SystemNoticeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java index f30a62d2d97..1c79a4a7074 100644 --- a/src/main/java/org/opentripplanner/api/mapping/SystemNoticeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/SystemNoticeMapper.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiSystemNotice; +import org.opentripplanner.ext.restapi.model.ApiSystemNotice; import org.opentripplanner.model.SystemNotice; public final class SystemNoticeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TransferMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java similarity index 77% rename from src/main/java/org/opentripplanner/api/mapping/TransferMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java index 3004d86aa44..49b87f25779 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TransferMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TransferMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiTransfer; +import org.opentripplanner.ext.restapi.model.ApiTransfer; import org.opentripplanner.model.PathTransfer; public class TransferMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java similarity index 92% rename from src/main/java/org/opentripplanner/api/mapping/TripMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java index 33df525a9a7..891741f531e 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java @@ -1,10 +1,10 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.opentripplanner.api.model.ApiTrip; -import org.opentripplanner.api.model.ApiTripShort; +import org.opentripplanner.ext.restapi.model.ApiTrip; +import org.opentripplanner.ext.restapi.model.ApiTripShort; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Trip; diff --git a/src/main/java/org/opentripplanner/api/mapping/TripPatternMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/TripPatternMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java index 439d2b5fe2f..ba68979c73f 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripPatternMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPatternMapper.java @@ -1,11 +1,11 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiPatternDetail; -import org.opentripplanner.api.model.ApiPatternShort; +import org.opentripplanner.ext.restapi.model.ApiPatternDetail; +import org.opentripplanner.ext.restapi.model.ApiPatternShort; import org.opentripplanner.transit.model.network.TripPattern; public class TripPatternMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripPlanMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/TripPlanMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java index 8c5459af8ed..891afcf9542 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripPlanMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripPlanMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Date; import java.util.Locale; -import org.opentripplanner.api.model.ApiTripPlan; +import org.opentripplanner.ext.restapi.model.ApiTripPlan; import org.opentripplanner.model.plan.TripPlan; public class TripPlanMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripSearchMetadataMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java similarity index 85% rename from src/main/java/org/opentripplanner/api/mapping/TripSearchMetadataMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java index 0a3b46bb118..db92e821493 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripSearchMetadataMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripSearchMetadataMapper.java @@ -1,7 +1,7 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.time.Instant; -import org.opentripplanner.api.model.ApiTripSearchMetadata; +import org.opentripplanner.ext.restapi.model.ApiTripSearchMetadata; import org.opentripplanner.routing.api.response.TripSearchMetadata; public class TripSearchMetadataMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/TripTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java similarity index 89% rename from src/main/java/org/opentripplanner/api/mapping/TripTimeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java index 2f5bfe91026..3cbb71cdb72 100644 --- a/src/main/java/org/opentripplanner/api/mapping/TripTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java @@ -1,10 +1,10 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiRealTimeState; -import org.opentripplanner.api.model.ApiTripTimeShort; +import org.opentripplanner.ext.restapi.model.ApiRealTimeState; +import org.opentripplanner.ext.restapi.model.ApiTripTimeShort; import org.opentripplanner.model.TripTimeOnDate; public class TripTimeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/VehicleRentalStationMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java similarity index 88% rename from src/main/java/org/opentripplanner/api/mapping/VehicleRentalStationMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java index 482a966dec0..2f68448fdf4 100644 --- a/src/main/java/org/opentripplanner/api/mapping/VehicleRentalStationMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VehicleRentalStationMapper.java @@ -1,8 +1,8 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.model.ApiVehicleRentalStation; +import org.opentripplanner.ext.restapi.model.ApiVehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; public class VehicleRentalStationMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/VertexTypeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java similarity index 83% rename from src/main/java/org/opentripplanner/api/mapping/VertexTypeMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java index 340be3d60fd..5f59ea4fd57 100644 --- a/src/main/java/org/opentripplanner/api/mapping/VertexTypeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/VertexTypeMapper.java @@ -1,6 +1,6 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import org.opentripplanner.api.model.ApiVertexType; +import org.opentripplanner.ext.restapi.model.ApiVertexType; import org.opentripplanner.model.plan.VertexType; public class VertexTypeMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/WalkStepMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java similarity index 84% rename from src/main/java/org/opentripplanner/api/mapping/WalkStepMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java index 5d633079e4a..fba316d32ba 100644 --- a/src/main/java/org/opentripplanner/api/mapping/WalkStepMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java @@ -1,13 +1,13 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; -import static org.opentripplanner.api.mapping.ElevationMapper.mapElevation; -import static org.opentripplanner.api.mapping.RelativeDirectionMapper.mapRelativeDirection; +import static org.opentripplanner.ext.restapi.mapping.ElevationMapper.mapElevation; +import static org.opentripplanner.ext.restapi.mapping.RelativeDirectionMapper.mapRelativeDirection; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.api.model.ApiWalkStep; +import org.opentripplanner.ext.restapi.model.ApiWalkStep; import org.opentripplanner.model.plan.WalkStep; public class WalkStepMapper { diff --git a/src/main/java/org/opentripplanner/api/mapping/WheelchairAccessibilityMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java similarity index 87% rename from src/main/java/org/opentripplanner/api/mapping/WheelchairAccessibilityMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java index 05d8cc97959..e0aafeaee05 100644 --- a/src/main/java/org/opentripplanner/api/mapping/WheelchairAccessibilityMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WheelchairAccessibilityMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.transit.model.basic.Accessibility; diff --git a/src/main/java/org/opentripplanner/api/model/ApiAbsoluteDirection.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java similarity index 79% rename from src/main/java/org/opentripplanner/api/model/ApiAbsoluteDirection.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java index 48d93618bf7..ffa00cbc54e 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiAbsoluteDirection.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAbsoluteDirection.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * An absolute cardinal or intermediate direction. diff --git a/src/main/java/org/opentripplanner/api/model/ApiAgency.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java similarity index 93% rename from src/main/java/org/opentripplanner/api/model/ApiAgency.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java index e895ea655cd..ada6739a795 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiAgency.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAgency.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiAlert.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java similarity index 83% rename from src/main/java/org/opentripplanner/api/model/ApiAlert.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java index 3c4d77c6129..a503a7d18e2 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiAlert.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiAlert.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Date; diff --git a/src/main/java/org/opentripplanner/api/model/ApiBookingInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiBookingInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java index f3a553fc1f1..c89d6429caa 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiBookingInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingInfo.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.time.Duration; diff --git a/src/main/java/org/opentripplanner/api/model/ApiBookingTime.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java similarity index 94% rename from src/main/java/org/opentripplanner/api/model/ApiBookingTime.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java index e0c140f8ee1..08eee69a3cf 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiBookingTime.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiBookingTime.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import org.opentripplanner.framework.tostring.ToStringBuilder; diff --git a/src/main/java/org/opentripplanner/api/model/ApiContactInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiContactInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java index 06c1fc8d198..b7c2ec90166 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiContactInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiContactInfo.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import org.opentripplanner.framework.tostring.ToStringBuilder; diff --git a/src/main/java/org/opentripplanner/api/model/ApiCurrency.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java similarity index 71% rename from src/main/java/org/opentripplanner/api/model/ApiCurrency.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java index 3835f7986ca..b3cff1eaa93 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiCurrency.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiCurrency.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public record ApiCurrency( String currency, diff --git a/src/main/java/org/opentripplanner/api/model/ApiFareComponent.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java similarity index 76% rename from src/main/java/org/opentripplanner/api/model/ApiFareComponent.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java index 8d6038c487a..e26f859c4f2 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFareComponent.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareComponent.java @@ -1,7 +1,6 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; -import java.util.Optional; import org.opentripplanner.transit.model.framework.FeedScopedId; public record ApiFareComponent( diff --git a/src/main/java/org/opentripplanner/api/model/ApiFareProduct.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java similarity index 91% rename from src/main/java/org/opentripplanner/api/model/ApiFareProduct.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java index 2beb991855d..af8561b73cb 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFareProduct.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareProduct.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * A Fares V2 product. This is a type of ticket or monthly pass that customers can buy. diff --git a/src/main/java/org/opentripplanner/api/model/ApiFareQualifier.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java similarity index 83% rename from src/main/java/org/opentripplanner/api/model/ApiFareQualifier.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java index 702caca7a0f..94a3731863a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFareQualifier.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFareQualifier.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Qualifiers for Fares V2 fare products. Qualifiers can be rider categories (youth, senior, veteran) or diff --git a/src/main/java/org/opentripplanner/api/model/ApiFeedInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java similarity index 93% rename from src/main/java/org/opentripplanner/api/model/ApiFeedInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java index a1614ba6391..1b96ee0759d 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiFeedInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiFeedInfo.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiItinerary.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiItinerary.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java index e2d205de13e..0bce9426fd8 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiItinerary.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItinerary.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.Calendar; diff --git a/src/main/java/org/opentripplanner/api/model/ApiItineraryFares.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java similarity index 92% rename from src/main/java/org/opentripplanner/api/model/ApiItineraryFares.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java index e908a81b452..a7140e59d4d 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiItineraryFares.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiItineraryFares.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/opentripplanner/api/model/ApiLeg.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java similarity index 99% rename from src/main/java/org/opentripplanner/api/model/ApiLeg.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java index 87be725615d..7bbd83f7c2d 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiLeg.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLeg.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Calendar; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiLegProducts.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java similarity index 88% rename from src/main/java/org/opentripplanner/api/model/ApiLegProducts.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java index ef7d95a3abf..abd4643100b 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiLegProducts.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiLegProducts.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Collection; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiMoney.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java similarity index 56% rename from src/main/java/org/opentripplanner/api/model/ApiMoney.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java index a9a27e828ae..a5f3f840bf6 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiMoney.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiMoney.java @@ -1,3 +1,3 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public record ApiMoney(int cents, ApiCurrency currency) {} diff --git a/src/main/java/org/opentripplanner/api/model/ApiPatternDetail.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java similarity index 87% rename from src/main/java/org/opentripplanner/api/model/ApiPatternDetail.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java index 1acb3acb6d5..d24f7f35c12 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiPatternDetail.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternDetail.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/org/opentripplanner/api/model/ApiPatternShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java similarity index 68% rename from src/main/java/org/opentripplanner/api/model/ApiPatternShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java index 0adcb6c2f18..d2acd234f47 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiPatternShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPatternShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiPatternShort { diff --git a/src/main/java/org/opentripplanner/api/model/ApiPlace.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiPlace.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java index 3ac922059ee..7cfe3bc7c22 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiPlace.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiPlace.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Calendar; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRealTimeState.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java similarity index 96% rename from src/main/java/org/opentripplanner/api/model/ApiRealTimeState.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java index df307007157..d9a068349ec 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRealTimeState.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRealTimeState.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import org.opentripplanner.transit.model.timetable.RealTimeState; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRelativeDirection.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java similarity index 90% rename from src/main/java/org/opentripplanner/api/model/ApiRelativeDirection.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java index e8e1553d51f..02a530f06de 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRelativeDirection.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Represents a turn direction, relative to the current heading. diff --git a/src/main/java/org/opentripplanner/api/model/ApiRoute.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java similarity index 95% rename from src/main/java/org/opentripplanner/api/model/ApiRoute.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java index 1826091f210..d4ce90d9b23 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRoute.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRoute.java @@ -1,5 +1,5 @@ /* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRouteShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java similarity index 85% rename from src/main/java/org/opentripplanner/api/model/ApiRouteShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java index db74e2514cc..a62dcc4bdb6 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRouteShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouteShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiRouteShort { diff --git a/src/main/java/org/opentripplanner/api/model/ApiRouterInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiRouterInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java index 3c08defcba5..a0bbb1116b3 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRouterInfo.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterInfo.java @@ -1,9 +1,9 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.Date; import java.util.List; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.ModeMapper; +import org.opentripplanner.ext.restapi.mapping.ModeMapper; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.vehicle_parking.VehicleParkingService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; diff --git a/src/main/java/org/opentripplanner/api/model/ApiRouterList.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java similarity index 75% rename from src/main/java/org/opentripplanner/api/model/ApiRouterList.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java index ec412716202..dd7ef3544af 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiRouterList.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRouterList.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiStop.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java similarity index 96% rename from src/main/java/org/opentripplanner/api/model/ApiStop.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java index b2604268f76..abe4adb623a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiStop.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStop.java @@ -1,5 +1,5 @@ /* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiStopShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java similarity index 92% rename from src/main/java/org/opentripplanner/api/model/ApiStopShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java index 3fe4daf7c4c..1eafd760248 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiStopShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/src/main/java/org/opentripplanner/api/model/ApiStopTimesInPattern.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java similarity index 74% rename from src/main/java/org/opentripplanner/api/model/ApiStopTimesInPattern.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java index c0069c1662a..405c200651b 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiStopTimesInPattern.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiStopTimesInPattern.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiSystemNotice.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java similarity index 95% rename from src/main/java/org/opentripplanner/api/model/ApiSystemNotice.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java index ab95bc2034d..dc7eb51177e 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiSystemNotice.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiSystemNotice.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.transit.model.basic.Notice; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTransfer.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java similarity index 82% rename from src/main/java/org/opentripplanner/api/model/ApiTransfer.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java index a9d45aac4c1..38cede8c1f1 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTransfer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTransfer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** Represents a transfer from a stop */ public class ApiTransfer { diff --git a/src/main/java/org/opentripplanner/api/model/ApiTravelOption.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiTravelOption.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java index 06b186969b0..d09de672d91 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTravelOption.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOption.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.HashSet; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTravelOptionsMaker.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiTravelOptionsMaker.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java index 5c0109f8baf..cf424392d70 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTravelOptionsMaker.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMaker.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTrip.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java similarity index 96% rename from src/main/java/org/opentripplanner/api/model/ApiTrip.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java index 947991ac392..3ff0626c9a8 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTrip.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTrip.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripPlan.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java similarity index 90% rename from src/main/java/org/opentripplanner/api/model/ApiTripPlan.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java index 7c62b6cdd66..bfb812b69c3 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripPlan.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripPlan.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.Date; diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripSearchMetadata.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiTripSearchMetadata.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java index 486118883f9..abe5a74337f 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripSearchMetadata.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripSearchMetadata.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Meta-data about the trip search performed. diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java similarity index 77% rename from src/main/java/org/opentripplanner/api/model/ApiTripShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java index 17560af64ce..cedfa471d4a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiTripShort { diff --git a/src/main/java/org/opentripplanner/api/model/ApiTripTimeShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java similarity index 93% rename from src/main/java/org/opentripplanner/api/model/ApiTripTimeShort.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java index 0a340d4a812..21c6010c5a2 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiTripTimeShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.io.Serializable; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingSpaces.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleParkingSpaces.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java index 8c4ab4b8fee..bcb10e70f0f 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingSpaces.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingSpaces.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; public class ApiVehicleParkingSpaces { diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingWithEntrance.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java similarity index 99% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleParkingWithEntrance.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java index 8cac78f6c9e..68a9f37dfe4 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleParkingWithEntrance.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStation.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java similarity index 95% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStation.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java index 354961bae16..8431ac5c387 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStation.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStation.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStationList.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java similarity index 78% rename from src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStationList.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java index ed74f8a7ab7..c97a18c337e 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVehicleRentalStationList.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleRentalStationList.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/model/ApiVertexType.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java similarity index 81% rename from src/main/java/org/opentripplanner/api/model/ApiVertexType.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java index 3bcc4034272..595f0628e0a 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiVertexType.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVertexType.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; /** * Represent type of vertex, used in Place aka from, to in API for easier client side localization diff --git a/src/main/java/org/opentripplanner/api/model/ApiWalkStep.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java similarity index 98% rename from src/main/java/org/opentripplanner/api/model/ApiWalkStep.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java index 5e810d98602..363a01cb7b5 100644 --- a/src/main/java/org/opentripplanner/api/model/ApiWalkStep.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiWalkStep.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import java.util.List; diff --git a/src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java similarity index 83% rename from src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java index 7b11f5fa736..b885883b17e 100644 --- a/src/main/java/org/opentripplanner/api/resource/ElevationMetadata.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ElevationMetadata.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.model; /** * Contains elevation-specific metadata to be included in the response diff --git a/src/main/java/org/opentripplanner/api/resource/TripPlannerResponse.java b/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java similarity index 95% rename from src/main/java/org/opentripplanner/api/resource/TripPlannerResponse.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java index 970acad5ac2..337301cddfd 100644 --- a/src/main/java/org/opentripplanner/api/resource/TripPlannerResponse.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java @@ -1,12 +1,11 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.model; import jakarta.ws.rs.core.UriInfo; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; -import org.opentripplanner.api.model.ApiTripPlan; -import org.opentripplanner.api.model.ApiTripSearchMetadata; import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.resource.DebugOutput; /** Represents a trip planner response, will be serialized into XML or JSON by Jersey */ public class TripPlannerResponse { diff --git a/src/main/java/org/opentripplanner/api/model/error/PlannerError.java b/src/ext/java/org/opentripplanner/ext/restapi/model/error/PlannerError.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/error/PlannerError.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/error/PlannerError.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiConfigInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiConfigInfo.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java b/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiProjectVersion.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiProjectVersion.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiServerInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiServerInfo.java diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java b/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiVersionControlInfo.java similarity index 100% rename from src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java rename to src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiVersionControlInfo.java diff --git a/src/main/java/org/opentripplanner/api/resource/BikeRental.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java similarity index 91% rename from src/main/java/org/opentripplanner/api/resource/BikeRental.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java index fdac9b39023..0da598f8a3f 100644 --- a/src/main/java/org/opentripplanner/api/resource/BikeRental.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/BikeRental.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -12,9 +12,9 @@ import java.util.List; import java.util.Locale; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.api.mapping.VehicleRentalStationMapper; -import org.opentripplanner.api.model.ApiVehicleRentalStation; -import org.opentripplanner.api.model.ApiVehicleRentalStationList; +import org.opentripplanner.ext.restapi.mapping.VehicleRentalStationMapper; +import org.opentripplanner.ext.restapi.model.ApiVehicleRentalStation; +import org.opentripplanner.ext.restapi.model.ApiVehicleRentalStationList; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.standalone.api.OtpServerRequestContext; diff --git a/src/main/java/org/opentripplanner/index/IndexAPI.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java similarity index 93% rename from src/main/java/org/opentripplanner/index/IndexAPI.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java index 74eba3a60b8..90fd12a1c7c 100644 --- a/src/main/java/org/opentripplanner/index/IndexAPI.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java @@ -1,4 +1,4 @@ -package org.opentripplanner.index; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.DefaultValue; @@ -25,31 +25,31 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.api.mapping.AgencyMapper; -import org.opentripplanner.api.mapping.AlertMapper; -import org.opentripplanner.api.mapping.FeedInfoMapper; -import org.opentripplanner.api.mapping.FeedScopedIdMapper; -import org.opentripplanner.api.mapping.RouteMapper; -import org.opentripplanner.api.mapping.StopMapper; -import org.opentripplanner.api.mapping.StopTimesInPatternMapper; -import org.opentripplanner.api.mapping.TransferMapper; -import org.opentripplanner.api.mapping.TripMapper; -import org.opentripplanner.api.mapping.TripPatternMapper; -import org.opentripplanner.api.mapping.TripTimeMapper; -import org.opentripplanner.api.model.ApiAgency; -import org.opentripplanner.api.model.ApiAlert; -import org.opentripplanner.api.model.ApiFeedInfo; -import org.opentripplanner.api.model.ApiPatternShort; -import org.opentripplanner.api.model.ApiRoute; -import org.opentripplanner.api.model.ApiRouteShort; -import org.opentripplanner.api.model.ApiStop; -import org.opentripplanner.api.model.ApiStopShort; -import org.opentripplanner.api.model.ApiStopTimesInPattern; -import org.opentripplanner.api.model.ApiTransfer; -import org.opentripplanner.api.model.ApiTrip; -import org.opentripplanner.api.model.ApiTripShort; -import org.opentripplanner.api.model.ApiTripTimeShort; -import org.opentripplanner.api.support.SemanticHash; +import org.opentripplanner.apis.common.SemanticHash; +import org.opentripplanner.ext.restapi.mapping.AgencyMapper; +import org.opentripplanner.ext.restapi.mapping.AlertMapper; +import org.opentripplanner.ext.restapi.mapping.FeedInfoMapper; +import org.opentripplanner.ext.restapi.mapping.FeedScopedIdMapper; +import org.opentripplanner.ext.restapi.mapping.RouteMapper; +import org.opentripplanner.ext.restapi.mapping.StopMapper; +import org.opentripplanner.ext.restapi.mapping.StopTimesInPatternMapper; +import org.opentripplanner.ext.restapi.mapping.TransferMapper; +import org.opentripplanner.ext.restapi.mapping.TripMapper; +import org.opentripplanner.ext.restapi.mapping.TripPatternMapper; +import org.opentripplanner.ext.restapi.mapping.TripTimeMapper; +import org.opentripplanner.ext.restapi.model.ApiAgency; +import org.opentripplanner.ext.restapi.model.ApiAlert; +import org.opentripplanner.ext.restapi.model.ApiFeedInfo; +import org.opentripplanner.ext.restapi.model.ApiPatternShort; +import org.opentripplanner.ext.restapi.model.ApiRoute; +import org.opentripplanner.ext.restapi.model.ApiRouteShort; +import org.opentripplanner.ext.restapi.model.ApiStop; +import org.opentripplanner.ext.restapi.model.ApiStopShort; +import org.opentripplanner.ext.restapi.model.ApiStopTimesInPattern; +import org.opentripplanner.ext.restapi.model.ApiTransfer; +import org.opentripplanner.ext.restapi.model.ApiTrip; +import org.opentripplanner.ext.restapi.model.ApiTripShort; +import org.opentripplanner.ext.restapi.model.ApiTripTimeShort; import org.opentripplanner.framework.geometry.EncodedPolyline; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.StopTimesInPattern; diff --git a/src/main/java/org/opentripplanner/api/resource/PlannerResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java similarity index 93% rename from src/main/java/org/opentripplanner/api/resource/PlannerResource.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java index bb2b4f1020a..ac1ee80df95 100644 --- a/src/main/java/org/opentripplanner/api/resource/PlannerResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @@ -10,11 +10,12 @@ import jakarta.ws.rs.core.UriInfo; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.common.Message; -import org.opentripplanner.api.common.RoutingResource; -import org.opentripplanner.api.mapping.PlannerErrorMapper; -import org.opentripplanner.api.mapping.TripPlanMapper; -import org.opentripplanner.api.mapping.TripSearchMetadataMapper; import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; +import org.opentripplanner.ext.restapi.mapping.TripPlanMapper; +import org.opentripplanner.ext.restapi.mapping.TripSearchMetadataMapper; +import org.opentripplanner.ext.restapi.model.ElevationMetadata; +import org.opentripplanner.ext.restapi.model.TripPlannerResponse; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.response.RoutingResponse; diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java similarity index 99% rename from src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index aa827ae5b4c..78048abffa2 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.common; +package org.opentripplanner.ext.restapi.resources; import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; diff --git a/src/main/java/org/opentripplanner/api/resource/Routers.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java similarity index 93% rename from src/main/java/org/opentripplanner/api/resource/Routers.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java index 63ed28fbea3..9cfab49017c 100644 --- a/src/main/java/org/opentripplanner/api/resource/Routers.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/Routers.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; import jakarta.annotation.security.PermitAll; import jakarta.ws.rs.GET; @@ -7,8 +7,8 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; -import org.opentripplanner.api.model.ApiRouterInfo; -import org.opentripplanner.api.model.ApiRouterList; +import org.opentripplanner.ext.restapi.model.ApiRouterInfo; +import org.opentripplanner.ext.restapi.model.ApiRouterList; import org.opentripplanner.routing.error.GraphNotFoundException; import org.opentripplanner.standalone.api.OtpServerRequestContext; diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java similarity index 99% rename from src/main/java/org/opentripplanner/api/common/RoutingResource.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 9cb4f139bc4..b727607c8e6 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -1,7 +1,7 @@ -package org.opentripplanner.api.common; +package org.opentripplanner.ext.restapi.resources; import static org.opentripplanner.api.common.LocationStringParser.fromOldStyleString; -import static org.opentripplanner.api.common.RequestToPreferencesMapper.setIfNotNull; +import static org.opentripplanner.ext.restapi.resources.RequestToPreferencesMapper.setIfNotNull; import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.QueryParam; diff --git a/src/main/java/org/opentripplanner/index/ValidateParameters.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java similarity index 96% rename from src/main/java/org/opentripplanner/index/ValidateParameters.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java index 41149ac31e3..5a94ca318f7 100644 --- a/src/main/java/org/opentripplanner/index/ValidateParameters.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/ValidateParameters.java @@ -1,4 +1,4 @@ -package org.opentripplanner.index; +package org.opentripplanner.ext.restapi.resources; import jakarta.ws.rs.BadRequestException; import java.util.HashSet; diff --git a/src/main/java/org/opentripplanner/api/resource/package-info.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java similarity index 74% rename from src/main/java/org/opentripplanner/api/resource/package-info.java rename to src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java index 4d67f4b2100..7b66666ee5d 100644 --- a/src/main/java/org/opentripplanner/api/resource/package-info.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/package-info.java @@ -2,4 +2,4 @@ * This package contains the JAX-RS-annotated REST resource classes for the OpenTripPlanner public * API, i.e. the Jersey REST endpoints. */ -package org.opentripplanner.api.resource; +package org.opentripplanner.ext.restapi.resources; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index f22145d261d..96093884a25 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -17,7 +17,7 @@ import java.util.Objects; import java.util.function.Predicate; import org.glassfish.grizzly.http.server.Request; -import org.opentripplanner.api.model.TileJson; +import org.opentripplanner.apis.common.TileJson; import org.opentripplanner.ext.vectortiles.layers.stations.StationsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.stops.StopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingGroupsLayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java index b706a0ae8c3..6e37471495e 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java @@ -6,8 +6,8 @@ import java.util.Map; import java.util.stream.Collectors; import org.json.simple.JSONArray; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Station; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java index 56e8be7b3e4..1b09d2e8c5d 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java @@ -9,7 +9,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java index 502adc7899f..597480d493b 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java @@ -8,8 +8,8 @@ import java.util.stream.Collectors; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index b6558f3cbe5..e57e3e48cb0 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java index a5bb4ae2c8b..cb2939da610 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java @@ -5,8 +5,8 @@ import java.util.Locale; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; public class DigitransitVehicleParkingGroupPropertyMapper diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java index 993675dcf06..a265d0552d0 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java index 0e7c5cd90e8..8c1e24f8321 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Locale; import org.json.simple.JSONObject; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.model.calendar.openinghours.OsmOpeningHoursSupport; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java index f39d042ad6e..59440b78ab7 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java @@ -8,7 +8,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java index 66dde2e4258..7a43044d40c 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java @@ -11,7 +11,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java index 4e181ed4fa1..06fecf26e57 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java @@ -7,7 +7,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java index a6f2aa63fd4..949cb071de4 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java @@ -7,8 +7,8 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java index e1093467d4d..1450b7855bd 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collection; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java index 1839edf8905..88549242b93 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java index 962c1db4b04..de0d3aa9bc0 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/main/java/org/opentripplanner/api/package.md b/src/main/java/org/opentripplanner/api/package.md deleted file mode 100644 index 5498b2e4c47..00000000000 --- a/src/main/java/org/opentripplanner/api/package.md +++ /dev/null @@ -1,8 +0,0 @@ -# OTP REST API - -This package contains the code which exposes OpenTripPlanner services to the outside world as a REST -API. This includes Jersey REST resource classes (in the "resource" subpackage, picked up by Jersey's -package scanning process), and the classes modeling the structure of the response (in the "model" -subpackage). We provide OTP with the REST API as a embedded standalone Grizzly-based command-line -server. - diff --git a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java index 2c21e0396ce..89905298e66 100644 --- a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java @@ -17,7 +17,7 @@ import java.util.Objects; import java.util.function.Predicate; import org.glassfish.grizzly.http.server.Request; -import org.opentripplanner.api.model.TileJson; +import org.opentripplanner.apis.common.TileJson; import org.opentripplanner.inspector.vector.AreaStopsLayerBuilder; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java similarity index 93% rename from src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java rename to src/main/java/org/opentripplanner/apis/APIEndpoints.java index b0d38aa00cd..773dccd9960 100644 --- a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.configuration; +package org.opentripplanner.apis; import static org.opentripplanner.framework.application.OTPFeature.APIBikeRental; import static org.opentripplanner.framework.application.OTPFeature.APIGraphInspectorTile; @@ -17,11 +17,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import org.opentripplanner.api.resource.BikeRental; import org.opentripplanner.api.resource.GraphInspectorTileResource; import org.opentripplanner.api.resource.GraphInspectorVectorTileResource; -import org.opentripplanner.api.resource.PlannerResource; -import org.opentripplanner.api.resource.Routers; import org.opentripplanner.api.resource.ServerInfo; import org.opentripplanner.api.resource.UpdaterStatusResource; import org.opentripplanner.apis.gtfs.GtfsGraphQLAPI; @@ -30,10 +27,13 @@ import org.opentripplanner.ext.geocoder.GeocoderResource; import org.opentripplanner.ext.parkAndRideApi.ParkAndRideResource; import org.opentripplanner.ext.reportapi.resource.ReportResource; +import org.opentripplanner.ext.restapi.resources.BikeRental; +import org.opentripplanner.ext.restapi.resources.IndexAPI; +import org.opentripplanner.ext.restapi.resources.PlannerResource; +import org.opentripplanner.ext.restapi.resources.Routers; import org.opentripplanner.ext.traveltime.TravelTimeResource; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.index.IndexAPI; /** * Configure API resource endpoints. diff --git a/src/main/java/org/opentripplanner/api/support/SemanticHash.java b/src/main/java/org/opentripplanner/apis/common/SemanticHash.java similarity index 99% rename from src/main/java/org/opentripplanner/api/support/SemanticHash.java rename to src/main/java/org/opentripplanner/apis/common/SemanticHash.java index bf7e8da8b01..73ef2da906c 100644 --- a/src/main/java/org/opentripplanner/api/support/SemanticHash.java +++ b/src/main/java/org/opentripplanner/apis/common/SemanticHash.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.support; +package org.opentripplanner.apis.common; import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; diff --git a/src/main/java/org/opentripplanner/api/model/TileJson.java b/src/main/java/org/opentripplanner/apis/common/TileJson.java similarity index 97% rename from src/main/java/org/opentripplanner/api/model/TileJson.java rename to src/main/java/org/opentripplanner/apis/common/TileJson.java index d012241d892..c9b3856e932 100644 --- a/src/main/java/org/opentripplanner/api/model/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/common/TileJson.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.apis.common; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.UriInfo; diff --git a/src/main/java/org/opentripplanner/api/json/FeedScopedIdDeserializer.java b/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdDeserializer.java similarity index 95% rename from src/main/java/org/opentripplanner/api/json/FeedScopedIdDeserializer.java rename to src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdDeserializer.java index aaccc900c1c..b1946038e7e 100644 --- a/src/main/java/org/opentripplanner/api/json/FeedScopedIdDeserializer.java +++ b/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdDeserializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.apis.common.json; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/org/opentripplanner/api/json/FeedScopedIdKeyDeserializer.java b/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdKeyDeserializer.java similarity index 93% rename from src/main/java/org/opentripplanner/api/json/FeedScopedIdKeyDeserializer.java rename to src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdKeyDeserializer.java index a59f46e1052..316894763ad 100644 --- a/src/main/java/org/opentripplanner/api/json/FeedScopedIdKeyDeserializer.java +++ b/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdKeyDeserializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.apis.common.json; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.KeyDeserializer; diff --git a/src/main/java/org/opentripplanner/api/json/FeedScopedIdSerializer.java b/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdSerializer.java similarity index 97% rename from src/main/java/org/opentripplanner/api/json/FeedScopedIdSerializer.java rename to src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdSerializer.java index 1e357f642b1..471d80aa915 100644 --- a/src/main/java/org/opentripplanner/api/json/FeedScopedIdSerializer.java +++ b/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdSerializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.apis.common.json; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/org/opentripplanner/api/json/GraphQLResponseSerializer.java b/src/main/java/org/opentripplanner/apis/common/json/GraphQLResponseSerializer.java similarity index 97% rename from src/main/java/org/opentripplanner/api/json/GraphQLResponseSerializer.java rename to src/main/java/org/opentripplanner/apis/common/json/GraphQLResponseSerializer.java index caba621294c..de068d170e9 100644 --- a/src/main/java/org/opentripplanner/api/json/GraphQLResponseSerializer.java +++ b/src/main/java/org/opentripplanner/apis/common/json/GraphQLResponseSerializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.apis.common.json; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/opentripplanner/api/json/JSONObjectMapperProvider.java b/src/main/java/org/opentripplanner/apis/common/json/JSONObjectMapperProvider.java similarity index 98% rename from src/main/java/org/opentripplanner/api/json/JSONObjectMapperProvider.java rename to src/main/java/org/opentripplanner/apis/common/json/JSONObjectMapperProvider.java index d4138563fc7..6121a0ba698 100644 --- a/src/main/java/org/opentripplanner/api/json/JSONObjectMapperProvider.java +++ b/src/main/java/org/opentripplanner/apis/common/json/JSONObjectMapperProvider.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.json; +package org.opentripplanner.apis.common.json; import com.bedatadriven.jackson.datatype.jts.JtsModule; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/src/main/java/org/opentripplanner/api/mapping/PlannerErrorMapper.java b/src/main/java/org/opentripplanner/apis/common/mapping/PlannerErrorMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/api/mapping/PlannerErrorMapper.java rename to src/main/java/org/opentripplanner/apis/common/mapping/PlannerErrorMapper.java index 204495110c1..b85986c930b 100644 --- a/src/main/java/org/opentripplanner/api/mapping/PlannerErrorMapper.java +++ b/src/main/java/org/opentripplanner/apis/common/mapping/PlannerErrorMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.apis.common.mapping; import java.util.List; import org.opentripplanner.api.common.Message; diff --git a/src/main/java/org/opentripplanner/api/mapping/PropertyMapper.java b/src/main/java/org/opentripplanner/apis/common/mapping/PropertyMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/api/mapping/PropertyMapper.java rename to src/main/java/org/opentripplanner/apis/common/mapping/PropertyMapper.java index 88f102a2b06..ad2868239a8 100644 --- a/src/main/java/org/opentripplanner/api/mapping/PropertyMapper.java +++ b/src/main/java/org/opentripplanner/apis/common/mapping/PropertyMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.apis.common.mapping; import edu.colorado.cires.cmg.mvt.VectorTile; import edu.colorado.cires.cmg.mvt.adapt.jts.IUserDataConverter; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java index 20d15b1cfe8..955fd8222da 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Future; -import org.opentripplanner.api.json.GraphQLResponseSerializer; +import org.opentripplanner.apis.common.json.GraphQLResponseSerializer; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index c70836a581f..9a4283d198a 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -26,7 +26,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.opentripplanner.api.json.GraphQLResponseSerializer; +import org.opentripplanner.apis.common.json.GraphQLResponseSerializer; import org.opentripplanner.apis.gtfs.datafetchers.AgencyImpl; import org.opentripplanner.apis.gtfs.datafetchers.AlertEntityTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.AlertImpl; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java index b13f6123d4d..639cb95bf28 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/LegImpl.java @@ -6,11 +6,11 @@ import java.util.Objects; import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.LocalDateMapper; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.mapping.NumberMapper; +import org.opentripplanner.ext.restapi.mapping.LocalDateMapper; import org.opentripplanner.ext.ridehailing.model.RideEstimate; import org.opentripplanner.ext.ridehailing.model.RideHailingLeg; import org.opentripplanner.framework.graphql.GraphQLUtils; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java index 241434c664f..5c121a6dd07 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java @@ -13,7 +13,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.api.support.SemanticHash; +import org.opentripplanner.apis.common.SemanticHash; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java index 9ae58be1334..36dc4a987d8 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java @@ -3,8 +3,8 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.PlannerErrorMapper; import org.opentripplanner.api.resource.DebugOutput; +import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StopArrival; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java index 7c516930888..d80db923df6 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java @@ -4,7 +4,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import org.opentripplanner.api.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.routing.api.response.RoutingError; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java index 2502d2b9539..c9b1abdaa64 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java @@ -15,7 +15,7 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.api.support.SemanticHash; +import org.opentripplanner.apis.common.SemanticHash; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java index baa601c7448..572535a540d 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java @@ -1,6 +1,6 @@ package org.opentripplanner.apis.gtfs.mapping; -import org.opentripplanner.api.mapping.StreetNoteMaperMapper; +import org.opentripplanner.ext.restapi.mapping.StreetNoteMaperMapper; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.routing.alertpatch.TimePeriod; import org.opentripplanner.routing.alertpatch.TransitAlert; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java index 79052f17b69..a8ae74dede2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java @@ -7,7 +7,7 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; -import org.opentripplanner.api.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; public class RoutingErrorType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java index d9c3c0caa02..fcf794a7ca8 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java @@ -8,7 +8,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import java.util.stream.Collectors; -import org.opentripplanner.api.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; import org.opentripplanner.apis.transmodel.model.PlanResponse; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.graphql.GraphQLUtils; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java index ecb5a38ef01..e6a5fea3ba0 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java @@ -4,7 +4,7 @@ import graphql.ExecutionResult; import graphql.GraphQLError; import jakarta.ws.rs.core.Response; -import org.opentripplanner.api.json.GraphQLResponseSerializer; +import org.opentripplanner.apis.common.json.GraphQLResponseSerializer; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.framework.http.OtpHttpStatus; diff --git a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java index 1604cf7d8d1..5f268d9f9bf 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; diff --git a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java index 88f7a17385b..db88579b35f 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java @@ -3,8 +3,8 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java index 3e796487271..cec59ef136f 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java @@ -10,7 +10,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; /** diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index 2718c649797..a36fdfad840 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,6 +1,6 @@ package org.opentripplanner.inspector.vector; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; /** * Configuration options for a single vector tile layer. diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java index 8a77b8502ea..3948f95e8ee 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java @@ -4,7 +4,7 @@ import java.util.Map; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java index 0d0f7b44fe9..7321727076c 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java @@ -6,7 +6,7 @@ import java.util.Collection; import java.util.List; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.common.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.street.model.vertex.Vertex; diff --git a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java index 18d94d23038..f0a2c854015 100644 --- a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java +++ b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java @@ -1,9 +1,11 @@ package org.opentripplanner.routing.error; +import org.opentripplanner.ext.restapi.resources.PlannerResource; + /** * Indicates that the call to org.opentripplanner.routing.services.PathService returned either null * or ZERO paths. * - * @see org.opentripplanner.api.resource.PlannerResource for where this is (locally) thrown. + * @see PlannerResource for where this is (locally) thrown. */ public class PathNotFoundException extends RuntimeException {} diff --git a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java b/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java index 56aaa2d1361..5612d98ea0c 100644 --- a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java +++ b/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java @@ -7,7 +7,6 @@ import io.micrometer.prometheus.PrometheusMeterRegistry; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.core.Application; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -17,10 +16,9 @@ import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.internal.inject.Binder; import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider; -import org.glassfish.jersey.server.ServerProperties; import org.opentripplanner.api.common.OTPExceptionMapper; -import org.opentripplanner.api.configuration.APIEndpoints; -import org.opentripplanner.api.json.JSONObjectMapperProvider; +import org.opentripplanner.apis.APIEndpoints; +import org.opentripplanner.apis.common.json.JSONObjectMapperProvider; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.bridge.SLF4JBridgeHandler; diff --git a/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java b/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java index 184e6b7e6d7..956b2aa065e 100644 --- a/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java +++ b/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java @@ -8,9 +8,12 @@ import java.util.Map; import java.util.function.Function; import org.junit.jupiter.api.Test; -import org.opentripplanner.api.model.ApiAbsoluteDirection; -import org.opentripplanner.api.model.ApiRelativeDirection; -import org.opentripplanner.api.model.ApiVertexType; +import org.opentripplanner.ext.restapi.mapping.AbsoluteDirectionMapper; +import org.opentripplanner.ext.restapi.mapping.RelativeDirectionMapper; +import org.opentripplanner.ext.restapi.mapping.VertexTypeMapper; +import org.opentripplanner.ext.restapi.model.ApiAbsoluteDirection; +import org.opentripplanner.ext.restapi.model.ApiRelativeDirection; +import org.opentripplanner.ext.restapi.model.ApiVertexType; import org.opentripplanner.model.plan.AbsoluteDirection; import org.opentripplanner.model.plan.RelativeDirection; import org.opentripplanner.model.plan.VertexType; diff --git a/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java b/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java index 44fb360efd2..0d13a77e7c9 100644 --- a/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java +++ b/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Locale; import org.junit.jupiter.api.Test; +import org.opentripplanner.ext.restapi.mapping.FareMapper; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; diff --git a/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java b/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java index 9429151a422..16e0ae1547e 100644 --- a/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java +++ b/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; +import org.opentripplanner.ext.restapi.model.ApiTravelOption; +import org.opentripplanner.ext.restapi.model.ApiTravelOptionsMaker; import org.opentripplanner.transit.model.basic.TransitMode; /** diff --git a/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java b/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java index 44be1348eee..fe265b05081 100644 --- a/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java +++ b/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java @@ -2,9 +2,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.opentripplanner.ext.restapi.model.ApiWalkStep; public class ApiWalkStepTest { diff --git a/src/test/java/org/opentripplanner/api/common/PlannerResourceTest.java b/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java similarity index 95% rename from src/test/java/org/opentripplanner/api/common/PlannerResourceTest.java rename to src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java index 36e0650b081..a86e270a2af 100644 --- a/src/test/java/org/opentripplanner/api/common/PlannerResourceTest.java +++ b/src/test/java/org/opentripplanner/ext/restapi/resources/PlannerResourceTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.common; +package org.opentripplanner.ext.restapi.resources; import static graphql.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -12,7 +12,6 @@ import org.opentripplanner.TestServerContext; import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.api.parameter.QualifiedModeSet; -import org.opentripplanner.api.resource.PlannerResource; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java index bf0e62dbc19..8dbf5536ea2 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/SnapshotTestBase.java @@ -36,11 +36,11 @@ import org.opentripplanner.ConstantsForTests; import org.opentripplanner.TestOtpModel; import org.opentripplanner.TestServerContext; -import org.opentripplanner.api.mapping.ItineraryMapper; -import org.opentripplanner.api.model.ApiLeg; import org.opentripplanner.api.parameter.ApiRequestMode; import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.Qualifier; +import org.opentripplanner.ext.restapi.mapping.ItineraryMapper; +import org.opentripplanner.ext.restapi.model.ApiLeg; import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.model.plan.Itinerary; From 48572ef615d63fc55d131acee23c669fa350fb81 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 17 Dec 2023 23:31:19 +0100 Subject: [PATCH 002/356] Add (enabled) feature switch for LegacyRestApi --- docs/Configuration.md | 2 ++ .../java/org/opentripplanner/apis/APIEndpoints.java | 10 +++++----- .../framework/application/OTPFeature.java | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index f1c0af287ab..40e340aa4e7 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -235,6 +235,8 @@ Here is a list of all features which can be toggled on/off and their default val | `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | | `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | | `TransmodelGraphQlApi` | Enable Transmodel (NeTEx) GraphQL API. | ✓️ | ✓️ | +| `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_(GTFS) and Interchanges(NeTEx). Turing this _off_ will increase the routing performance a little. | ✓️ | | +| `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | | `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | | `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | | `Co2Emissions` | Enable the emissions sandbox module. | | ✓️ | diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java index 773dccd9960..04a0e3a145a 100644 --- a/src/main/java/org/opentripplanner/apis/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -6,6 +6,7 @@ import static org.opentripplanner.framework.application.OTPFeature.APIUpdaterStatus; import static org.opentripplanner.framework.application.OTPFeature.ActuatorAPI; import static org.opentripplanner.framework.application.OTPFeature.GtfsGraphQlApi; +import static org.opentripplanner.framework.application.OTPFeature.LegacyRestApi; import static org.opentripplanner.framework.application.OTPFeature.ReportApi; import static org.opentripplanner.framework.application.OTPFeature.SandboxAPIGeocoder; import static org.opentripplanner.framework.application.OTPFeature.SandboxAPIMapboxVectorTilesApi; @@ -43,13 +44,12 @@ public class APIEndpoints { private final List> resources = new ArrayList<>(); private APIEndpoints() { - // Add mandatory APIs - add(Routers.class); - add(PlannerResource.class); - add(IndexAPI.class); - // Add feature enabled APIs, these can be enabled by default, some is not. // See the OTPFeature enum for details. + addIfEnabled(LegacyRestApi, Routers.class); + addIfEnabled(LegacyRestApi, PlannerResource.class); + addIfEnabled(LegacyRestApi, IndexAPI.class); + addIfEnabled(APIBikeRental, BikeRental.class); addIfEnabled(APIGraphInspectorTile, GraphInspectorTileResource.class); addIfEnabled(APIGraphInspectorTile, GraphInspectorVectorTileResource.class); diff --git a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java index 05d1284a883..766fb136ecd 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java +++ b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java @@ -64,6 +64,7 @@ public enum OTPFeature { "Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little." ), TransmodelGraphQlApi(true, true, "Enable Transmodel (NeTEx) GraphQL API."), + LegacyRestApi(true, true, "Enable legacy REST API. This API will be removed in the future."), /* Sandbox extension features - Must be turned OFF by default */ From 21ec80c2f25bc0c93a070cd76ade29f9436b3ca9 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 19 Dec 2023 00:17:01 +0100 Subject: [PATCH 003/356] Regenerate docs --- docs/Configuration.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index 40e340aa4e7..7da21ea2175 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -235,7 +235,6 @@ Here is a list of all features which can be toggled on/off and their default val | `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | | `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | | `TransmodelGraphQlApi` | Enable Transmodel (NeTEx) GraphQL API. | ✓️ | ✓️ | -| `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_(GTFS) and Interchanges(NeTEx). Turing this _off_ will increase the routing performance a little. | ✓️ | | | `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | | `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | | `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | From 8768380908eabfcb3ab2c2295dfbdde9f5724232 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 20 Dec 2023 12:21:08 +0100 Subject: [PATCH 004/356] Apply review feedback --- docs/Configuration.md | 2 +- .../org/opentripplanner/ext/restapi/mapping/LegMapper.java | 1 + .../org/opentripplanner/ext/restapi/mapping/PlaceMapper.java | 1 + .../org/opentripplanner/ext/restapi/mapping/RouteMapper.java | 1 + .../org/opentripplanner/ext/restapi/mapping/StopMapper.java | 1 + .../org/opentripplanner/ext/restapi/mapping/TripMapper.java | 1 + .../opentripplanner/ext/restapi/mapping/TripTimeMapper.java | 1 + .../layers/stations/DigitransitStationPropertyMapper.java | 2 +- .../layers/stops/DigitransitStopPropertyMapper.java | 2 +- .../DigitransitVehicleParkingGroupPropertyMapper.java | 2 +- .../DigitransitVehicleParkingPropertyMapper.java | 2 +- .../StadtnaviVehicleParkingPropertyMapper.java | 2 +- ...igitransitRealtimeVehicleRentalStationPropertyMapper.java | 2 +- .../mapper/DigitransitVehicleRentalPropertyMapper.java | 2 +- .../DigitransitVehicleRentalStationPropertyMapper.java | 2 +- .../restapi/mapping => framework/i18n}/I18NStringMapper.java | 5 ++--- .../java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java | 2 +- .../java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java | 2 +- .../apis/transmodel/support/ExecutionResultMapper.java | 2 +- .../opentripplanner/framework/application/OTPFeature.java | 2 +- .../graphql}/GraphQLResponseSerializer.java | 3 ++- .../inspector/vector/DebugClientAreaStopPropertyMapper.java | 2 +- 22 files changed, 24 insertions(+), 18 deletions(-) rename src/ext/java/org/opentripplanner/{ext/restapi/mapping => framework/i18n}/I18NStringMapper.java (76%) rename src/main/java/org/opentripplanner/{apis/common/json => framework/graphql}/GraphQLResponseSerializer.java (94%) diff --git a/docs/Configuration.md b/docs/Configuration.md index 7da21ea2175..a0161c4ae20 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -235,7 +235,6 @@ Here is a list of all features which can be toggled on/off and their default val | `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | | `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | | `TransmodelGraphQlApi` | Enable Transmodel (NeTEx) GraphQL API. | ✓️ | ✓️ | -| `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | | `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | | `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | | `Co2Emissions` | Enable the emissions sandbox module. | | ✓️ | @@ -243,6 +242,7 @@ Here is a list of all features which can be toggled on/off and their default val | `FaresV2` | Enable import of GTFS-Fares v2 data. | | ✓️ | | `FlexRouting` | Enable FLEX routing. | | ✓️ | | `GoogleCloudStorage` | Enable Google Cloud Storage integration. | | ✓️ | +| `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | | `RealtimeResolver` | When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data | | ✓️ | | `ReportApi` | Enable the report API. | | ✓️ | | `RestAPIPassInDefaultConfigAsJson` | Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! | | | diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java index 91b41c8ff81..f16a9e8fbf5 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java @@ -10,6 +10,7 @@ import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.ext.restapi.model.ApiLeg; import org.opentripplanner.framework.geometry.EncodedPolyline; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java index 3ebdc678f1e..b1eb3410af8 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/PlaceMapper.java @@ -11,6 +11,7 @@ import org.opentripplanner.ext.restapi.model.ApiPlace; import org.opentripplanner.ext.restapi.model.ApiVehicleParkingSpaces; import org.opentripplanner.ext.restapi.model.ApiVehicleParkingWithEntrance; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.VehicleParkingWithEntrance; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java index 374fad1e94b..decee369a17 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/RouteMapper.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.ext.restapi.model.ApiRoute; import org.opentripplanner.ext.restapi.model.ApiRouteShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Branding; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java index 7dc911120d5..9e3c8b04262 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/StopMapper.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.ext.restapi.model.ApiStop; import org.opentripplanner.ext.restapi.model.ApiStopShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.site.StopLocation; public class StopMapper { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java index 891741f531e..f4894a4a7a3 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripMapper.java @@ -5,6 +5,7 @@ import java.util.stream.Stream; import org.opentripplanner.ext.restapi.model.ApiTrip; import org.opentripplanner.ext.restapi.model.ApiTripShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.Trip; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java index 3cbb71cdb72..f1f37e6d8b4 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.ext.restapi.model.ApiRealTimeState; import org.opentripplanner.ext.restapi.model.ApiTripTimeShort; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.model.TripTimeOnDate; public class TripTimeMapper { diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java index 6e37471495e..b7b21e01c38 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; import org.json.simple.JSONArray; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Station; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java index 597480d493b..d2b72e36cd3 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java @@ -9,7 +9,7 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java index cb2939da610..66cb6060ca9 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java @@ -6,7 +6,7 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; public class DigitransitVehicleParkingGroupPropertyMapper diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java index a265d0552d0..27d2b78776b 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java @@ -6,7 +6,7 @@ import java.util.Locale; import javax.annotation.Nonnull; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java index 8c1e24f8321..7ff573864a2 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java @@ -5,7 +5,7 @@ import java.util.Locale; import org.json.simple.JSONObject; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.model.calendar.openinghours.OsmOpeningHoursSupport; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java index 949cb071de4..87b5cf9e126 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.Locale; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java index 88549242b93..90e553e6320 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Locale; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java index de0d3aa9bc0..6d82f592b38 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java @@ -6,7 +6,7 @@ import java.util.Locale; import java.util.stream.Collectors; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/I18NStringMapper.java b/src/ext/java/org/opentripplanner/framework/i18n/I18NStringMapper.java similarity index 76% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/I18NStringMapper.java rename to src/ext/java/org/opentripplanner/framework/i18n/I18NStringMapper.java index f7adef24108..acdb30b301f 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/I18NStringMapper.java +++ b/src/ext/java/org/opentripplanner/framework/i18n/I18NStringMapper.java @@ -1,9 +1,8 @@ -package org.opentripplanner.ext.restapi.mapping; +package org.opentripplanner.framework.i18n; import java.util.Locale; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.opentripplanner.framework.i18n.I18NString; public class I18NStringMapper { @@ -24,7 +23,7 @@ public String mapNonnullToApi(I18NString string) { } @Nullable - static String mapToApi(I18NString string, Locale locale) { + public static String mapToApi(I18NString string, Locale locale) { return string == null ? null : string.toString(locale); } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java index 955fd8222da..b9b93190816 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Future; -import org.opentripplanner.apis.common.json.GraphQLResponseSerializer; +import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 9a4283d198a..b50bbaa9b9e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -26,7 +26,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.opentripplanner.apis.common.json.GraphQLResponseSerializer; import org.opentripplanner.apis.gtfs.datafetchers.AgencyImpl; import org.opentripplanner.apis.gtfs.datafetchers.AlertEntityTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.AlertImpl; @@ -88,6 +87,7 @@ import org.opentripplanner.ext.actuator.MicrometerGraphQLInstrumentation; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.concurrent.OtpRequestThreadFactory; +import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java index e6a5fea3ba0..d0ccb198e16 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/support/ExecutionResultMapper.java @@ -4,8 +4,8 @@ import graphql.ExecutionResult; import graphql.GraphQLError; import jakarta.ws.rs.core.Response; -import org.opentripplanner.apis.common.json.GraphQLResponseSerializer; import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.opentripplanner.framework.http.OtpHttpStatus; /** diff --git a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java index 766fb136ecd..816279d5a95 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java +++ b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java @@ -64,7 +64,6 @@ public enum OTPFeature { "Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little." ), TransmodelGraphQlApi(true, true, "Enable Transmodel (NeTEx) GraphQL API."), - LegacyRestApi(true, true, "Enable legacy REST API. This API will be removed in the future."), /* Sandbox extension features - Must be turned OFF by default */ @@ -83,6 +82,7 @@ public enum OTPFeature { FaresV2(false, true, "Enable import of GTFS-Fares v2 data."), FlexRouting(false, true, "Enable FLEX routing."), GoogleCloudStorage(false, true, "Enable Google Cloud Storage integration."), + LegacyRestApi(true, true, "Enable legacy REST API. This API will be removed in the future."), RealtimeResolver( false, true, diff --git a/src/main/java/org/opentripplanner/apis/common/json/GraphQLResponseSerializer.java b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java similarity index 94% rename from src/main/java/org/opentripplanner/apis/common/json/GraphQLResponseSerializer.java rename to src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java index de068d170e9..25242456722 100644 --- a/src/main/java/org/opentripplanner/apis/common/json/GraphQLResponseSerializer.java +++ b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.json; +package org.opentripplanner.framework.graphql; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -10,6 +10,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import org.opentripplanner.apis.common.json.JSONObjectMapperProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java index db88579b35f..fb50a25fd33 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Locale; import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.ext.restapi.mapping.I18NStringMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; From 4264ab8ed8933574a2272ccb34d39756b43a3f2b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 21 Dec 2023 12:08:51 +0100 Subject: [PATCH 005/356] Introduce fallback zone id if none could be derived from the system --- .../api/common/RoutingResource.java | 3 +- .../apis/gtfs/mapping/RouteRequestMapper.java | 3 +- .../framework/application/ZoneIdFallback.java | 39 +++++++++++++++++++ .../framework/logging/Throttle.java | 4 ++ .../mapping/GraphPathToItineraryMapper.java | 3 +- .../service/DefaultRoutingService.java | 3 +- 6 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/main/java/org/opentripplanner/api/common/RoutingResource.java index 9cb4f139bc4..a97a8368187 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/main/java/org/opentripplanner/api/common/RoutingResource.java @@ -21,6 +21,7 @@ import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; import org.opentripplanner.framework.application.OTPFeature; +import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.RouteRequest; @@ -711,7 +712,7 @@ protected RouteRequest buildRequest(MultivaluedMap queryParamete { //FIXME: move into setter method on routing request - ZoneId tz = serverContext.transitService().getTimeZone(); + ZoneId tz = ZoneIdFallback.zoneId(serverContext.transitService().getTimeZone()); if (date == null && time != null) { // Time was provided but not date LOG.debug("parsing ISO datetime {}", time); try { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index ab9e8bce823..7b47f3231c9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -16,6 +16,7 @@ import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.RouteRequest; @@ -54,7 +55,7 @@ public static RouteRequest toRouteRequest( request.setDateTime( environment.getArgument("date"), environment.getArgument("time"), - context.transitService().getTimeZone() + ZoneIdFallback.zoneId(context.transitService().getTimeZone()) ); callWith.argument("wheelchair", request::setWheelchair); diff --git a/src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java b/src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java new file mode 100644 index 00000000000..260fb40f0bf --- /dev/null +++ b/src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java @@ -0,0 +1,39 @@ +package org.opentripplanner.framework.application; + +import java.time.ZoneId; +import javax.annotation.Nullable; +import org.opentripplanner.framework.logging.Throttle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class provides a fallback mechanism for retrieving a zone id (=time zone). + * If a ZoneId is not provided, it returns a default fallback ZoneId (UTC). + *

+ * This situation happens when you don't load any transit data into the graph but want to route + * anyway, perhaps only on the street network. + */ +public class ZoneIdFallback { + + private static final Logger LOG = LoggerFactory.getLogger(ZoneIdFallback.class); + private static final ZoneId FALLBACK = ZoneId.of("UTC"); + private static final Throttle THROTTLE = Throttle.ofOneMinute(); + + /** + * Accepts a nullable zone id (time zone) and returns UTC as the fallback. + */ + public static ZoneId zoneId(@Nullable ZoneId id) { + if (id == null) { + THROTTLE.throttle(() -> { + LOG.warn( + "Your instance doesn't contain a time zone (which is usually derived from transit data). Assuming {}.", + FALLBACK + ); + LOG.warn("Please double-check that transit data was correctly loaded."); + }); + return FALLBACK; + } else { + return id; + } + } +} diff --git a/src/main/java/org/opentripplanner/framework/logging/Throttle.java b/src/main/java/org/opentripplanner/framework/logging/Throttle.java index 47417aa974a..631d59a2697 100644 --- a/src/main/java/org/opentripplanner/framework/logging/Throttle.java +++ b/src/main/java/org/opentripplanner/framework/logging/Throttle.java @@ -35,6 +35,10 @@ public static Throttle ofOneSecond() { return new Throttle(1000); } + public static Throttle ofOneMinute() { + return new Throttle(1000 * 60); + } + public String setupInfo() { return setupInfo; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java index 9858ccfee50..c363689d03d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java @@ -16,6 +16,7 @@ import org.opentripplanner.ext.flex.FlexibleTransitLeg; import org.opentripplanner.ext.flex.edgetype.FlexTripEdge; import org.opentripplanner.framework.application.OTPFeature; +import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.plan.ElevationProfile; @@ -58,7 +59,7 @@ public GraphPathToItineraryMapper( StreetNotesService streetNotesService, double ellipsoidToGeoidDifference ) { - this.timeZone = timeZone; + this.timeZone = ZoneIdFallback.zoneId(timeZone); this.streetNotesService = streetNotesService; this.ellipsoidToGeoidDifference = ellipsoidToGeoidDifference; } diff --git a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java index 320ffb2117d..a9a887588dd 100644 --- a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java +++ b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java @@ -2,6 +2,7 @@ import java.time.ZoneId; import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.tostring.MultiLineToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.RoutingWorker; @@ -30,7 +31,7 @@ public class DefaultRoutingService implements RoutingService { public DefaultRoutingService(OtpServerRequestContext serverContext) { this.serverContext = serverContext; - this.timeZone = serverContext.transitService().getTimeZone(); + this.timeZone = ZoneIdFallback.zoneId(serverContext.transitService().getTimeZone()); } @Override From bf2bef8b6795720a1aa65911f40d17c6174fdd0d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 21 Dec 2023 12:18:40 +0100 Subject: [PATCH 006/356] Move fallback class --- .../java/org/opentripplanner/api/common/RoutingResource.java | 2 +- .../{framework/application => api/support}/ZoneIdFallback.java | 2 +- .../opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java | 2 +- .../routing/algorithm/mapping/GraphPathToItineraryMapper.java | 2 +- .../opentripplanner/routing/service/DefaultRoutingService.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/main/java/org/opentripplanner/{framework/application => api/support}/ZoneIdFallback.java (96%) diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/main/java/org/opentripplanner/api/common/RoutingResource.java index a97a8368187..dab06e970ce 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/main/java/org/opentripplanner/api/common/RoutingResource.java @@ -19,9 +19,9 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import org.opentripplanner.api.parameter.QualifiedModeSet; +import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.RouteRequest; diff --git a/src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java b/src/main/java/org/opentripplanner/api/support/ZoneIdFallback.java similarity index 96% rename from src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java rename to src/main/java/org/opentripplanner/api/support/ZoneIdFallback.java index 260fb40f0bf..0175337e2d4 100644 --- a/src/main/java/org/opentripplanner/framework/application/ZoneIdFallback.java +++ b/src/main/java/org/opentripplanner/api/support/ZoneIdFallback.java @@ -1,4 +1,4 @@ -package org.opentripplanner.framework.application; +package org.opentripplanner.api.support; import java.time.ZoneId; import javax.annotation.Nullable; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index 7b47f3231c9..306abf8945f 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -15,8 +15,8 @@ import org.opentripplanner.api.common.LocationStringParser; import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; +import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; -import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.RouteRequest; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java index c363689d03d..ee86f8de720 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java @@ -12,11 +12,11 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; +import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.ext.flex.FlexibleTransitLeg; import org.opentripplanner.ext.flex.edgetype.FlexTripEdge; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.plan.ElevationProfile; diff --git a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java index a9a887588dd..92ccd2cc786 100644 --- a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java +++ b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.service; import java.time.ZoneId; +import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.framework.application.OTPRequestTimeoutException; -import org.opentripplanner.framework.application.ZoneIdFallback; import org.opentripplanner.framework.tostring.MultiLineToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.RoutingWorker; From 8c8967a5a1ac66aa57123cfc92fa513a2a8b6fee Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 21 Dec 2023 12:24:28 +0100 Subject: [PATCH 007/356] Add test --- .../api/support/ZoneIdFallbackTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java diff --git a/src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java b/src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java new file mode 100644 index 00000000000..02013f0856b --- /dev/null +++ b/src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java @@ -0,0 +1,19 @@ +package org.opentripplanner.api.support; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.opentripplanner._support.time.ZoneIds; + +class ZoneIdFallbackTest { + + @Test + void fallback() { + assertEquals(ZoneIds.UTC, ZoneIdFallback.zoneId(null)); + } + + @Test + void keepOriginal() { + assertEquals(ZoneIds.BERLIN, ZoneIdFallback.zoneId(ZoneIds.BERLIN)); + } +} From 22f05019e5493209b38c2930b21cd684c138d4b6 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 20 Dec 2023 12:54:28 +0100 Subject: [PATCH 008/356] refactor: Rename TransitGroupPriority to TransitPriorityGroup --- docs/RouteRequest.md | 24 +++++----- .../common/RequestToPreferencesMapper.java | 4 +- .../api/common/RoutingResource.java | 4 +- .../preferences/TransitPreferencesMapper.java | 2 +- .../apis/transmodel/model/plan/TripQuery.java | 14 +++--- .../raptor/api/model/RaptorTripPattern.java | 2 +- .../api/request/MultiCriteriaRequest.java | 10 ++--- ...java => RaptorTransitGroupCalculator.java} | 8 ++-- .../internalapi/PassThroughPointsService.java | 2 +- .../configure/McRangeRaptorConfig.java | 13 +++--- ...a => TransitGroupPriorityRideFactory.java} | 21 ++++----- ...p32n.java => TransitGroupPriority32n.java} | 20 ++++----- .../transit/mappers/RaptorRequestMapper.java | 8 ++-- .../request/PriorityGroupConfigurator.java | 20 ++++----- .../transit/request/PriorityGroupMatcher.java | 8 ++-- .../RaptorRoutingRequestTransitData.java | 6 +-- ...aptorRoutingRequestTransitDataCreator.java | 2 +- .../preference/TransitPreferences.java | 26 +++++------ .../api/request/request/TransitRequest.java | 16 +++---- ...oupSelect.java => TransitGroupSelect.java} | 20 ++++----- .../routerequest/RouteRequestConfig.java | 21 ++++----- ...g.java => TransitGroupPriorityConfig.java} | 30 ++++++------- .../apis/transmodel/schema.graphql | 10 ++--- .../moduletests/K01_TransitPriorityTest.java | 16 +++---- .../K02_TransitPriorityDestinationTest.java | 17 +++---- ....java => TransitGroupPriority32nTest.java} | 44 +++++++++---------- .../PriorityGroupConfiguratorTest.java | 40 ++++++++--------- .../request/PriorityGroupMatcherTest.java | 18 ++++---- .../preference/TransitPreferencesTest.java | 6 +-- 29 files changed, 207 insertions(+), 225 deletions(-) rename src/main/java/org/opentripplanner/raptor/api/request/{RaptorTransitPriorityGroupCalculator.java => RaptorTransitGroupCalculator.java} (71%) rename src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/{TransitPriorityGroupRideFactory.java => TransitGroupPriorityRideFactory.java} (67%) rename src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/{TransitPriorityGroup32n.java => TransitGroupPriority32n.java} (76%) rename src/main/java/org/opentripplanner/routing/api/request/request/filter/{TransitPriorityGroupSelect.java => TransitGroupSelect.java} (87%) rename src/main/java/org/opentripplanner/standalone/config/routerequest/{TransitPriorityGroupConfig.java => TransitGroupPriorityConfig.java} (76%) rename src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/{TransitPriorityGroup32nTest.java => TransitGroupPriority32nTest.java} (51%) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 9e891cf732d..cef482eb781 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -57,7 +57,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | numItineraries | `integer` | The maximum number of itineraries to return. | *Optional* | `50` | 2.0 | | [optimize](#rd_optimize) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | | [otherThanPreferredRoutesPenalty](#rd_otherThanPreferredRoutesPenalty) | `integer` | Penalty added for using every route that is not preferred if user set any route as preferred. | *Optional* | `300` | 2.0 | -| [relaxTransitPriorityGroup](#rd_relaxTransitPriorityGroup) | `string` | The relax function for transit-priority-groups | *Optional* | `"0s + 1.00 t"` | 2.5 | +| [relaxTransitGroupPriority](#rd_relaxTransitGroupPriority) | `string` | The relax function for transit-group-priority | *Optional* | `"0s + 1.00 t"` | 2.5 | | [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | | [searchWindow](#rd_searchWindow) | `duration` | The duration of the search-window. | *Optional* | | 2.0 | | stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | @@ -108,7 +108,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | |    [minSafeWaitTimeFactor](#rd_to_minSafeWaitTimeFactor) | `double` | Used to set a maximum wait-time cost, base on min-safe-transfer-time. | *Optional* | `5.0` | 2.1 | |    [optimizeTransferWaitTime](#rd_to_optimizeTransferWaitTime) | `boolean` | This enables the transfer wait time optimization. | *Optional* | `true` | 2.1 | -| [transitPriorityGroups](#rd_transitPriorityGroups) | `object` | Transit priority groups configuration | *Optional* | | 2.5 | +| [transitGroupPriority](#rd_transitGroupPriority) | `object` | Group transit patterns and give each group a mutual advantage in the Raptor search. | *Optional* | | 2.5 | | [transitReluctanceForMode](#rd_transitReluctanceForMode) | `enum map of double` | Transit reluctance for a given transport mode | *Optional* | | 2.1 | | [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | |    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | @@ -247,16 +247,16 @@ Penalty added for using every route that is not preferred if user set any route We return number of seconds that we are willing to wait for preferred route. -

relaxTransitPriorityGroup

+

relaxTransitGroupPriority

**Since version:** `2.5` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"0s + 1.00 t"` **Path:** /routingDefaults -The relax function for transit-priority-groups +The relax function for transit-group-priority -A path is considered optimal if the generalized-cost is less than the -generalized-cost of another path. If this parameter is set, the comparison is relaxed -further if they belong to different transit-priority-groups. +A path is considered optimal if the generalized-cost is less than the generalized-cost of +another path. If this parameter is set, the comparison is relaxed further if they belong +to different transit groups.

relaxTransitSearchGeneralizedCostAtDestination

@@ -812,22 +812,20 @@ This enables the transfer wait time optimization. If not enabled generalizedCost function is used to pick the optimal transfer point. -

transitPriorityGroups

+

transitGroupPriority

**Since version:** `2.5` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` **Path:** /routingDefaults -Transit priority groups configuration +Group transit patterns and give each group a mutual advantage in the Raptor search. Use this to separate transit patterns into groups. Each group will be given a group-id. A path (multiple legs) will then have a set of group-ids based on the group-id from each leg. Hence, two paths with a different set of group-ids will BOTH be optimal unless the cost is -worse than the relaxation specified in the `relaxTransitPriorityGroup` parameter. This is +worse than the relaxation specified in the `relaxTransitGroupPriority` parameter. This is only available in the TransmodelAPI for now. -Unmatched patterns are put in the BASE priority-group (group id: 0). This group is special. -If a path only have legs in the base group, then that path dominates other paths, but other -paths must be better to make it. +Unmatched patterns are put in the BASE priority-group. **THIS IS STILL AN EXPERIMENTAL FEATURE - IT MAY CHANGE WITHOUT ANY NOTICE!** diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index aa827ae5b4c..6a8b71fe939 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -95,9 +95,9 @@ private BoardAndAlightSlack mapTransit() { setIfNotNull(req.otherThanPreferredRoutesPenalty, tr::setOtherThanPreferredRoutesPenalty); setIfNotNull(req.ignoreRealtimeUpdates, tr::setIgnoreRealtimeUpdates); - if (req.relaxTransitPriorityGroup != null) { + if (req.relaxTransitGroupPriority != null) { tr.withTransitGroupPriorityGeneralizedCostSlack( - CostLinearFunction.of(req.relaxTransitPriorityGroup) + CostLinearFunction.of(req.relaxTransitGroupPriority) ); } else { setIfNotNull( diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/main/java/org/opentripplanner/api/common/RoutingResource.java index 9cb4f139bc4..72812234b29 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/main/java/org/opentripplanner/api/common/RoutingResource.java @@ -658,8 +658,8 @@ public abstract class RoutingResource { @QueryParam("useVehicleParkingAvailabilityInformation") protected Boolean useVehicleParkingAvailabilityInformation; - @QueryParam("relaxTransitPriorityGroup") - protected String relaxTransitPriorityGroup; + @QueryParam("relaxTransitGroupPriority") + protected String relaxTransitGroupPriority; /** * Whether non-optimal transit paths at the destination should be returned. diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java index caa8ebf7715..d4bf92b828c 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java @@ -34,7 +34,7 @@ public static void mapTransitPreferences( callWith.argument("includePlannedCancellations", transit::setIncludePlannedCancellations); callWith.argument("includeRealtimeCancellations", transit::setIncludeRealtimeCancellations); callWith.argument( - "relaxTransitPriorityGroup", + "relaxTransitGroupPriority", transit::withTransitGroupPriorityGeneralizedCostSlack ); callWith.argument( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java index d06c5954444..52bafc1f28b 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java @@ -277,16 +277,16 @@ public static GraphQLFieldDefinition create( .argument( GraphQLArgument .newArgument() - .name("relaxTransitPriorityGroup") + .name("relaxTransitGroupPriority") .description( """ Relax generalized-cost when comparing trips with a different set of - transit-priority-groups. The groups are set server side for service-journey and + transit-group-priorities. The groups are set server side for service-journey and can not be configured in the API. This mainly helps to return competition neutral - services. Long distance authorities are put in different transit-priority-groups. + services. Long distance authorities are put in different transit-groups. This relaxes the comparison inside the routing engine for each stop-arrival. If two - paths have a different set of transit-priority-groups, then the generalized-cost + paths have a different set of transit-group-priorities, then the generalized-cost comparison is relaxed. The final set of paths are filtered through the normal itinerary-filters. @@ -298,9 +298,9 @@ public static GraphQLFieldDefinition create( ) .type(RelaxCostType.INPUT_TYPE) .defaultValueLiteral( - preferences.transit().relaxTransitPriorityGroup().isNormal() + preferences.transit().relaxTransitGroupPriority().isNormal() ? NullValue.of() - : RelaxCostType.valueOf(preferences.transit().relaxTransitPriorityGroup()) + : RelaxCostType.valueOf(preferences.transit().relaxTransitGroupPriority()) ) .build() ) @@ -523,7 +523,7 @@ public static GraphQLFieldDefinition create( GraphQLArgument .newArgument() .name("relaxTransitSearchGeneralizedCostAtDestination") - .deprecate("This is replaced by 'relaxTransitPriorityGroup'.") + .deprecate("This is replaced by 'relaxTransitGroupPriority'.") .description( """ Whether non-optimal transit paths at the destination should be returned. Let c be the diff --git a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java b/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java index 98a2533486b..e5be1cab0d5 100644 --- a/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java +++ b/src/main/java/org/opentripplanner/raptor/api/model/RaptorTripPattern.java @@ -46,7 +46,7 @@ public interface RaptorTripPattern { int slackIndex(); /** - * A pattern may belong to a transit-priority-group. Each group is given an advantage during + * A pattern may belong to a transit-group-priority. Each group is given an advantage during * the multi-criteria search, so the best alternative for each group is found. */ int priorityGroupId(); diff --git a/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java b/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java index 64cd9dae1a5..368b4660922 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java +++ b/src/main/java/org/opentripplanner/raptor/api/request/MultiCriteriaRequest.java @@ -18,7 +18,7 @@ public class MultiCriteriaRequest { private final RelaxFunction relaxC1; @Nullable - private final RaptorTransitPriorityGroupCalculator transitPriorityCalculator; + private final RaptorTransitGroupCalculator transitPriorityCalculator; private final List passThroughPoints; @@ -63,7 +63,7 @@ public RelaxFunction relaxC1() { return relaxC1; } - public Optional transitPriorityCalculator() { + public Optional transitPriorityCalculator() { return Optional.ofNullable(transitPriorityCalculator); } @@ -140,7 +140,7 @@ public static class Builder { private final MultiCriteriaRequest original; private RelaxFunction relaxC1; - private RaptorTransitPriorityGroupCalculator transitPriorityCalculator; + private RaptorTransitGroupCalculator transitPriorityCalculator; private List passThroughPoints; private Double relaxCostAtDestination; @@ -163,11 +163,11 @@ public Builder withRelaxC1(RelaxFunction relaxC1) { } @Nullable - public RaptorTransitPriorityGroupCalculator transitPriorityCalculator() { + public RaptorTransitGroupCalculator transitPriorityCalculator() { return transitPriorityCalculator; } - public Builder withTransitPriorityCalculator(RaptorTransitPriorityGroupCalculator value) { + public Builder withTransitPriorityCalculator(RaptorTransitGroupCalculator value) { transitPriorityCalculator = value; return this; } diff --git a/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitPriorityGroupCalculator.java b/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupCalculator.java similarity index 71% rename from src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitPriorityGroupCalculator.java rename to src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupCalculator.java index c3890fa47b3..b5f0598415e 100644 --- a/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitPriorityGroupCalculator.java +++ b/src/main/java/org/opentripplanner/raptor/api/request/RaptorTransitGroupCalculator.java @@ -2,19 +2,19 @@ import org.opentripplanner.raptor.api.model.DominanceFunction; -public interface RaptorTransitPriorityGroupCalculator { +public interface RaptorTransitGroupCalculator { /** - * Merge in the trip transit priority group id with an existing set. Note! Both the set + * Merge in the transit group id with an existing set. Note! Both the set * and the group id type is {@code int}. * * @param currentGroupIds the set of groupIds for all legs in a path. * @param boardingGroupId the transit group id to add to the given set. * @return the new computed set of groupIds */ - int mergeTransitPriorityGroupIds(int currentGroupIds, int boardingGroupId); + int mergeGroupIds(int currentGroupIds, int boardingGroupId); /** - * This is the dominance function to use for comparing transit-priority-groupIds. + * This is the dominance function to use for comparing transit-groups. * It is critical that the implementation is "static" so it can be inlined, since it * is run in the innermost loop of Raptor. */ diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java index 69899b55688..4932d9c46fe 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/internalapi/PassThroughPointsService.java @@ -54,7 +54,7 @@ default boolean isNoop() { void updateC2Value(int currentPathC2, IntConsumer update); /** - * This is the dominance function to use for comparing transit-priority-groupIds. + * This is the dominance function to use for comparing transit-group-priorityIds. * It is critical that the implementation is "static" so it can be inlined, since it * is run in the innermost loop of Raptor. */ diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java index e7aa07fb914..8eef90950dd 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/configure/McRangeRaptorConfig.java @@ -6,7 +6,7 @@ import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.request.MultiCriteriaRequest; -import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; import org.opentripplanner.raptor.rangeraptor.context.SearchContext; import org.opentripplanner.raptor.rangeraptor.internalapi.Heuristics; import org.opentripplanner.raptor.rangeraptor.internalapi.ParetoSetCost; @@ -29,7 +29,7 @@ import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c1.PatternRideC1; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2.PassThroughRideFactory; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2.PatternRideC2; -import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2.TransitPriorityGroupRideFactory; +import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.c2.TransitGroupPriorityRideFactory; import org.opentripplanner.raptor.rangeraptor.path.DestinationArrivalPaths; import org.opentripplanner.raptor.rangeraptor.path.configure.PathConfig; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; @@ -173,7 +173,8 @@ private MultiCriteriaRequest mcRequest() { } /** - * Currently "transit-priority-groups" is the only feature using two multi-criteria(c2). + * Use c2 in the search, this is use-case specific. For example the pass-through or + * transit-group-priority features uses the c2 value. */ private boolean includeC2() { return mcRequest().includeC2(); @@ -184,7 +185,7 @@ private PatternRideFactory> createPatternRideC2Factory() { return new PassThroughRideFactory<>(passThroughPointsService); } if (isTransitPriority()) { - return new TransitPriorityGroupRideFactory<>(getTransitPriorityGroupCalculator()); + return new TransitGroupPriorityRideFactory<>(getTransitGroupPriorityCalculator()); } throw new IllegalStateException("Only pass-through and transit-priority uses c2."); } @@ -195,12 +196,12 @@ private DominanceFunction dominanceFunctionC2() { return passThroughPointsService.dominanceFunction(); } if (isTransitPriority()) { - return getTransitPriorityGroupCalculator().dominanceFunction(); + return getTransitGroupPriorityCalculator().dominanceFunction(); } return null; } - private RaptorTransitPriorityGroupCalculator getTransitPriorityGroupCalculator() { + private RaptorTransitGroupCalculator getTransitGroupPriorityCalculator() { return mcRequest().transitPriorityCalculator().orElseThrow(); } diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitPriorityGroupRideFactory.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java similarity index 67% rename from src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitPriorityGroupRideFactory.java rename to src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java index eca049233b9..5d65c40d021 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitPriorityGroupRideFactory.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/multicriteria/ride/c2/TransitGroupPriorityRideFactory.java @@ -2,25 +2,25 @@ import org.opentripplanner.raptor.api.model.RaptorTripPattern; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; -import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; import org.opentripplanner.raptor.rangeraptor.multicriteria.arrivals.McStopArrival; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.PatternRide; import org.opentripplanner.raptor.rangeraptor.multicriteria.ride.PatternRideFactory; /** - * This factory creates new {@link PatternRide}s and merge in transit-priority-group ids + * This factory creates new {@link PatternRide}s and merge in transit-group-priority ids * into c2. */ -public class TransitPriorityGroupRideFactory +public class TransitGroupPriorityRideFactory implements PatternRideFactory> { private int currentPatternGroupPriority; - private final RaptorTransitPriorityGroupCalculator transitPriorityGroupCalculator; + private final RaptorTransitGroupCalculator transitGroupPriorityCalculator; - public TransitPriorityGroupRideFactory( - RaptorTransitPriorityGroupCalculator transitPriorityGroupCalculator + public TransitGroupPriorityRideFactory( + RaptorTransitGroupCalculator transitGroupPriorityCalculator ) { - this.transitPriorityGroupCalculator = transitPriorityGroupCalculator; + this.transitGroupPriorityCalculator = transitGroupPriorityCalculator; } @Override @@ -52,12 +52,9 @@ public void prepareForTransitWith(RaptorTripPattern pattern) { } /** - * Currently transit-priority-group is the only usage of c2 + * Currently transit-group-priority is the only usage of c2 */ private int calculateC2(int c2) { - return transitPriorityGroupCalculator.mergeTransitPriorityGroupIds( - c2, - currentPatternGroupPriority - ); + return transitGroupPriorityCalculator.mergeGroupIds(c2, currentPatternGroupPriority); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitPriorityGroup32n.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitGroupPriority32n.java similarity index 76% rename from src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitPriorityGroup32n.java rename to src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitGroupPriority32n.java index 9b744932b8b..feb3f6f7b3a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitPriorityGroup32n.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitGroupPriority32n.java @@ -1,33 +1,33 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority; import org.opentripplanner.raptor.api.model.DominanceFunction; -import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; /** * This is a "BitSet" implementation for groupId. It can store upto 32 groups, * a set with few elements does NOT dominate a set with more elements. */ -public class TransitPriorityGroup32n { +public class TransitGroupPriority32n { private static final int GROUP_ZERO = 0; private static final int MIN_SEQ_NO = 0; private static final int MAX_SEQ_NO = 32; - public static RaptorTransitPriorityGroupCalculator priorityCalculator() { - return new RaptorTransitPriorityGroupCalculator() { + public static RaptorTransitGroupCalculator priorityCalculator() { + return new RaptorTransitGroupCalculator() { @Override - public int mergeTransitPriorityGroupIds(int currentGroupIds, int boardingGroupId) { + public int mergeGroupIds(int currentGroupIds, int boardingGroupId) { return mergeInGroupId(currentGroupIds, boardingGroupId); } @Override public DominanceFunction dominanceFunction() { - return TransitPriorityGroup32n::dominate; + return TransitGroupPriority32n::dominate; } @Override public String toString() { - return "TransitPriorityGroup32nCalculator{}"; + return "TransitGroupPriority32nCalculator{}"; } }; } @@ -42,7 +42,7 @@ public static boolean dominate(int left, int right) { @Override public String toString() { - return "TransitPriorityGroup32n{}"; + return "TransitGroupPriority32n{}"; } /** @@ -64,12 +64,12 @@ public static int mergeInGroupId(final int currentSetOfGroupIds, final int newGr private static void assertValidGroupSeqNo(int priorityGroupIndex) { if (priorityGroupIndex < MIN_SEQ_NO) { throw new IllegalArgumentException( - "Transit priority group can not be a negative number: " + priorityGroupIndex + "Transit group priority can not be a negative number: " + priorityGroupIndex ); } if (priorityGroupIndex > MAX_SEQ_NO) { throw new IllegalArgumentException( - "Transit priority group exceeds max number of groups: " + + "Transit group priority exceeds max number of groups: " + priorityGroupIndex + " (MAX=" + MAX_SEQ_NO + diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java index 75c1bcf7214..e5384933750 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java @@ -21,7 +21,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority.TransitPriorityGroup32n; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority.TransitGroupPriority32n; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.transit.model.site.StopLocation; @@ -117,9 +117,9 @@ private RaptorRequest doMap() { builder.withMultiCriteria(mcBuilder -> { var pt = preferences.transit(); var r = pt.raptor(); - if (!pt.relaxTransitPriorityGroup().isNormal()) { - mcBuilder.withTransitPriorityCalculator(TransitPriorityGroup32n.priorityCalculator()); - mcBuilder.withRelaxC1(mapRelaxCost(pt.relaxTransitPriorityGroup())); + if (!pt.relaxTransitGroupPriority().isNormal()) { + mcBuilder.withTransitPriorityCalculator(TransitGroupPriority32n.priorityCalculator()); + mcBuilder.withRelaxC1(mapRelaxCost(pt.relaxTransitGroupPriority())); } else { mcBuilder.withPassThroughPoints(mapPassThroughPoints()); r.relaxGeneralizedCostAtDestination().ifPresent(mcBuilder::withRelaxCostAtDestination); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java index 25006af49d8..826b9c09a13 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java @@ -8,14 +8,14 @@ import java.util.List; import java.util.stream.Stream; import org.opentripplanner.framework.lang.ArrayUtils; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority.TransitPriorityGroup32n; -import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority.TransitGroupPriority32n; +import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.RoutingTripPattern; /** * This class dynamically builds an index of transit-group-ids from the - * provided {@link TransitPriorityGroupSelect}s while serving the caller with + * provided {@link TransitGroupSelect}s while serving the caller with * group-ids for each requested pattern. It is made for optimal * performance, since it is used in request scope. *

@@ -44,7 +44,7 @@ public class PriorityGroupConfigurator { */ private static final int GROUP_INDEX_COUNTER_START = 1; - private final int baseGroupId = TransitPriorityGroup32n.groupId(GROUP_INDEX_COUNTER_START); + private final int baseGroupId = TransitGroupPriority32n.groupId(GROUP_INDEX_COUNTER_START); private int groupIndexCounter = GROUP_INDEX_COUNTER_START; private final boolean enabled; private final PriorityGroupMatcher[] agencyMatchers; @@ -63,8 +63,8 @@ private PriorityGroupConfigurator() { } private PriorityGroupConfigurator( - Collection byAgency, - Collection global + Collection byAgency, + Collection global ) { this.agencyMatchers = PriorityGroupMatcher.of(byAgency); this.globalMatchers = PriorityGroupMatcher.of(global); @@ -80,8 +80,8 @@ public static PriorityGroupConfigurator empty() { } public static PriorityGroupConfigurator of( - Collection byAgency, - Collection global + Collection byAgency, + Collection global ) { if (Stream.of(byAgency, global).allMatch(Collection::isEmpty)) { return empty(); @@ -94,7 +94,7 @@ public static PriorityGroupConfigurator of( *

* @throws IllegalArgumentException if more than 32 group-ids are requested. */ - public int lookupTransitPriorityGroupId(RoutingTripPattern tripPattern) { + public int lookupTransitGroupPriorityId(RoutingTripPattern tripPattern) { if (!enabled || tripPattern == null) { return baseGroupId; } @@ -128,7 +128,7 @@ public int baseGroupId() { } private int nextGroupId() { - return TransitPriorityGroup32n.groupId(++groupIndexCounter); + return TransitGroupPriority32n.groupId(++groupIndexCounter); } /** Pair of matcher and groupId. Used only inside this class. */ diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java index 4d8a0475239..c017f2862ab 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcher.java @@ -15,13 +15,13 @@ import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; +import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; /** - * This class turns a {@link TransitPriorityGroupSelect} into a matcher. + * This class turns a {@link TransitGroupSelect} into a matcher. *

* Design: It uses the composite design pattern. A matcher is created for each * value in the "select", then the list of non-empty matchers is merged into @@ -42,7 +42,7 @@ boolean isEmpty() { } }; - public static PriorityGroupMatcher of(TransitPriorityGroupSelect select) { + public static PriorityGroupMatcher of(TransitGroupSelect select) { if (select.isEmpty()) { return NOOP; } @@ -65,7 +65,7 @@ public static PriorityGroupMatcher of(TransitPriorityGroupSelect select) { return andOf(list); } - static PriorityGroupMatcher[] of(Collection selectors) { + static PriorityGroupMatcher[] of(Collection selectors) { return selectors .stream() .map(PriorityGroupMatcher::of) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java index f1212b2f545..4338593d59d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitData.java @@ -92,7 +92,7 @@ public RaptorRoutingRequestTransitData( additionalPastSearchDays, additionalFutureSearchDays, filter, - createTransitPriorityGroupConfigurator(request) + createTransitGroupPriorityConfigurator(request) ); this.patternIndex = transitDataCreator.createPatternIndex(tripPatterns); this.activeTripPatternsPerStop = transitDataCreator.createTripPatternsPerStop(tripPatterns); @@ -243,8 +243,8 @@ public RaptorConstrainedBoardingSearch transferConstraintsReverseS return new ConstrainedBoardingSearch(false, toStopTransfers, fromStopTransfers); } - private PriorityGroupConfigurator createTransitPriorityGroupConfigurator(RouteRequest request) { - if (request.preferences().transit().relaxTransitPriorityGroup().isNormal()) { + private PriorityGroupConfigurator createTransitGroupPriorityConfigurator(RouteRequest request) { + if (request.preferences().transit().relaxTransitGroupPriority().isNormal()) { return PriorityGroupConfigurator.empty(); } var transitRequest = request.journey().transit(); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java index 0cb155facd5..b8f915d6eb4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java @@ -147,7 +147,7 @@ static List merge( tripPattern.getAlightingPossible(), BoardAlight.ALIGHT ), - priorityGroupConfigurator.lookupTransitPriorityGroupId(tripPattern) + priorityGroupConfigurator.lookupTransitGroupPriorityId(tripPattern) ) ); } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java index da5c4aad60d..c0a090937d9 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java @@ -26,7 +26,7 @@ public final class TransitPreferences implements Serializable { private final Map reluctanceForMode; private final Cost otherThanPreferredRoutesPenalty; private final CostLinearFunction unpreferredCost; - private final CostLinearFunction relaxTransitPriorityGroup; + private final CostLinearFunction relaxTransitGroupPriority; private final boolean ignoreRealtimeUpdates; private final boolean includePlannedCancellations; private final boolean includeRealtimeCancellations; @@ -37,7 +37,7 @@ private TransitPreferences() { this.reluctanceForMode = Map.of(); this.otherThanPreferredRoutesPenalty = Cost.costOfMinutes(5); this.unpreferredCost = CostLinearFunction.NORMAL; - this.relaxTransitPriorityGroup = CostLinearFunction.NORMAL; + this.relaxTransitGroupPriority = CostLinearFunction.NORMAL; this.ignoreRealtimeUpdates = false; this.includePlannedCancellations = false; this.includeRealtimeCancellations = false; @@ -50,7 +50,7 @@ private TransitPreferences(Builder builder) { this.reluctanceForMode = Map.copyOf(requireNonNull(builder.reluctanceForMode)); this.otherThanPreferredRoutesPenalty = builder.otherThanPreferredRoutesPenalty; this.unpreferredCost = requireNonNull(builder.unpreferredCost); - this.relaxTransitPriorityGroup = Objects.requireNonNull(builder.relaxTransitPriorityGroup); + this.relaxTransitGroupPriority = Objects.requireNonNull(builder.relaxTransitGroupPriority); this.ignoreRealtimeUpdates = builder.ignoreRealtimeUpdates; this.includePlannedCancellations = builder.includePlannedCancellations; this.includeRealtimeCancellations = builder.includeRealtimeCancellations; @@ -128,13 +128,13 @@ public CostLinearFunction unpreferredCost() { } /** - * This is used to relax the cost when comparing transit-priority-groups. The default is the - * NORMAL function({@code f(x) = x}. This is the same as not using priority-groups. The + * This is used to relax the cost when comparing transit-groups. The default is the + * NORMAL function({@code f(t) = t}. This is the same as not using priority-groups. The * coefficient must be in range {@code [1.0 to 4.0]} and the constant must be in range * {@code [$0 to $1440(4h)]}. */ - public CostLinearFunction relaxTransitPriorityGroup() { - return relaxTransitPriorityGroup; + public CostLinearFunction relaxTransitGroupPriority() { + return relaxTransitGroupPriority; } /** @@ -176,7 +176,7 @@ public boolean equals(Object o) { reluctanceForMode.equals(that.reluctanceForMode) && otherThanPreferredRoutesPenalty == that.otherThanPreferredRoutesPenalty && unpreferredCost.equals(that.unpreferredCost) && - Objects.equals(relaxTransitPriorityGroup, that.relaxTransitPriorityGroup) && + Objects.equals(relaxTransitGroupPriority, that.relaxTransitGroupPriority) && ignoreRealtimeUpdates == that.ignoreRealtimeUpdates && includePlannedCancellations == that.includePlannedCancellations && includeRealtimeCancellations == that.includeRealtimeCancellations && @@ -192,7 +192,7 @@ public int hashCode() { reluctanceForMode, otherThanPreferredRoutesPenalty, unpreferredCost, - relaxTransitPriorityGroup, + relaxTransitGroupPriority, ignoreRealtimeUpdates, includePlannedCancellations, includeRealtimeCancellations, @@ -213,7 +213,7 @@ public String toString() { DEFAULT.otherThanPreferredRoutesPenalty ) .addObj("unpreferredCost", unpreferredCost, DEFAULT.unpreferredCost) - .addObj("relaxTransitPriorityGroup", relaxTransitPriorityGroup, CostLinearFunction.NORMAL) + .addObj("relaxTransitGroupPriority", relaxTransitGroupPriority, CostLinearFunction.NORMAL) .addBoolIfTrue( "ignoreRealtimeUpdates", ignoreRealtimeUpdates != DEFAULT.ignoreRealtimeUpdates @@ -240,7 +240,7 @@ public static class Builder { private Map reluctanceForMode; private Cost otherThanPreferredRoutesPenalty; private CostLinearFunction unpreferredCost; - private CostLinearFunction relaxTransitPriorityGroup; + private CostLinearFunction relaxTransitGroupPriority; private boolean ignoreRealtimeUpdates; private boolean includePlannedCancellations; private boolean includeRealtimeCancellations; @@ -253,7 +253,7 @@ public Builder(TransitPreferences original) { this.reluctanceForMode = original.reluctanceForMode; this.otherThanPreferredRoutesPenalty = original.otherThanPreferredRoutesPenalty; this.unpreferredCost = original.unpreferredCost; - this.relaxTransitPriorityGroup = original.relaxTransitPriorityGroup; + this.relaxTransitGroupPriority = original.relaxTransitGroupPriority; this.ignoreRealtimeUpdates = original.ignoreRealtimeUpdates; this.includePlannedCancellations = original.includePlannedCancellations; this.includeRealtimeCancellations = original.includeRealtimeCancellations; @@ -303,7 +303,7 @@ public Builder setUnpreferredCostString(String constFunction) { } public Builder withTransitGroupPriorityGeneralizedCostSlack(CostLinearFunction value) { - this.relaxTransitPriorityGroup = value; + this.relaxTransitGroupPriority = value; return this; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java b/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java index 67a56249328..b5626c479a0 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java +++ b/src/main/java/org/opentripplanner/routing/api/request/request/TransitRequest.java @@ -8,7 +8,7 @@ import org.opentripplanner.routing.api.request.DebugRaptor; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; import org.opentripplanner.routing.api.request.request.filter.TransitFilter; -import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; +import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.framework.FeedScopedId; // TODO VIA: Javadoc @@ -31,8 +31,8 @@ public class TransitRequest implements Cloneable, Serializable { private List unpreferredRoutes = List.of(); - private List priorityGroupsByAgency = new ArrayList<>(); - private List priorityGroupsGlobal = new ArrayList<>(); + private List priorityGroupsByAgency = new ArrayList<>(); + private List priorityGroupsGlobal = new ArrayList<>(); private DebugRaptor raptorDebugging = new DebugRaptor(); public void setBannedTripsFromString(String ids) { @@ -64,16 +64,14 @@ public void setFilters(List filters) { *

* Note! Entities that are not matched are put in the BASE-GROUP with id 0. */ - public List priorityGroupsByAgency() { + public List priorityGroupsByAgency() { return priorityGroupsByAgency; } /** * All patterns matching the same select will be assigned the same group-id. */ - public void addPriorityGroupsByAgency( - Collection priorityGroupsByAgency - ) { + public void addPriorityGroupsByAgency(Collection priorityGroupsByAgency) { this.priorityGroupsByAgency.addAll(priorityGroupsByAgency); } @@ -82,11 +80,11 @@ public void addPriorityGroupsByAgency( *

* Note! Entities that are not matched are put in the BASE-GROUP with id 0. */ - public List priorityGroupsGlobal() { + public List priorityGroupsGlobal() { return priorityGroupsGlobal; } - public void addPriorityGroupsGlobal(Collection priorityGroupsGlobal) { + public void addPriorityGroupsGlobal(Collection priorityGroupsGlobal) { this.priorityGroupsGlobal.addAll(priorityGroupsGlobal); } diff --git a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitPriorityGroupSelect.java b/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java similarity index 87% rename from src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitPriorityGroupSelect.java rename to src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java index 6d763e9c3bc..dfa5daa0e31 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitPriorityGroupSelect.java +++ b/src/main/java/org/opentripplanner/routing/api/request/request/filter/TransitGroupSelect.java @@ -21,23 +21,23 @@ *

  • {@code Entity(mode:SUBWAY, agency:A3)}
  • * */ -public class TransitPriorityGroupSelect { +public class TransitGroupSelect { - private static final TransitPriorityGroupSelect DEFAULT = new TransitPriorityGroupSelect(); + private static final TransitGroupSelect DEFAULT = new TransitGroupSelect(); private final List modes; private final List subModeRegexp; private final List agencyIds; private final List routeIds; - public TransitPriorityGroupSelect() { + public TransitGroupSelect() { this.modes = List.of(); this.subModeRegexp = List.of(); this.agencyIds = List.of(); this.routeIds = List.of(); } - private TransitPriorityGroupSelect(Builder builder) { + private TransitGroupSelect(Builder builder) { // Sort and keep only unique entries, this make this // implementation consistent for eq/hc/toString. this.modes = @@ -77,7 +77,7 @@ public boolean isEmpty() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - TransitPriorityGroupSelect that = (TransitPriorityGroupSelect) o; + TransitGroupSelect that = (TransitGroupSelect) o; return ( Objects.equals(modes, that.modes) && Objects.equals(subModeRegexp, that.subModeRegexp) && @@ -96,7 +96,7 @@ public String toString() { return isEmpty() ? "TransitGroupSelect{ EMPTY }" : ToStringBuilder - .of(TransitPriorityGroupSelect.class) + .of(TransitGroupSelect.class) .addCol("modes", modes) .addCol("subModeRegexp", subModeRegexp) .addCol("agencyIds", agencyIds) @@ -106,13 +106,13 @@ public String toString() { public static class Builder { - private final TransitPriorityGroupSelect original; + private final TransitGroupSelect original; private final List modes; private final List subModeRegexp; private final List agencyIds; private final List routeIds; - public Builder(TransitPriorityGroupSelect original) { + public Builder(TransitGroupSelect original) { this.original = original; this.modes = new ArrayList<>(original.modes); this.subModeRegexp = new ArrayList<>(original.subModeRegexp); @@ -140,8 +140,8 @@ public Builder addRouteIds(Collection routeIds) { return this; } - public TransitPriorityGroupSelect build() { - var obj = new TransitPriorityGroupSelect(this); + public TransitGroupSelect build() { + var obj = new TransitGroupSelect(this); return original.equals(obj) ? original : obj; } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index f6a79ea9192..1f3807f46b6 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -167,7 +167,7 @@ cost function. The cost function (`unpreferredCost`) is defined as a linear func .asFeedScopedIds(request.journey().transit().unpreferredAgencies()) ); - TransitPriorityGroupConfig.mapTransitRequest(c, request.journey().transit()); + TransitGroupPriorityConfig.mapTransitRequest(c, request.journey().transit()); // Map preferences request.withPreferences(preferences -> mapPreferences(c, request, preferences)); @@ -297,25 +297,26 @@ The board time is added to the time when going from the stop (offboard) to onboa .asCostLinearFunction(dft.unpreferredCost()) ); - String relaxTransitPriorityGroupValue = c - .of("relaxTransitPriorityGroup") + String relaxTransitGroupPriorityValue = c + .of("relaxTransitGroupPriority") .since(V2_5) - .summary("The relax function for transit-priority-groups") + .summary("The relax function for transit-group-priority") .description( """ - A path is considered optimal if the generalized-cost is less than the - generalized-cost of another path. If this parameter is set, the comparison is relaxed - further if they belong to different transit-priority-groups. + A path is considered optimal if the generalized-cost is less than the generalized-cost of + another path. If this parameter is set, the comparison is relaxed further if they belong + to different transit groups. """ ) - .asString(dft.relaxTransitPriorityGroup().toString()); + .asString(dft.relaxTransitGroupPriority().toString()); - if (relaxTransitPriorityGroupValue != null) { + if (relaxTransitGroupPriorityValue != null) { builder.withTransitGroupPriorityGeneralizedCostSlack( - CostLinearFunction.of(relaxTransitPriorityGroupValue) + CostLinearFunction.of(relaxTransitGroupPriorityValue) ); } + // TODO REMOVE THIS builder.withRaptor(it -> c .of("relaxTransitSearchGeneralizedCostAtDestination") diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitPriorityGroupConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java similarity index 76% rename from src/main/java/org/opentripplanner/standalone/config/routerequest/TransitPriorityGroupConfig.java rename to src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java index 51faafc7cbf..e5f1ccd784a 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitPriorityGroupConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TransitGroupPriorityConfig.java @@ -6,36 +6,36 @@ import java.util.Collection; import java.util.List; import org.opentripplanner.routing.api.request.request.TransitRequest; -import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; +import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.framework.json.OtpVersion; import org.opentripplanner.transit.model.basic.TransitMode; -public class TransitPriorityGroupConfig { +public class TransitGroupPriorityConfig { public static void mapTransitRequest(NodeAdapter root, TransitRequest transit) { var c = root - .of("transitPriorityGroups") + .of("transitGroupPriority") .since(OtpVersion.V2_5) - .summary("Transit priority groups configuration") + .summary( + "Group transit patterns and give each group a mutual advantage in the Raptor search." + ) .description( """ Use this to separate transit patterns into groups. Each group will be given a group-id. A path (multiple legs) will then have a set of group-ids based on the group-id from each leg. Hence, two paths with a different set of group-ids will BOTH be optimal unless the cost is - worse than the relaxation specified in the `relaxTransitPriorityGroup` parameter. This is + worse than the relaxation specified in the `relaxTransitGroupPriority` parameter. This is only available in the TransmodelAPI for now. - Unmatched patterns are put in the BASE priority-group (group id: 0). This group is special. - If a path only have legs in the base group, then that path dominates other paths, but other - paths must be better to make it. + Unmatched patterns are put in the BASE priority-group. """ ) .experimentalFeature() .asObject(); transit.addPriorityGroupsByAgency( - TransitPriorityGroupConfig.mapList( + TransitGroupPriorityConfig.mapList( c, "byAgency", "All groups here are split by agency. For example if you list mode " + @@ -44,7 +44,7 @@ public static void mapTransitRequest(NodeAdapter root, TransitRequest transit) { ) ); transit.addPriorityGroupsGlobal( - TransitPriorityGroupConfig.mapList( + TransitGroupPriorityConfig.mapList( c, "global", "All services matching a 'global' group will get the same group-id. Use this " + @@ -53,7 +53,7 @@ public static void mapTransitRequest(NodeAdapter root, TransitRequest transit) { ); } - private static Collection mapList( + private static Collection mapList( NodeAdapter root, String parameterName, String description @@ -61,13 +61,13 @@ private static Collection mapList( return root .of(parameterName) .since(V2_5) - .summary("Configuration for transit priority groups.") + .summary("List of transit groups.") .description(description + " The max total number of group-ids are 32, so be careful.") - .asObjects(TransitPriorityGroupConfig::mapTransitGroupSelect); + .asObjects(TransitGroupPriorityConfig::mapTransitGroupSelect); } - private static TransitPriorityGroupSelect mapTransitGroupSelect(NodeAdapter c) { - return TransitPriorityGroupSelect + private static TransitGroupSelect mapTransitGroupSelect(NodeAdapter c) { + return TransitGroupSelect .of() .addModes( c diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 349c05f63dd..ab79917b9cc 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -825,12 +825,12 @@ type QueryType { passThroughPoints: [PassThroughPoint!], """ Relax generalized-cost when comparing trips with a different set of - transit-priority-groups. The groups are set server side for service-journey and + transit-group-priorities. The groups are set server side for service-journey and can not be configured in the API. This mainly helps to return competition neutral - services. Long distance authorities are put in different transit-priority-groups. + services. Long distance authorities are put in different transit-groups. This relaxes the comparison inside the routing engine for each stop-arrival. If two - paths have a different set of transit-priority-groups, then the generalized-cost + paths have a different set of transit-group-priorities, then the generalized-cost comparison is relaxed. The final set of paths are filtered through the normal itinerary-filters. @@ -839,7 +839,7 @@ type QueryType { THIS IS STILL AN EXPERIMENTAL FEATURE - IT MAY CHANGE WITHOUT ANY NOTICE! """ - relaxTransitPriorityGroup: RelaxCostInput = null, + relaxTransitGroupPriority: RelaxCostInput = null, """ Whether non-optimal transit paths at the destination should be returned. Let c be the existing minimum pareto optimal generalized-cost to beat. Then a trip with cost c' is @@ -852,7 +852,7 @@ type QueryType { Values less than 1.0 is not allowed, and values greater than 2.0 are not supported, due to performance reasons. """ - relaxTransitSearchGeneralizedCostAtDestination: Float = null @deprecated(reason : "This is replaced by 'relaxTransitPriorityGroup'."), + relaxTransitSearchGeneralizedCostAtDestination: Float = null @deprecated(reason : "This is replaced by 'relaxTransitGroupPriority'."), """ The length of the search-window in minutes. This parameter is optional. diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java index c1db11be779..43351b06eb8 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java +++ b/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java @@ -22,7 +22,7 @@ import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.request.RaptorProfile; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; -import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; @@ -33,9 +33,9 @@ */ public class K01_TransitPriorityTest { - private static final RaptorTransitPriorityGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitPriorityGroupCalculator() { + private static final RaptorTransitGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitGroupCalculator() { @Override - public int mergeTransitPriorityGroupIds(int currentGroupIds, int boardingGroupId) { + public int mergeGroupIds(int currentGroupIds, int boardingGroupId) { return currentGroupIds | boardingGroupId; } @@ -51,14 +51,8 @@ public DominanceFunction dominanceFunction() { private static final int GROUP_A = 0x01; private static final int GROUP_B = 0x02; private static final int GROUP_C = 0x04; - private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeTransitPriorityGroupIds( - GROUP_A, - GROUP_B - ); - private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeTransitPriorityGroupIds( - GROUP_A, - GROUP_C - ); + private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_B); + private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_C); private static final int C1_SLACK_90s = RaptorCostConverter.toRaptorCost(90); private final TestTransitData data = new TestTransitData(); diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java index c7b64cb5b9e..6954ac0d41a 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java +++ b/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java @@ -8,7 +8,6 @@ import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_D; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_E; import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_F; -import static org.opentripplanner.raptor._data.RaptorTestConstants.STOP_G; import static org.opentripplanner.raptor._data.RaptorTestConstants.T00_00; import static org.opentripplanner.raptor._data.RaptorTestConstants.T01_00; import static org.opentripplanner.raptor._data.api.PathUtils.pathsToString; @@ -26,7 +25,7 @@ import org.opentripplanner.raptor.api.model.DominanceFunction; import org.opentripplanner.raptor.api.request.RaptorProfile; import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; -import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; import org.opentripplanner.raptor.configure.RaptorConfig; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; @@ -37,9 +36,9 @@ */ public class K02_TransitPriorityDestinationTest { - private static final RaptorTransitPriorityGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitPriorityGroupCalculator() { + private static final RaptorTransitGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitGroupCalculator() { @Override - public int mergeTransitPriorityGroupIds(int currentGroupIds, int boardingGroupId) { + public int mergeGroupIds(int currentGroupIds, int boardingGroupId) { return currentGroupIds | boardingGroupId; } @@ -55,14 +54,8 @@ public DominanceFunction dominanceFunction() { private static final int GROUP_A = 0x01; private static final int GROUP_B = 0x02; private static final int GROUP_C = 0x04; - private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeTransitPriorityGroupIds( - GROUP_A, - GROUP_B - ); - private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeTransitPriorityGroupIds( - GROUP_A, - GROUP_C - ); + private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_B); + private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_C); private static final int C1_SLACK_90s = RaptorCostConverter.toRaptorCost(90); private final TestTransitData data = new TestTransitData(); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitPriorityGroup32nTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitGroupPriority32nTest.java similarity index 51% rename from src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitPriorityGroup32nTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitGroupPriority32nTest.java index 85083a3ee6a..2713a190dbf 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitPriorityGroup32nTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/grouppriority/TransitGroupPriority32nTest.java @@ -6,9 +6,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor.api.request.RaptorTransitPriorityGroupCalculator; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; -class TransitPriorityGroup32nTest { +class TransitGroupPriority32nTest { private static final int GROUP_INDEX_0 = 0; private static final int GROUP_INDEX_1 = 1; @@ -16,35 +16,35 @@ class TransitPriorityGroup32nTest { private static final int GROUP_INDEX_30 = 30; private static final int GROUP_INDEX_31 = 31; - private static final int GROUP_0 = TransitPriorityGroup32n.groupId(GROUP_INDEX_0); - private static final int GROUP_1 = TransitPriorityGroup32n.groupId(GROUP_INDEX_1); - private static final int GROUP_2 = TransitPriorityGroup32n.groupId(GROUP_INDEX_2); - private static final int GROUP_30 = TransitPriorityGroup32n.groupId(GROUP_INDEX_30); - private static final int GROUP_31 = TransitPriorityGroup32n.groupId(GROUP_INDEX_31); - private static final RaptorTransitPriorityGroupCalculator subjct = TransitPriorityGroup32n.priorityCalculator(); + private static final int GROUP_0 = TransitGroupPriority32n.groupId(GROUP_INDEX_0); + private static final int GROUP_1 = TransitGroupPriority32n.groupId(GROUP_INDEX_1); + private static final int GROUP_2 = TransitGroupPriority32n.groupId(GROUP_INDEX_2); + private static final int GROUP_30 = TransitGroupPriority32n.groupId(GROUP_INDEX_30); + private static final int GROUP_31 = TransitGroupPriority32n.groupId(GROUP_INDEX_31); + private static final RaptorTransitGroupCalculator subjct = TransitGroupPriority32n.priorityCalculator(); @Test void groupId() { - assertEqualsHex(0x00_00_00_00, TransitPriorityGroup32n.groupId(0)); - assertEqualsHex(0x00_00_00_01, TransitPriorityGroup32n.groupId(1)); - assertEqualsHex(0x00_00_00_02, TransitPriorityGroup32n.groupId(2)); - assertEqualsHex(0x00_00_00_04, TransitPriorityGroup32n.groupId(3)); - assertEqualsHex(0x40_00_00_00, TransitPriorityGroup32n.groupId(31)); - assertEqualsHex(0x80_00_00_00, TransitPriorityGroup32n.groupId(32)); + assertEqualsHex(0x00_00_00_00, TransitGroupPriority32n.groupId(0)); + assertEqualsHex(0x00_00_00_01, TransitGroupPriority32n.groupId(1)); + assertEqualsHex(0x00_00_00_02, TransitGroupPriority32n.groupId(2)); + assertEqualsHex(0x00_00_00_04, TransitGroupPriority32n.groupId(3)); + assertEqualsHex(0x40_00_00_00, TransitGroupPriority32n.groupId(31)); + assertEqualsHex(0x80_00_00_00, TransitGroupPriority32n.groupId(32)); - assertThrows(IllegalArgumentException.class, () -> TransitPriorityGroup32n.groupId(-1)); - assertThrows(IllegalArgumentException.class, () -> TransitPriorityGroup32n.groupId(33)); + assertThrows(IllegalArgumentException.class, () -> TransitGroupPriority32n.groupId(-1)); + assertThrows(IllegalArgumentException.class, () -> TransitGroupPriority32n.groupId(33)); } @Test - void mergeTransitPriorityGroupIds() { - assertEqualsHex(GROUP_0, subjct.mergeTransitPriorityGroupIds(GROUP_0, GROUP_0)); - assertEqualsHex(GROUP_1, subjct.mergeTransitPriorityGroupIds(GROUP_1, GROUP_1)); - assertEqualsHex(GROUP_0 | GROUP_1, subjct.mergeTransitPriorityGroupIds(GROUP_0, GROUP_1)); - assertEqualsHex(GROUP_30 | GROUP_31, subjct.mergeTransitPriorityGroupIds(GROUP_30, GROUP_31)); + void mergeTransitGroupPriorityIds() { + assertEqualsHex(GROUP_0, subjct.mergeGroupIds(GROUP_0, GROUP_0)); + assertEqualsHex(GROUP_1, subjct.mergeGroupIds(GROUP_1, GROUP_1)); + assertEqualsHex(GROUP_0 | GROUP_1, subjct.mergeGroupIds(GROUP_0, GROUP_1)); + assertEqualsHex(GROUP_30 | GROUP_31, subjct.mergeGroupIds(GROUP_30, GROUP_31)); assertEqualsHex( GROUP_0 | GROUP_1 | GROUP_2 | GROUP_30 | GROUP_31, - subjct.mergeTransitPriorityGroupIds(GROUP_0 | GROUP_1 | GROUP_2 | GROUP_30, GROUP_31) + subjct.mergeGroupIds(GROUP_0 | GROUP_1 | GROUP_2 | GROUP_30, GROUP_31) ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java index 777aee5352c..cc4bb09f01e 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java @@ -7,7 +7,7 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; +import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.RoutingTripPattern; import org.opentripplanner.transit.model.site.RegularStop; @@ -69,14 +69,14 @@ class PriorityGroupConfiguratorTest { @Test void emptyConfigurationShouldReturnGroupZero() { var subject = PriorityGroupConfigurator.of(List.of(), List.of()); - assertEquals(subject.baseGroupId(), subject.lookupTransitPriorityGroupId(railR1)); - assertEquals(subject.baseGroupId(), subject.lookupTransitPriorityGroupId(busB2)); - assertEquals(subject.baseGroupId(), subject.lookupTransitPriorityGroupId(null)); + assertEquals(subject.baseGroupId(), subject.lookupTransitGroupPriorityId(railR1)); + assertEquals(subject.baseGroupId(), subject.lookupTransitGroupPriorityId(busB2)); + assertEquals(subject.baseGroupId(), subject.lookupTransitGroupPriorityId(null)); } @Test - void lookupTransitPriorityGroupIdByAgency() { - var select = TransitPriorityGroupSelect + void lookupTransitGroupIdByAgency() { + var select = TransitGroupSelect .of() .addModes(List.of(TransitMode.BUS, TransitMode.RAIL)) .build(); @@ -85,12 +85,12 @@ void lookupTransitPriorityGroupIdByAgency() { var subject = PriorityGroupConfigurator.of(List.of(select), List.of()); // Agency groups are indexed (group-id set) at request time - assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(null)); - assertEquals(EXP_GROUP_1, subject.lookupTransitPriorityGroupId(busB2)); - assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(railR3)); - assertEquals(EXP_GROUP_3, subject.lookupTransitPriorityGroupId(railR1)); - assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(busB3)); - assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(ferryF3)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitGroupPriorityId(null)); + assertEquals(EXP_GROUP_1, subject.lookupTransitGroupPriorityId(busB2)); + assertEquals(EXP_GROUP_2, subject.lookupTransitGroupPriorityId(railR3)); + assertEquals(EXP_GROUP_3, subject.lookupTransitGroupPriorityId(railR1)); + assertEquals(EXP_GROUP_2, subject.lookupTransitGroupPriorityId(busB3)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitGroupPriorityId(ferryF3)); } @Test @@ -99,17 +99,17 @@ void lookupTransitPriorityGroupIdByGlobalMode() { var subject = PriorityGroupConfigurator.of( List.of(), List.of( - TransitPriorityGroupSelect.of().addModes(List.of(TransitMode.BUS)).build(), - TransitPriorityGroupSelect.of().addModes(List.of(TransitMode.RAIL)).build() + TransitGroupSelect.of().addModes(List.of(TransitMode.BUS)).build(), + TransitGroupSelect.of().addModes(List.of(TransitMode.RAIL)).build() ) ); - assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(null)); - assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(railR1)); - assertEquals(EXP_GROUP_1, subject.lookupTransitPriorityGroupId(busB2)); - assertEquals(EXP_GROUP_2, subject.lookupTransitPriorityGroupId(railR3)); - assertEquals(EXP_GROUP_1, subject.lookupTransitPriorityGroupId(busB3)); - assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitPriorityGroupId(ferryF3)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitGroupPriorityId(null)); + assertEquals(EXP_GROUP_2, subject.lookupTransitGroupPriorityId(railR1)); + assertEquals(EXP_GROUP_1, subject.lookupTransitGroupPriorityId(busB2)); + assertEquals(EXP_GROUP_2, subject.lookupTransitGroupPriorityId(railR3)); + assertEquals(EXP_GROUP_1, subject.lookupTransitGroupPriorityId(busB3)); + assertEquals(EXP_GROUP_ID_BASE, subject.lookupTransitGroupPriorityId(ferryF3)); } private static TestRouteData route( diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java index 880d8bc9b45..91d0142f9ef 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupMatcherTest.java @@ -6,7 +6,7 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.routing.api.request.request.filter.TransitPriorityGroupSelect; +import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; @@ -35,7 +35,7 @@ class PriorityGroupMatcherTest { @Test void testMode() { var m = PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addModes(List.of(TransitMode.BUS, TransitMode.TRAM)).build() + TransitGroupSelect.of().addModes(List.of(TransitMode.BUS, TransitMode.TRAM)).build() ); assertEquals("Mode(BUS | TRAM)", m.toString()); assertFalse(m.isEmpty()); @@ -47,10 +47,10 @@ void testMode() { @Test void testAgencyIds() { var m1 = PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addAgencyIds(List.of(r1agencyId)).build() + TransitGroupSelect.of().addAgencyIds(List.of(r1agencyId)).build() ); var m2 = PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addAgencyIds(List.of(r1agencyId, anyId)).build() + TransitGroupSelect.of().addAgencyIds(List.of(r1agencyId, anyId)).build() ); var matchers = List.of(m1, m2); @@ -68,10 +68,10 @@ void testAgencyIds() { @Test void routeIds() { var m1 = PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addRouteIds(List.of(r1routeId)).build() + TransitGroupSelect.of().addRouteIds(List.of(r1routeId)).build() ); var m2 = PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addRouteIds(List.of(r1routeId, anyId)).build() + TransitGroupSelect.of().addRouteIds(List.of(r1routeId, anyId)).build() ); var matchers = List.of(m1, m2); @@ -89,7 +89,7 @@ void routeIds() { @Test void testSubMode() { var subject = PriorityGroupMatcher.of( - TransitPriorityGroupSelect.of().addSubModeRegexp(List.of(".*local.*")).build() + TransitGroupSelect.of().addSubModeRegexp(List.of(".*local.*")).build() ); assertEquals("SubModeRegexp(.*local.*)", subject.toString()); @@ -103,7 +103,7 @@ void testSubMode() { @Test void testAnd() { var subject = PriorityGroupMatcher.of( - TransitPriorityGroupSelect + TransitGroupSelect .of() .addSubModeRegexp(List.of("express")) .addRouteIds(List.of(r1routeId)) @@ -125,7 +125,7 @@ void testAnd() { @Test void testToString() { var subject = PriorityGroupMatcher.of( - TransitPriorityGroupSelect + TransitGroupSelect .of() .addModes(List.of(TransitMode.BUS, TransitMode.TRAM)) .addAgencyIds(List.of(anyId, r1agencyId)) diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java index 811c4a70b29..eb48de51867 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java @@ -77,8 +77,8 @@ void unpreferredCost() { } @Test - void relaxTransitPriorityGroup() { - assertEquals(TRANSIT_GROUP_PRIORITY_RELAX, subject.relaxTransitPriorityGroup()); + void relaxTransitGroupPriority() { + assertEquals(TRANSIT_GROUP_PRIORITY_RELAX, subject.relaxTransitGroupPriority()); } @Test @@ -125,7 +125,7 @@ void testToString() { "reluctanceForMode: {AIRPLANE=2.1}, " + "otherThanPreferredRoutesPenalty: $350, " + "unpreferredCost: 5m + 1.15 t, " + - "relaxTransitPriorityGroup: 5m + 1.50 t, " + + "relaxTransitGroupPriority: 5m + 1.50 t, " + "ignoreRealtimeUpdates, " + "includePlannedCancellations, " + "includeRealtimeCancellations, " + From 4c537c8a2f6ee9d1872d35892a31432972e03168 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 20 Dec 2023 14:55:33 +0100 Subject: [PATCH 009/356] fix: Properly implement the `relaxTransitGroupPriority` parameter in Transmodel API --- .../common/RequestToPreferencesMapper.java | 4 +- .../preferences/TransitPreferencesMapper.java | 8 +- .../transmodel/model/plan/RelaxCostType.java | 45 +++++++--- .../apis/transmodel/model/plan/TripQuery.java | 2 +- .../graphql/scalar/CostScalarFactory.java | 83 +++++++++++++++++++ .../preference/TransitPreferences.java | 2 +- .../routerequest/RouteRequestConfig.java | 4 +- .../apis/transmodel/schema.graphql | 13 +-- .../model/plan/RelaxCostTypeTest.java | 71 ++++++++++++++++ .../preference/TransitPreferencesTest.java | 2 +- 10 files changed, 209 insertions(+), 25 deletions(-) create mode 100644 src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java create mode 100644 src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 6a8b71fe939..5c64d04a5d5 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -96,9 +96,7 @@ private BoardAndAlightSlack mapTransit() { setIfNotNull(req.ignoreRealtimeUpdates, tr::setIgnoreRealtimeUpdates); if (req.relaxTransitGroupPriority != null) { - tr.withTransitGroupPriorityGeneralizedCostSlack( - CostLinearFunction.of(req.relaxTransitGroupPriority) - ); + tr.withRelaxTransitGroupPriority(CostLinearFunction.of(req.relaxTransitGroupPriority)); } else { setIfNotNull( req.relaxTransitSearchGeneralizedCostAtDestination, diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java index d4bf92b828c..28643bf8199 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/TransitPreferencesMapper.java @@ -1,8 +1,11 @@ package org.opentripplanner.apis.transmodel.mapping.preferences; import graphql.schema.DataFetchingEnvironment; +import java.util.Map; import org.opentripplanner.apis.transmodel.model.TransportModeSlack; +import org.opentripplanner.apis.transmodel.model.plan.RelaxCostType; import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; +import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.TransitPreferences; public class TransitPreferencesMapper { @@ -35,7 +38,10 @@ public static void mapTransitPreferences( callWith.argument("includeRealtimeCancellations", transit::setIncludeRealtimeCancellations); callWith.argument( "relaxTransitGroupPriority", - transit::withTransitGroupPriorityGeneralizedCostSlack + it -> + transit.withRelaxTransitGroupPriority( + RelaxCostType.mapToDomain((Map) it, CostLinearFunction.NORMAL) + ) ); callWith.argument( "relaxTransitSearchGeneralizedCostAtDestination", diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java index 3bd3ed129ef..d3455083695 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java @@ -2,13 +2,15 @@ import graphql.Scalars; import graphql.language.FloatValue; -import graphql.language.IntValue; import graphql.language.ObjectField; import graphql.language.ObjectValue; +import graphql.language.StringValue; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; -import graphql.schema.GraphQLList; -import graphql.schema.GraphQLNonNull; +import java.util.Map; +import org.opentripplanner.framework.graphql.scalar.CostScalarFactory; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; public class RelaxCostType { @@ -26,8 +28,8 @@ public class RelaxCostType { with twice as high cost as another one, is accepted. A `constant=$300` means a "fixed" constant is added to the limit. A `{ratio=1.0, constant=0}` is said to be the NORMAL relaxed cost - the limit is the same as the cost used to calculate the limit. The NORMAL is usually - the default. We can express the RelaxCost as a function `f(x) = constant + ratio * x`. - `f(x)=x` is the NORMAL function. + the default. We can express the RelaxCost as a function `f(t) = constant + ratio * t`. + `f(t)=t` is the NORMAL function. """ ) .field( @@ -44,11 +46,12 @@ public class RelaxCostType { .newInputObjectField() .name(CONSTANT) .description( - "The constant value to add to the limit. Must be a positive number. The unit" + - " is cost-seconds." + "The constant value to add to the limit. Must be a positive number. The value is" + + "equivalent to transit-cost-seconds. Integers is treated as seconds, but you may use " + + "the duration format. Example: '3665 = 'DT1h1m5s' = '1h1m5s'." ) - .defaultValueLiteral(IntValue.of(0)) - .type(new GraphQLList(new GraphQLNonNull(Scalars.GraphQLID))) + .defaultValueProgrammatic("0s") + .type(CostScalarFactory.costScalar()) .build() ) .build(); @@ -63,9 +66,31 @@ public static ObjectValue valueOf(CostLinearFunction value) { ObjectField .newObjectField() .name(CONSTANT) - .value(IntValue.of(value.constant().toSeconds())) + // We only use this to display default value (this is an input type), so using the + // lenient OTP version of duration is ok - it is slightly more readable. + .value(StringValue.of(DurationUtils.durationToStr(value.constant().asDuration()))) .build() ) .build(); } + + public static CostLinearFunction mapToDomain( + Map input, + CostLinearFunction defaultValue + ) { + if (input == null || input.isEmpty()) { + return defaultValue; + } + + double ratio = 1.0; + Cost constant = Cost.ZERO; + + if (input.containsKey(RATIO)) { + ratio = (Double) input.get(RATIO); + } + if (input.containsKey(CONSTANT)) { + constant = (Cost) input.get(CONSTANT); + } + return CostLinearFunction.of(constant, ratio); + } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java index 52bafc1f28b..410ec0ee74a 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java @@ -291,7 +291,7 @@ public static GraphQLFieldDefinition create( itinerary-filters. - The `ratio` must be greater or equal to 1.0 and less then 1.2. - - The `slack` must be greater or equal to 0 and less then 3600. + - The `constant` must be greater or equal to '0s' and less then '1h'. THIS IS STILL AN EXPERIMENTAL FEATURE - IT MAY CHANGE WITHOUT ANY NOTICE! """.stripIndent() diff --git a/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java b/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java new file mode 100644 index 00000000000..6f710328174 --- /dev/null +++ b/src/main/java/org/opentripplanner/framework/graphql/scalar/CostScalarFactory.java @@ -0,0 +1,83 @@ +package org.opentripplanner.framework.graphql.scalar; + +import graphql.GraphQLContext; +import graphql.execution.CoercedVariables; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.GraphQLScalarType; +import java.util.Locale; +import java.util.NoSuchElementException; +import javax.annotation.Nonnull; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.time.DurationUtils; + +public class CostScalarFactory { + + private static final String TYPENAME = "Cost"; + + private static final String DOCUMENTATION = + "A cost value, normally a value of 1 is equivalent to riding transit for 1 second, " + + "but it might not depending on the use-case. Format: 3665 = DT1h1m5s = 1h1m5s"; + + private static final GraphQLScalarType SCALAR_INSTANCE = createCostScalar(); + + private CostScalarFactory() {} + + public static GraphQLScalarType costScalar() { + return SCALAR_INSTANCE; + } + + private static GraphQLScalarType createCostScalar() { + return GraphQLScalarType + .newScalar() + .name(TYPENAME) + .description(DOCUMENTATION) + .coercing(createCoercing()) + .build(); + } + + private static String serializeCost(Cost cost) { + return cost.asDuration().toString(); + } + + private static Cost parseCost(String input) throws CoercingParseValueException { + try { + return Cost.fromDuration(DurationUtils.parseSecondsOrDuration(input).orElseThrow()); + } catch (IllegalArgumentException | NoSuchElementException e) { + throw new CoercingParseValueException(e.getMessage(), e); + } + } + + private static Coercing createCoercing() { + return new Coercing<>() { + @Override + public String serialize(@Nonnull Object result, GraphQLContext c, Locale l) { + return serializeCost((Cost) result); + } + + @Override + public Cost parseValue(Object input, GraphQLContext c, Locale l) + throws CoercingParseValueException { + return parseCost((String) input); + } + + @Override + public Cost parseLiteral(Value input, CoercedVariables v, GraphQLContext c, Locale l) + throws CoercingParseLiteralException { + if (input instanceof StringValue stringValue) { + return parseCost(stringValue.getValue()); + } + return null; + } + + @Override + @Nonnull + public Value valueToLiteral(Object input, GraphQLContext c, Locale l) { + return StringValue.of((String) input); + } + }; + } +} diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java index c0a090937d9..9c54fcb6d5c 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/TransitPreferences.java @@ -302,7 +302,7 @@ public Builder setUnpreferredCostString(String constFunction) { return setUnpreferredCost(CostLinearFunction.of(constFunction)); } - public Builder withTransitGroupPriorityGeneralizedCostSlack(CostLinearFunction value) { + public Builder withRelaxTransitGroupPriority(CostLinearFunction value) { this.relaxTransitGroupPriority = value; return this; } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 1f3807f46b6..a975848e260 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -311,9 +311,7 @@ The board time is added to the time when going from the stop (offboard) to onboa .asString(dft.relaxTransitGroupPriority().toString()); if (relaxTransitGroupPriorityValue != null) { - builder.withTransitGroupPriorityGeneralizedCostSlack( - CostLinearFunction.of(relaxTransitGroupPriorityValue) - ); + builder.withRelaxTransitGroupPriority(CostLinearFunction.of(relaxTransitGroupPriorityValue)); } // TODO REMOVE THIS diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index ab79917b9cc..b5d1dc00a39 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -835,7 +835,7 @@ type QueryType { itinerary-filters. - The `ratio` must be greater or equal to 1.0 and less then 1.2. - - The `slack` must be greater or equal to 0 and less then 3600. + - The `constant` must be greater or equal to '0s' and less then '1h'. THIS IS STILL AN EXPERIMENTAL FEATURE - IT MAY CHANGE WITHOUT ANY NOTICE! """ @@ -1867,6 +1867,9 @@ enum WheelchairBoarding { "List of coordinates like: [[60.89, 11.12], [62.56, 12.10]]" scalar Coordinates +"A cost value, normally a value of 1 is equivalent to riding transit for 1 second, but it might not depending on the use-case. Format: 3665 = DT1h1m5s = 1h1m5s" +scalar Cost + "Local date using the ISO 8601 format: `YYYY-MM-DD`. Example: `2020-05-17`." scalar Date @@ -2028,12 +2031,12 @@ This is used to include more results into the result. A `ratio=2.0` means a path with twice as high cost as another one, is accepted. A `constant=$300` means a "fixed" constant is added to the limit. A `{ratio=1.0, constant=0}` is said to be the NORMAL relaxed cost - the limit is the same as the cost used to calculate the limit. The NORMAL is usually -the default. We can express the RelaxCost as a function `f(x) = constant + ratio * x`. -`f(x)=x` is the NORMAL function. +the default. We can express the RelaxCost as a function `f(t) = constant + ratio * t`. +`f(t)=t` is the NORMAL function. """ input RelaxCostInput { - "The constant value to add to the limit. Must be a positive number. The unit is cost-seconds." - constant: [ID!] = 0 + "The constant value to add to the limit. Must be a positive number. The value isequivalent to transit-cost-seconds. Integers is treated as seconds, but you may use the duration format. Example: '3665 = 'DT1h1m5s' = '1h1m5s'." + constant: Cost = "0s" "The factor to multiply with the 'other cost'. Minimum value is 1.0." ratio: Float = 1.0 } diff --git a/src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java b/src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java new file mode 100644 index 00000000000..b4da249742c --- /dev/null +++ b/src/test/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostTypeTest.java @@ -0,0 +1,71 @@ +package org.opentripplanner.apis.transmodel.model.plan; + +import static org.junit.jupiter.api.Assertions.*; +import static org.opentripplanner.apis.transmodel.model.plan.RelaxCostType.CONSTANT; +import static org.opentripplanner.apis.transmodel.model.plan.RelaxCostType.RATIO; + +import graphql.language.FloatValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.StringValue; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.routing.api.request.framework.CostLinearFunction; + +class RelaxCostTypeTest { + + @Test + void valueOf() { + assertEquals( + ObjectValue + .newObjectValue() + .objectField(ObjectField.newObjectField().name(RATIO).value(FloatValue.of(1.0)).build()) + .objectField( + ObjectField.newObjectField().name(CONSTANT).value(StringValue.of("0s")).build() + ) + .build() + .toString(), + RelaxCostType.valueOf(CostLinearFunction.NORMAL).toString() + ); + assertEquals( + ObjectValue + .newObjectValue() + .objectField(ObjectField.newObjectField().name(RATIO).value(FloatValue.of(1.3)).build()) + .objectField( + ObjectField.newObjectField().name(CONSTANT).value(StringValue.of("1m7s")).build() + ) + .build() + .toString(), + RelaxCostType.valueOf(CostLinearFunction.of(Cost.costOfSeconds(67), 1.3)).toString() + ); + } + + @Test + void mapToDomain() { + Map input; + + input = Map.of(RATIO, 1.0, CONSTANT, Cost.ZERO); + assertEquals( + CostLinearFunction.NORMAL, + RelaxCostType.mapToDomain(input, CostLinearFunction.ZERO) + ); + + input = Map.of(RATIO, 0.0, CONSTANT, Cost.ZERO); + assertEquals( + CostLinearFunction.ZERO, + RelaxCostType.mapToDomain(input, CostLinearFunction.ZERO) + ); + + input = Map.of(RATIO, 1.7, CONSTANT, Cost.costOfSeconds(3600 + 3 * 60 + 7)); + assertEquals( + CostLinearFunction.of("1h3m7s + 1.7t"), + RelaxCostType.mapToDomain(input, CostLinearFunction.ZERO) + ); + assertEquals( + CostLinearFunction.NORMAL, + RelaxCostType.mapToDomain(null, CostLinearFunction.NORMAL) + ); + assertEquals(CostLinearFunction.ZERO, RelaxCostType.mapToDomain(null, CostLinearFunction.ZERO)); + } +} diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java index eb48de51867..b77a7d9085b 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/TransitPreferencesTest.java @@ -42,7 +42,7 @@ class TransitPreferencesTest { .setUnpreferredCost(UNPREFERRED_COST) .withBoardSlack(b -> b.withDefault(D45s).with(TransitMode.AIRPLANE, D35m)) .withAlightSlack(b -> b.withDefault(D15s).with(TransitMode.AIRPLANE, D25m)) - .withTransitGroupPriorityGeneralizedCostSlack(TRANSIT_GROUP_PRIORITY_RELAX) + .withRelaxTransitGroupPriority(TRANSIT_GROUP_PRIORITY_RELAX) .setIgnoreRealtimeUpdates(IGNORE_REALTIME_UPDATES) .setIncludePlannedCancellations(INCLUDE_PLANNED_CANCELLATIONS) .setIncludeRealtimeCancellations(INCLUDE_REALTIME_CANCELLATIONS) From ce558ec12dd1a00e695875badae520c31068a1c9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 21 Dec 2023 16:28:49 +0100 Subject: [PATCH 010/356] refactor: Cleanup transit-group-priority module-tests --- .../moduletests/K01_TransitPriorityTest.java | 44 +++------------- .../K02_TransitPriorityDestinationTest.java | 44 +++------------- .../support/TestGroupPriorityCalculator.java | 51 +++++++++++++++++++ 3 files changed, 63 insertions(+), 76 deletions(-) create mode 100644 src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java index 43351b06eb8..1795663aaba 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java +++ b/src/test/java/org/opentripplanner/raptor/moduletests/K01_TransitPriorityTest.java @@ -12,6 +12,9 @@ import static org.opentripplanner.raptor._data.transit.TestRoute.route; import static org.opentripplanner.raptor._data.transit.TestTripPattern.pattern; import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule; +import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_A; +import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_B; +import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_C; import java.time.Duration; import org.junit.jupiter.api.BeforeEach; @@ -24,6 +27,7 @@ import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; import org.opentripplanner.raptor.configure.RaptorConfig; +import org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** @@ -33,26 +37,8 @@ */ public class K01_TransitPriorityTest { - private static final RaptorTransitGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitGroupCalculator() { - @Override - public int mergeGroupIds(int currentGroupIds, int boardingGroupId) { - return currentGroupIds | boardingGroupId; - } - - /** - * Left dominate right, if right has at least one priority group not in left. - */ - @Override - public DominanceFunction dominanceFunction() { - return (l, r) -> ((l ^ r) & r) != 0; - } - }; - - private static final int GROUP_A = 0x01; - private static final int GROUP_B = 0x02; - private static final int GROUP_C = 0x04; - private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_B); - private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_C); + private static final RaptorTransitGroupCalculator PRIORITY_GROUP_CALCULATOR = + TestGroupPriorityCalculator.PRIORITY_CALCULATOR; private static final int C1_SLACK_90s = RaptorCostConverter.toRaptorCost(90); private final TestTransitData data = new TestTransitData(); @@ -102,7 +88,6 @@ private void prepareRequest() { ); // Add 1 second access/egress paths requestBuilder.searchParams().addAccessPaths(walk(STOP_B, 1)).addEgressPaths(walk(STOP_C, 1)); - assetGroupCalculatorIsSetupCorrect(); } @Test @@ -116,21 +101,4 @@ public void transitPriority() { pathsToString(raptorService.route(requestBuilder.build(), data)) ); } - - /** - * Make sure the calculator and group setup is done correct. - */ - void assetGroupCalculatorIsSetupCorrect() { - var d = PRIORITY_GROUP_CALCULATOR.dominanceFunction(); - - assertTrue(d.leftDominateRight(GROUP_A, GROUP_B)); - assertTrue(d.leftDominateRight(GROUP_B, GROUP_A)); - assertFalse(d.leftDominateRight(GROUP_A, GROUP_A)); - // 3 = 1&2, 5 = 1&4 - assertTrue(d.leftDominateRight(GROUP_A, GROUP_AB)); - assertFalse(d.leftDominateRight(GROUP_AB, GROUP_A)); - assertFalse(d.leftDominateRight(GROUP_AB, GROUP_AB)); - assertTrue(d.leftDominateRight(GROUP_AB, GROUP_AC)); - assertTrue(d.leftDominateRight(GROUP_AC, GROUP_AB)); - } } diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java b/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java index 6954ac0d41a..a2185acef5e 100644 --- a/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java +++ b/src/test/java/org/opentripplanner/raptor/moduletests/K02_TransitPriorityDestinationTest.java @@ -15,6 +15,9 @@ import static org.opentripplanner.raptor._data.transit.TestRoute.route; import static org.opentripplanner.raptor._data.transit.TestTripPattern.pattern; import static org.opentripplanner.raptor._data.transit.TestTripSchedule.schedule; +import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_A; +import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_B; +import static org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator.GROUP_C; import java.time.Duration; import org.junit.jupiter.api.BeforeEach; @@ -27,6 +30,7 @@ import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; import org.opentripplanner.raptor.configure.RaptorConfig; +import org.opentripplanner.raptor.moduletests.support.TestGroupPriorityCalculator; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; /** @@ -36,26 +40,8 @@ */ public class K02_TransitPriorityDestinationTest { - private static final RaptorTransitGroupCalculator PRIORITY_GROUP_CALCULATOR = new RaptorTransitGroupCalculator() { - @Override - public int mergeGroupIds(int currentGroupIds, int boardingGroupId) { - return currentGroupIds | boardingGroupId; - } - - /** - * Left dominate right, if right has at least one priority group not in left. - */ - @Override - public DominanceFunction dominanceFunction() { - return (l, r) -> ((l ^ r) & r) != 0; - } - }; - - private static final int GROUP_A = 0x01; - private static final int GROUP_B = 0x02; - private static final int GROUP_C = 0x04; - private static final int GROUP_AB = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_B); - private static final int GROUP_AC = PRIORITY_GROUP_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_C); + private static final RaptorTransitGroupCalculator PRIORITY_GROUP_CALCULATOR = + TestGroupPriorityCalculator.PRIORITY_CALCULATOR; private static final int C1_SLACK_90s = RaptorCostConverter.toRaptorCost(90); private final TestTransitData data = new TestTransitData(); @@ -110,7 +96,6 @@ private void prepareRequest() { .addEgressPaths(walk(STOP_D, 1)) .addEgressPaths(walk(STOP_E, 1)) .addEgressPaths(walk(STOP_F, 1)); - assetGroupCalculatorIsSetupCorrect(); } @Test @@ -124,21 +109,4 @@ public void transitPriority() { pathsToString(raptorService.route(requestBuilder.build(), data)) ); } - - /** - * Make sure the calculator and group setup is done correct. - */ - void assetGroupCalculatorIsSetupCorrect() { - var d = PRIORITY_GROUP_CALCULATOR.dominanceFunction(); - - assertTrue(d.leftDominateRight(GROUP_A, GROUP_B)); - assertTrue(d.leftDominateRight(GROUP_B, GROUP_A)); - assertFalse(d.leftDominateRight(GROUP_A, GROUP_A)); - // 3 = 1&2, 5 = 1&4 - assertTrue(d.leftDominateRight(GROUP_A, GROUP_AB)); - assertFalse(d.leftDominateRight(GROUP_AB, GROUP_A)); - assertFalse(d.leftDominateRight(GROUP_AB, GROUP_AB)); - assertTrue(d.leftDominateRight(GROUP_AB, GROUP_AC)); - assertTrue(d.leftDominateRight(GROUP_AC, GROUP_AB)); - } } diff --git a/src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java b/src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java new file mode 100644 index 00000000000..cdbe82f18a6 --- /dev/null +++ b/src/test/java/org/opentripplanner/raptor/moduletests/support/TestGroupPriorityCalculator.java @@ -0,0 +1,51 @@ +package org.opentripplanner.raptor.moduletests.support; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor.api.model.DominanceFunction; +import org.opentripplanner.raptor.api.request.RaptorTransitGroupCalculator; + +public class TestGroupPriorityCalculator implements RaptorTransitGroupCalculator { + + public static final RaptorTransitGroupCalculator PRIORITY_CALCULATOR = new TestGroupPriorityCalculator(); + + public static final int GROUP_A = 0x01; + public static final int GROUP_B = 0x02; + public static final int GROUP_C = 0x04; + + private static final int GROUP_AB = PRIORITY_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_B); + private static final int GROUP_AC = PRIORITY_CALCULATOR.mergeGroupIds(GROUP_A, GROUP_C); + + @Override + public int mergeGroupIds(int currentGroupIds, int boardingGroupId) { + return currentGroupIds | boardingGroupId; + } + + /** + * Left dominate right, if right has at least one priority group not in left. + */ + @Override + public DominanceFunction dominanceFunction() { + return (l, r) -> ((l ^ r) & r) != 0; + } + + /** + * Make sure the calculator and group setup is done correct. + */ + @Test + void assetGroupCalculatorIsSetupCorrect() { + var d = PRIORITY_CALCULATOR.dominanceFunction(); + + assertTrue(d.leftDominateRight(GROUP_A, GROUP_B)); + assertTrue(d.leftDominateRight(GROUP_B, GROUP_A)); + assertFalse(d.leftDominateRight(GROUP_A, GROUP_A)); + // 3 = 1&2, 5 = 1&4 + assertTrue(d.leftDominateRight(GROUP_A, GROUP_AB)); + assertFalse(d.leftDominateRight(GROUP_AB, GROUP_A)); + assertFalse(d.leftDominateRight(GROUP_AB, GROUP_AB)); + assertTrue(d.leftDominateRight(GROUP_AB, GROUP_AC)); + assertTrue(d.leftDominateRight(GROUP_AC, GROUP_AB)); + } +} From 32ebf6c4389b3e261fbe1e207624a7ef93c42130 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 2 Jan 2024 16:42:03 +0100 Subject: [PATCH 011/356] Move serialization code into sandbox --- .../ext/restapi/serialization}/FeedScopedIdDeserializer.java | 2 +- .../ext/restapi/serialization}/FeedScopedIdKeyDeserializer.java | 2 +- .../ext/restapi/serialization}/FeedScopedIdSerializer.java | 2 +- .../ext/restapi/serialization}/JSONObjectMapperProvider.java | 2 +- .../framework/graphql/GraphQLResponseSerializer.java | 2 +- .../opentripplanner/standalone/server/OTPWebApplication.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/{main/java/org/opentripplanner/apis/common/json => ext/java/org/opentripplanner/ext/restapi/serialization}/FeedScopedIdDeserializer.java (94%) rename src/{main/java/org/opentripplanner/apis/common/json => ext/java/org/opentripplanner/ext/restapi/serialization}/FeedScopedIdKeyDeserializer.java (91%) rename src/{main/java/org/opentripplanner/apis/common/json => ext/java/org/opentripplanner/ext/restapi/serialization}/FeedScopedIdSerializer.java (96%) rename src/{main/java/org/opentripplanner/apis/common/json => ext/java/org/opentripplanner/ext/restapi/serialization}/JSONObjectMapperProvider.java (98%) diff --git a/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdDeserializer.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java similarity index 94% rename from src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdDeserializer.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java index b1946038e7e..75b1b58bfee 100644 --- a/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdDeserializer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdDeserializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.json; +package org.opentripplanner.ext.restapi.serialization; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdKeyDeserializer.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java similarity index 91% rename from src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdKeyDeserializer.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java index 316894763ad..75270e9dd0b 100644 --- a/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdKeyDeserializer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdKeyDeserializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.json; +package org.opentripplanner.ext.restapi.serialization; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.KeyDeserializer; diff --git a/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdSerializer.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdSerializer.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java index 471d80aa915..c9c67e675c4 100644 --- a/src/main/java/org/opentripplanner/apis/common/json/FeedScopedIdSerializer.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/FeedScopedIdSerializer.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.json; +package org.opentripplanner.ext.restapi.serialization; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/org/opentripplanner/apis/common/json/JSONObjectMapperProvider.java b/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java similarity index 98% rename from src/main/java/org/opentripplanner/apis/common/json/JSONObjectMapperProvider.java rename to src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java index 6121a0ba698..e271e945ca1 100644 --- a/src/main/java/org/opentripplanner/apis/common/json/JSONObjectMapperProvider.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/serialization/JSONObjectMapperProvider.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.json; +package org.opentripplanner.ext.restapi.serialization; import com.bedatadriven.jackson.datatype.jts.JtsModule; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java index 25242456722..cb3b146a113 100644 --- a/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java +++ b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java @@ -10,7 +10,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import org.opentripplanner.apis.common.json.JSONObjectMapperProvider; +import org.opentripplanner.ext.restapi.serialization.JSONObjectMapperProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java b/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java index 5612d98ea0c..b238a74c7d3 100644 --- a/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java +++ b/src/main/java/org/opentripplanner/standalone/server/OTPWebApplication.java @@ -18,7 +18,7 @@ import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider; import org.opentripplanner.api.common.OTPExceptionMapper; import org.opentripplanner.apis.APIEndpoints; -import org.opentripplanner.apis.common.json.JSONObjectMapperProvider; +import org.opentripplanner.ext.restapi.serialization.JSONObjectMapperProvider; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.bridge.SLF4JBridgeHandler; From 2218c1af12110e1d84730f25a76870cf94e856ec Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 19 Dec 2023 18:52:42 +0100 Subject: [PATCH 012/356] Add new debug vector tiles --- .../api/configuration/APIEndpoints.java | 2 +- .../GraphInspectorVectorTileResource.java | 58 +++++++++++++++--- .../apis/vectortiles/MapboxStyleJson.java | 53 ++++++++++++++++ .../vector/RegularStopsLayerBuilder.java | 60 +++++++++++++++++++ 4 files changed, 164 insertions(+), 9 deletions(-) rename src/main/java/org/opentripplanner/{api/resource => apis/vectortiles}/GraphInspectorVectorTileResource.java (72%) create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java create mode 100644 src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java diff --git a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java b/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java index b0d38aa00cd..64bbb2896a2 100644 --- a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java @@ -19,13 +19,13 @@ import java.util.List; import org.opentripplanner.api.resource.BikeRental; import org.opentripplanner.api.resource.GraphInspectorTileResource; -import org.opentripplanner.api.resource.GraphInspectorVectorTileResource; import org.opentripplanner.api.resource.PlannerResource; import org.opentripplanner.api.resource.Routers; import org.opentripplanner.api.resource.ServerInfo; import org.opentripplanner.api.resource.UpdaterStatusResource; import org.opentripplanner.apis.gtfs.GtfsGraphQLAPI; import org.opentripplanner.apis.transmodel.TransmodelAPI; +import org.opentripplanner.apis.vectortiles.GraphInspectorVectorTileResource; import org.opentripplanner.ext.actuator.ActuatorAPI; import org.opentripplanner.ext.geocoder.GeocoderResource; import org.opentripplanner.ext.parkAndRideApi.ParkAndRideResource; diff --git a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java similarity index 72% rename from src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java rename to src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 2c21e0396ce..04d2630a301 100644 --- a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.resource; +package org.opentripplanner.apis.vectortiles; import static org.opentripplanner.framework.io.HttpUtils.APPLICATION_X_PROTOBUF; @@ -14,13 +14,20 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.function.Predicate; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.model.TileJson; +import org.opentripplanner.apis.vectortiles.MapboxStyleJson.LayerStyleBuilder; +import org.opentripplanner.apis.vectortiles.MapboxStyleJson.VectorTileSource; +import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.inspector.vector.AreaStopsLayerBuilder; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; +import org.opentripplanner.inspector.vector.RegularStopsLayerBuilder; import org.opentripplanner.inspector.vector.VectorTileResponseFactory; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; import org.opentripplanner.model.FeedInfo; @@ -34,6 +41,7 @@ public class GraphInspectorVectorTileResource { private static final List> DEBUG_LAYERS = List.of( + new LayerParams("regularStops", LayerType.RegularStop), new LayerParams("areaStops", LayerType.AreaStop), new LayerParams("geofencingZones", LayerType.GeofencingZones) ); @@ -84,13 +92,7 @@ public TileJson getTileJson( @PathParam("layers") String requestedLayers ) { var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); - List feedInfos = serverContext - .transitService() - .getFeedIds() - .stream() - .map(serverContext.transitService()::getFeedInfo) - .filter(Predicate.not(Objects::isNull)) - .toList(); + List feedInfos = feedInfos(); return new TileJson( uri, @@ -103,18 +105,58 @@ public TileJson getTileJson( ); } + @GET + @Path("/style.json") + @Produces(MediaType.APPLICATION_JSON) + public MapboxStyleJson getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) { + var base = HttpUtils.getBaseAddress(uri, headers); + final String allLayers = DEBUG_LAYERS + .stream() + .map(LayerParameters::name) + .collect(Collectors.joining(",")); + var url = + base + + "/otp/routers/" + + ignoreRouterId + + "/inspector/vectortile/" + + allLayers + + "/tilejson.json"; + return new MapboxStyleJson( + "OTP Debug Tiles", + Map.of("debug", new VectorTileSource("vector", url)), + List.of(LayerStyleBuilder.ofId("regular-stop").source("regularStops").circleColor("#f73109").build()) + ); + } + + @Nonnull + private List feedInfos() { + return serverContext + .transitService() + .getFeedIds() + .stream() + .map(serverContext.transitService()::getFeedInfo) + .filter(Predicate.not(Objects::isNull)) + .toList(); + } + private static LayerBuilder createLayerBuilder( LayerParameters layerParameters, Locale locale, OtpServerRequestContext context ) { return switch (layerParameters.type()) { + case RegularStop -> new RegularStopsLayerBuilder( + context.transitService(), + layerParameters, + locale + ); case AreaStop -> new AreaStopsLayerBuilder(context.transitService(), layerParameters, locale); case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); }; } private enum LayerType { + RegularStop, AreaStop, GeofencingZones, } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java new file mode 100644 index 00000000000..72f92a9c02e --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java @@ -0,0 +1,53 @@ +package org.opentripplanner.apis.vectortiles; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.opentripplanner.framework.json.ObjectMappers; + +public record MapboxStyleJson( + String name, + Map sources, + List layers +) { + public record VectorTileSource(String type, String url) {} + + public static class LayerStyleBuilder { + + private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); + private final Map props = new HashMap<>(); + private final Map paint = new HashMap<>(); + + public static LayerStyleBuilder ofId(String id) { + return new LayerStyleBuilder(id); + } + + private LayerStyleBuilder(String id) { + props.put("id", id); + } + + /** + * Which vector tile source this should apply to. + */ + public LayerStyleBuilder source(String source) { + props.put("source", source); + return this; + } + + public LayerStyleBuilder circleColor(String color) { + paint.put("circle-color", color); + return this; + } + + public JsonNode build() { + var copy = new HashMap<>(props); + if(!paint.isEmpty()) { + copy.put("paint", paint); + } + return OBJECT_MAPPER.valueToTree(copy); + } + + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java new file mode 100644 index 00000000000..c4bf0d88a23 --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java @@ -0,0 +1,60 @@ +package org.opentripplanner.inspector.vector; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.Function; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.transit.model.site.AreaStop; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.service.TransitService; + +/** + * A vector tile layer containing all {@link RegularStop}s inside the vector tile bounds. + */ +public class RegularStopsLayerBuilder extends LayerBuilder { + + private static final Map mappers = Map.of( + MapperType.DebugClient, + DebugClientAreaStopPropertyMapper::create + ); + private final Function> findAreaStops; + + public RegularStopsLayerBuilder( + TransitService transitService, + LayerParameters layerParameters, + Locale locale + ) { + super( + mappers.get(MapperType.valueOf(layerParameters.mapper())).build(transitService, locale), + layerParameters.name(), + layerParameters.expansionFactor() + ); + this.findAreaStops = transitService::findRegularStop; + } + + @Override + protected List getGeometries(Envelope query) { + return findAreaStops + .apply(query) + .stream() + .map(stop -> { + Geometry geometry = stop.getGeometry().copy(); + geometry.setUserData(stop); + return geometry; + }) + .toList(); + } + + enum MapperType { + DebugClient, + } + + @FunctionalInterface + private interface MapperFactory { + PropertyMapper build(TransitService transitService, Locale locale); + } +} From 176187c5dba4a735fbd78171d98c5dda0c29c1cb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 19 Dec 2023 18:48:30 +0100 Subject: [PATCH 013/356] Add stop layer to tile.json --- .../GraphInspectorVectorTileResource.java | 40 ++++++- .../apis/vectortiles/MapboxStyleJson.java | 53 --------- .../vectortiles/model/LayerStyleBuilder.java | 105 ++++++++++++++++++ .../vectortiles/model/MapboxStyleJson.java | 46 ++++++++ .../apis/vectortiles/model/TileSource.java | 25 +++++ .../vector/AreaStopsLayerBuilder.java | 10 +- .../DebugClientAreaStopPropertyMapper.java | 14 +-- .../vector/RegularStopsLayerBuilder.java | 20 +--- .../vector/AreaStopLayerBuilderTest.java | 5 +- 9 files changed, 225 insertions(+), 93 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 04d2630a301..8df1fd9e388 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -14,15 +14,17 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.model.TileJson; -import org.opentripplanner.apis.vectortiles.MapboxStyleJson.LayerStyleBuilder; -import org.opentripplanner.apis.vectortiles.MapboxStyleJson.VectorTileSource; +import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder; +import org.opentripplanner.apis.vectortiles.model.MapboxStyleJson; +import org.opentripplanner.apis.vectortiles.model.TileSource; +import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; +import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.inspector.vector.AreaStopsLayerBuilder; import org.opentripplanner.inspector.vector.LayerBuilder; @@ -121,10 +123,38 @@ public MapboxStyleJson getTileJson(@Context UriInfo uri, @Context HttpHeaders he "/inspector/vectortile/" + allLayers + "/tilejson.json"; + var vectorSource = new VectorSource("debug", url); + var backgroundSource = new RasterSource( + "background", + List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), + 256 + ); + List sources = List.of( + backgroundSource, + vectorSource + ); return new MapboxStyleJson( "OTP Debug Tiles", - Map.of("debug", new VectorTileSource("vector", url)), - List.of(LayerStyleBuilder.ofId("regular-stop").source("regularStops").circleColor("#f73109").build()) + sources, + List.of( + LayerStyleBuilder + .ofId("background") + .typeRaster() + .source(backgroundSource) + .minZoom(0) + .maxZoom(22) + .build(), + LayerStyleBuilder + .ofId("regular-stop") + .source(vectorSource) + .sourceLayer("regularStops") + .typeCircle() + .circleStroke("#140d0e", 1) + .circleColor("#fcf9fa") + .minZoom(13) + .maxZoom(22) + .build() + ) ); } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java deleted file mode 100644 index 72f92a9c02e..00000000000 --- a/src/main/java/org/opentripplanner/apis/vectortiles/MapboxStyleJson.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.opentripplanner.apis.vectortiles; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.opentripplanner.framework.json.ObjectMappers; - -public record MapboxStyleJson( - String name, - Map sources, - List layers -) { - public record VectorTileSource(String type, String url) {} - - public static class LayerStyleBuilder { - - private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); - private final Map props = new HashMap<>(); - private final Map paint = new HashMap<>(); - - public static LayerStyleBuilder ofId(String id) { - return new LayerStyleBuilder(id); - } - - private LayerStyleBuilder(String id) { - props.put("id", id); - } - - /** - * Which vector tile source this should apply to. - */ - public LayerStyleBuilder source(String source) { - props.put("source", source); - return this; - } - - public LayerStyleBuilder circleColor(String color) { - paint.put("circle-color", color); - return this; - } - - public JsonNode build() { - var copy = new HashMap<>(props); - if(!paint.isEmpty()) { - copy.put("paint", paint); - } - return OBJECT_MAPPER.valueToTree(copy); - } - - } -} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java new file mode 100644 index 00000000000..65a009ec53e --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -0,0 +1,105 @@ +package org.opentripplanner.apis.vectortiles.model; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; +import org.opentripplanner.framework.json.ObjectMappers; + +/** + * Builds a Maplibre/Mapbox vector tile + * layer style. + */ +public class LayerStyleBuilder { + + private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); + private static final String TYPE = "type"; + private static final String SOURCE_LAYER = "source-layer"; + private final Map props = new HashMap<>(); + private final Map paint = new HashMap<>(); + + public static LayerStyleBuilder ofId(String id) { + return new LayerStyleBuilder(id); + } + + public enum LayerType { + Circle, + Raster, + } + + private LayerStyleBuilder(String id) { + props.put("id", id); + } + + public LayerStyleBuilder minZoom(int i) { + props.put("minzoom", i); + return this; + } + + public LayerStyleBuilder maxZoom(int i) { + props.put("maxzoom", i); + return this; + } + + /** + * Which vector tile source this should apply to. + */ + public LayerStyleBuilder source(TileSource source) { + props.put("source", source.id()); + return this; + } + + public LayerStyleBuilder sourceLayer(String source) { + props.put(SOURCE_LAYER, source); + return this; + } + + public LayerStyleBuilder typeRaster() { + return type(LayerType.Raster); + } + + public LayerStyleBuilder typeCircle() { + return type(LayerType.Circle); + } + + private LayerStyleBuilder type(LayerType type) { + props.put(TYPE, type.name().toLowerCase()); + return this; + } + + public LayerStyleBuilder circleColor(String color) { + paint.put("circle-color", validateColor(color)); + return this; + } + + public LayerStyleBuilder circleStroke(String color, int width) { + paint.put("circle-stroke-color", validateColor(color)); + paint.put("circle-stroke-width", width); + return this; + } + + public JsonNode build() { + validate(); + + var copy = new HashMap<>(props); + if (!paint.isEmpty()) { + copy.put("paint", paint); + } + return OBJECT_MAPPER.valueToTree(copy); + } + + private String validateColor(String color) { + if (!color.startsWith("#")) { + throw new IllegalArgumentException("Colors must start with '#'"); + } + return color; + } + + private void validate() { + Stream + .of(TYPE) + .forEach(p -> Objects.requireNonNull(props.get(p), "%s must be set".formatted(p))); + } +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java new file mode 100644 index 00000000000..bf84b697b92 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java @@ -0,0 +1,46 @@ +package org.opentripplanner.apis.vectortiles.model; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public final class MapboxStyleJson { + + private final String name; + private final List sources; + private final List layers; + + public MapboxStyleJson( + String name, + List sources, + List layers + ) { + this.name = name; + this.sources = sources; + this.layers = layers; + } + + @JsonSerialize + public int version() { + return 8; + } + + @JsonSerialize + public String name() { + return name; + } + + @JsonSerialize + public Map sources() { + var output = new HashMap(); + sources.forEach(s -> output.put(s.id(), s)); + return output; + } + + @JsonSerialize + public List layers() { + return layers; + } +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java new file mode 100644 index 00000000000..2e404d9a1eb --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -0,0 +1,25 @@ +package org.opentripplanner.apis.vectortiles.model; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import java.util.List; + +public sealed interface TileSource { + @JsonSerialize + String type(); + + String id(); + + record VectorSource(String id, String url) implements TileSource { + @Override + public String type() { + return "vector"; + } + } + + record RasterSource(String id, List tiles, int tileSize) implements TileSource { + @Override + public String type() { + return "raster"; + } + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java index 1604cf7d8d1..6ce7b0962ba 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java @@ -3,23 +3,19 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.api.mapping.PropertyMapper; import org.opentripplanner.transit.model.site.AreaStop; +import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; /** * A vector tile layer containing all {@link AreaStop}s inside the vector tile bounds. */ -public class AreaStopsLayerBuilder extends LayerBuilder { +public class AreaStopsLayerBuilder extends LayerBuilder { - private static final Map mappers = Map.of( - MapperType.DebugClient, - DebugClientAreaStopPropertyMapper::create - ); private final Function> findAreaStops; public AreaStopsLayerBuilder( @@ -28,7 +24,7 @@ public AreaStopsLayerBuilder( Locale locale ) { super( - mappers.get(MapperType.valueOf(layerParameters.mapper())).build(transitService, locale), + new DebugClientAreaStopPropertyMapper(locale), layerParameters.name(), layerParameters.expansionFactor() ); diff --git a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java index 88f7a17385b..1d507140378 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java @@ -5,29 +5,29 @@ import java.util.Locale; import org.opentripplanner.api.mapping.I18NStringMapper; import org.opentripplanner.api.mapping.PropertyMapper; -import org.opentripplanner.transit.model.site.AreaStop; +import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; /** * A {@link PropertyMapper} for the {@link AreaStopsLayerBuilder} for the OTP debug client. */ -public class DebugClientAreaStopPropertyMapper extends PropertyMapper { +public class DebugClientAreaStopPropertyMapper extends PropertyMapper { private final I18NStringMapper i18NStringMapper; - public DebugClientAreaStopPropertyMapper(TransitService transitService, Locale locale) { + public DebugClientAreaStopPropertyMapper(Locale locale) { this.i18NStringMapper = new I18NStringMapper(locale); } - public static PropertyMapper create(TransitService transitService, Locale locale) { - return new DebugClientAreaStopPropertyMapper(transitService, locale); + public static PropertyMapper create(TransitService ignored, Locale locale) { + return new DebugClientAreaStopPropertyMapper(locale); } @Override - protected Collection map(AreaStop input) { + protected Collection map(StopLocation input) { return List.of( new KeyValue("id", input.getId().toString()), - new KeyValue("name", i18NStringMapper.mapNonnullToApi(input.getName())) + new KeyValue("name", i18NStringMapper.mapToApi(input.getName())) ); } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java index c4bf0d88a23..26e3f8726ae 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java @@ -3,24 +3,18 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.common.mapping.PropertyMapper; -import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; /** * A vector tile layer containing all {@link RegularStop}s inside the vector tile bounds. */ -public class RegularStopsLayerBuilder extends LayerBuilder { +public class RegularStopsLayerBuilder extends LayerBuilder { - private static final Map mappers = Map.of( - MapperType.DebugClient, - DebugClientAreaStopPropertyMapper::create - ); private final Function> findAreaStops; public RegularStopsLayerBuilder( @@ -29,7 +23,7 @@ public RegularStopsLayerBuilder( Locale locale ) { super( - mappers.get(MapperType.valueOf(layerParameters.mapper())).build(transitService, locale), + new DebugClientAreaStopPropertyMapper(locale), layerParameters.name(), layerParameters.expansionFactor() ); @@ -49,12 +43,4 @@ protected List getGeometries(Envelope query) { .toList(); } - enum MapperType { - DebugClient, - } - - @FunctionalInterface - private interface MapperFactory { - PropertyMapper build(TransitService transitService, Locale locale); - } } diff --git a/src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java b/src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java index 09b64adcf75..6f2ca872f21 100644 --- a/src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java +++ b/src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java @@ -38,10 +38,7 @@ class AreaStopLayerBuilderTest { @Test void map() { - var subject = new DebugClientAreaStopPropertyMapper( - new DefaultTransitService(new TransitModel()), - Locale.ENGLISH - ); + var subject = new DebugClientAreaStopPropertyMapper(Locale.ENGLISH); var properties = subject.map(areaStop); From 7aaf79ff43d1421786ac5c0e4c8297d783b7b06b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 19 Dec 2023 23:41:36 +0100 Subject: [PATCH 014/356] Move classes into their own packages --- .../GraphInspectorVectorTileResource.java | 9 ++--- .../vectortiles/model/LayerStyleBuilder.java | 5 +++ .../vectortiles/model/MapboxStyleJson.java | 6 +-- .../opentripplanner/astar/model/BinHeap.java | 12 ------ .../vector/edge/EdgeLayerBuilder.java | 40 +++++++++++++++++++ .../vector/edge/EdgePropertyMapper.java | 18 +++++++++ .../GeofencingZonesLayerBuilder.java | 17 +------- .../{ => stop}/AreaStopsLayerBuilder.java | 18 ++------- .../{ => stop}/RegularStopsLayerBuilder.java | 7 ++-- .../StopLocationPropertyMapper.java} | 9 +++-- .../{ => stop}/AreaStopLayerBuilderTest.java | 7 ++-- 11 files changed, 84 insertions(+), 64 deletions(-) create mode 100644 src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java create mode 100644 src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java rename src/main/java/org/opentripplanner/inspector/vector/{ => stop}/AreaStopsLayerBuilder.java (77%) rename src/main/java/org/opentripplanner/inspector/vector/{ => stop}/RegularStopsLayerBuilder.java (84%) rename src/main/java/org/opentripplanner/inspector/vector/{DebugClientAreaStopPropertyMapper.java => stop/StopLocationPropertyMapper.java} (74%) rename src/test/java/org/opentripplanner/inspector/vector/{ => stop}/AreaStopLayerBuilderTest.java (86%) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 8df1fd9e388..9d083bd5e03 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -26,12 +26,12 @@ import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.framework.io.HttpUtils; -import org.opentripplanner.inspector.vector.AreaStopsLayerBuilder; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; -import org.opentripplanner.inspector.vector.RegularStopsLayerBuilder; import org.opentripplanner.inspector.vector.VectorTileResponseFactory; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; +import org.opentripplanner.inspector.vector.stop.AreaStopsLayerBuilder; +import org.opentripplanner.inspector.vector.stop.RegularStopsLayerBuilder; import org.opentripplanner.model.FeedInfo; import org.opentripplanner.standalone.api.OtpServerRequestContext; @@ -129,10 +129,7 @@ public MapboxStyleJson getTileJson(@Context UriInfo uri, @Context HttpHeaders he List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), 256 ); - List sources = List.of( - backgroundSource, - vectorSource - ); + List sources = List.of(backgroundSource, vectorSource); return new MapboxStyleJson( "OTP Debug Tiles", sources, diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index 65a009ec53e..759ce7eeb30 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -51,6 +51,11 @@ public LayerStyleBuilder source(TileSource source) { return this; } + /** + * For vector tile sources, specify which source layer in the tile the styles should apply to. + * There is an unfortunate collision in the name "layer" as it can both refer to a styling layer + * and the layer inside the vector tile. + */ public LayerStyleBuilder sourceLayer(String source) { props.put(SOURCE_LAYER, source); return this; diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java index bf84b697b92..6461d697bfc 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java @@ -12,11 +12,7 @@ public final class MapboxStyleJson { private final List sources; private final List layers; - public MapboxStyleJson( - String name, - List sources, - List layers - ) { + public MapboxStyleJson(String name, List sources, List layers) { this.name = name; this.sources = sources; this.layers = layers; diff --git a/src/main/java/org/opentripplanner/astar/model/BinHeap.java b/src/main/java/org/opentripplanner/astar/model/BinHeap.java index 9bc2b0762a8..1e9b540a77a 100644 --- a/src/main/java/org/opentripplanner/astar/model/BinHeap.java +++ b/src/main/java/org/opentripplanner/astar/model/BinHeap.java @@ -79,14 +79,6 @@ public void rekey(T e, double p) { prio[i] = p; } - public void dump() { - for (int i = 0; i <= capacity; i++) { - String topMarker = (i > size) ? "(UNUSED)" : ""; - System.out.printf("%d\t%f\t%s\t%s\n", i, prio[i], elem[i], topMarker); - } - System.out.printf("-----------------------\n"); - } - public void reset() { // empties the queue in one operation size = 0; @@ -135,8 +127,4 @@ public void resize(int capacity) { prio = Arrays.copyOf(prio, capacity + 1); elem = Arrays.copyOf(elem, capacity + 1); } - - public int getCapacity() { - return capacity; - } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java new file mode 100644 index 00000000000..3c1bc3436d8 --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java @@ -0,0 +1,40 @@ +package org.opentripplanner.inspector.vector.edge; + +import java.util.List; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.framework.geometry.GeometryUtils; +import org.opentripplanner.inspector.vector.LayerBuilder; +import org.opentripplanner.inspector.vector.LayerParameters; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.routing.graph.index.StreetIndex; +import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.transit.model.site.AreaStop; + +/** + * A vector tile layer containing all {@link AreaStop}s inside the vector tile bounds. + */ +public class EdgeLayerBuilder extends LayerBuilder { + + private final StreetIndex streetIndex; + + public EdgeLayerBuilder(Graph graph, LayerParameters layerParameters) { + super(new EdgePropertyMapper(), layerParameters.name(), layerParameters.expansionFactor()); + this.streetIndex = graph.getStreetIndex(); + } + + @Override + protected List getGeometries(Envelope query) { + return streetIndex + .getEdgesForEnvelope(query) + .stream() + .filter(edge -> edge.getGeometry() != null) + .map(edge -> { + Geometry geometry = edge.getGeometry().copy(); + geometry.setUserData(edge); + return geometry; + }) + .toList(); + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java new file mode 100644 index 00000000000..936c965c9f5 --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java @@ -0,0 +1,18 @@ +package org.opentripplanner.inspector.vector.edge; + +import java.util.Collection; +import java.util.List; +import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.inspector.vector.KeyValue; +import org.opentripplanner.street.model.edge.Edge; + +/** + * A {@link PropertyMapper} for the {@link EdgeLayerBuilder} for the OTP debug client. + */ +public class EdgePropertyMapper extends PropertyMapper { + + @Override + protected Collection map(Edge edge) { + return List.of(new KeyValue("java-class", edge.getClass().getSimpleName())); + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java index 8a77b8502ea..24be8d202a8 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java @@ -1,10 +1,8 @@ package org.opentripplanner.inspector.vector.geofencing; import java.util.List; -import java.util.Map; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; @@ -19,15 +17,11 @@ */ public class GeofencingZonesLayerBuilder extends LayerBuilder { - private static final Map mappers = Map.of( - MapperType.DebugClient, - transitService -> new GeofencingZonesPropertyMapper() - ); private final StreetIndex streetIndex; public GeofencingZonesLayerBuilder(Graph graph, LayerParameters layerParameters) { super( - mappers.get(MapperType.valueOf(layerParameters.mapper())).build(graph), + new GeofencingZonesPropertyMapper(), layerParameters.name(), layerParameters.expansionFactor() ); @@ -47,13 +41,4 @@ protected List getGeometries(Envelope query) { }) .toList(); } - - enum MapperType { - DebugClient, - } - - @FunctionalInterface - private interface MapperFactory { - PropertyMapper build(Graph transitService); - } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java similarity index 77% rename from src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java rename to src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java index 6ce7b0962ba..d1a2552e4e2 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.inspector.vector; +package org.opentripplanner.inspector.vector.stop; import java.util.Collection; import java.util.List; @@ -6,7 +6,8 @@ import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.inspector.vector.LayerBuilder; +import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; @@ -24,7 +25,7 @@ public AreaStopsLayerBuilder( Locale locale ) { super( - new DebugClientAreaStopPropertyMapper(locale), + new StopLocationPropertyMapper(locale), layerParameters.name(), layerParameters.expansionFactor() ); @@ -38,20 +39,9 @@ protected List getGeometries(Envelope query) { .stream() .map(areaStop -> { Geometry geometry = areaStop.getGeometry().copy(); - geometry.setUserData(areaStop); - return geometry; }) .toList(); } - - enum MapperType { - DebugClient, - } - - @FunctionalInterface - private interface MapperFactory { - PropertyMapper build(TransitService transitService, Locale locale); - } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/stop/RegularStopsLayerBuilder.java similarity index 84% rename from src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java rename to src/main/java/org/opentripplanner/inspector/vector/stop/RegularStopsLayerBuilder.java index 26e3f8726ae..f943e23eb88 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/RegularStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/RegularStopsLayerBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.inspector.vector; +package org.opentripplanner.inspector.vector.stop; import java.util.Collection; import java.util.List; @@ -6,6 +6,8 @@ import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.inspector.vector.LayerBuilder; +import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; @@ -23,7 +25,7 @@ public RegularStopsLayerBuilder( Locale locale ) { super( - new DebugClientAreaStopPropertyMapper(locale), + new StopLocationPropertyMapper(locale), layerParameters.name(), layerParameters.expansionFactor() ); @@ -42,5 +44,4 @@ protected List getGeometries(Envelope query) { }) .toList(); } - } diff --git a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java similarity index 74% rename from src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java rename to src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java index 1d507140378..d2e1accf483 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java @@ -1,26 +1,27 @@ -package org.opentripplanner.inspector.vector; +package org.opentripplanner.inspector.vector.stop; import java.util.Collection; import java.util.List; import java.util.Locale; import org.opentripplanner.api.mapping.I18NStringMapper; import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitService; /** * A {@link PropertyMapper} for the {@link AreaStopsLayerBuilder} for the OTP debug client. */ -public class DebugClientAreaStopPropertyMapper extends PropertyMapper { +public class StopLocationPropertyMapper extends PropertyMapper { private final I18NStringMapper i18NStringMapper; - public DebugClientAreaStopPropertyMapper(Locale locale) { + public StopLocationPropertyMapper(Locale locale) { this.i18NStringMapper = new I18NStringMapper(locale); } public static PropertyMapper create(TransitService ignored, Locale locale) { - return new DebugClientAreaStopPropertyMapper(locale); + return new StopLocationPropertyMapper(locale); } @Override diff --git a/src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java b/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java similarity index 86% rename from src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java rename to src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java index 6f2ca872f21..3fea49ab236 100644 --- a/src/test/java/org/opentripplanner/inspector/vector/AreaStopLayerBuilderTest.java +++ b/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.inspector.vector; +package org.opentripplanner.inspector.vector.stop; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -9,12 +9,11 @@ import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; +import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.StopModel; import org.opentripplanner.transit.service.StopModelBuilder; -import org.opentripplanner.transit.service.TransitModel; class AreaStopLayerBuilderTest { @@ -38,7 +37,7 @@ class AreaStopLayerBuilderTest { @Test void map() { - var subject = new DebugClientAreaStopPropertyMapper(Locale.ENGLISH); + var subject = new StopLocationPropertyMapper(Locale.ENGLISH); var properties = subject.map(areaStop); From 033000a2afa7921730bf41a64fb5517b7eaf6a2f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 20 Dec 2023 11:20:08 +0100 Subject: [PATCH 015/356] Move styles into separate class --- .../apis/vectortiles/DebugStyleJson.java | 43 +++++++++++++++++++ .../GraphInspectorVectorTileResource.java | 35 +-------------- .../vectortiles/model/LayerStyleBuilder.java | 2 +- .../vectortiles/model/MapboxStyleJson.java | 4 +- 4 files changed, 47 insertions(+), 37 deletions(-) create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java new file mode 100644 index 00000000000..75592cbc0cd --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java @@ -0,0 +1,43 @@ +package org.opentripplanner.apis.vectortiles; + +import java.util.List; +import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder; +import org.opentripplanner.apis.vectortiles.model.MapboxStyleJson; +import org.opentripplanner.apis.vectortiles.model.TileSource; +import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; +import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; + +public class DebugStyleJson { + + private static final RasterSource BACKGROUND_SOURCE = new RasterSource( + "background", + List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), + 256 + ); + + static MapboxStyleJson build(String url) { + var vectorSource = new VectorSource("debug", url); + List sources = List.of(BACKGROUND_SOURCE, vectorSource); + return new MapboxStyleJson( + "OTP Debug Tiles", + sources, + List.of( + LayerStyleBuilder + .ofId("background") + .typeRaster() + .source(BACKGROUND_SOURCE) + .minZoom(0) + .maxZoom(22), + LayerStyleBuilder + .ofId("regular-stop") + .typeCircle() + .source(vectorSource) + .sourceLayer("regularStops") + .circleStroke("#140d0e", 1) + .circleColor("#fcf9fa") + .minZoom(13) + .maxZoom(22) + ) + ); + } +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 9d083bd5e03..6d23e533aad 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -20,11 +20,7 @@ import javax.annotation.Nonnull; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.model.TileJson; -import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder; import org.opentripplanner.apis.vectortiles.model.MapboxStyleJson; -import org.opentripplanner.apis.vectortiles.model.TileSource; -import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; -import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; @@ -123,36 +119,7 @@ public MapboxStyleJson getTileJson(@Context UriInfo uri, @Context HttpHeaders he "/inspector/vectortile/" + allLayers + "/tilejson.json"; - var vectorSource = new VectorSource("debug", url); - var backgroundSource = new RasterSource( - "background", - List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), - 256 - ); - List sources = List.of(backgroundSource, vectorSource); - return new MapboxStyleJson( - "OTP Debug Tiles", - sources, - List.of( - LayerStyleBuilder - .ofId("background") - .typeRaster() - .source(backgroundSource) - .minZoom(0) - .maxZoom(22) - .build(), - LayerStyleBuilder - .ofId("regular-stop") - .source(vectorSource) - .sourceLayer("regularStops") - .typeCircle() - .circleStroke("#140d0e", 1) - .circleColor("#fcf9fa") - .minZoom(13) - .maxZoom(22) - .build() - ) - ); + return DebugStyleJson.build(url); } @Nonnull diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index 759ce7eeb30..d549f2938e0 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -85,7 +85,7 @@ public LayerStyleBuilder circleStroke(String color, int width) { return this; } - public JsonNode build() { + public JsonNode toJson() { validate(); var copy = new HashMap<>(props); diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java index 6461d697bfc..6214a5aac65 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java @@ -12,10 +12,10 @@ public final class MapboxStyleJson { private final List sources; private final List layers; - public MapboxStyleJson(String name, List sources, List layers) { + public MapboxStyleJson(String name, List sources, List layers) { this.name = name; this.sources = sources; - this.layers = layers; + this.layers = layers.stream().map(LayerStyleBuilder::toJson).toList(); } @JsonSerialize From 57f07ddac6a2c34973b4f591b49ad20bec83e02f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 21 Dec 2023 08:30:45 +0100 Subject: [PATCH 016/356] Use style.json from server --- client-next/src/components/MapView/MapView.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 011d9408148..258a925a142 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -4,7 +4,6 @@ import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts import { NavigationMarkers } from './NavigationMarkers.tsx'; import { LegLines } from './LegLines.tsx'; import { useMapDoubleClick } from './useMapDoubleClick.ts'; -import { mapStyle } from './mapStyle.ts'; import { useState } from 'react'; import { ContextMenuPopup } from './ContextMenuPopup.tsx'; @@ -37,12 +36,21 @@ export function MapView({ // @ts-ignore mapLib={import('maplibre-gl')} // @ts-ignore - mapStyle={mapStyle} + mapStyle="http://localhost:8080/otp/routers/default/inspector/vectortile/style.json" initialViewState={initialViewState} onDblClick={onMapDoubleClick} onContextMenu={(e) => { setShowPopup(e.lngLat); }} + interactiveLayerIds={["regular-stop"]} + onClick={e => { + console.log(e.features); + }} + // put lat/long in URL and pan to it on page reload + hash={true} + // disable pitching and rotating the map + touchPitch={false} + dragRotate={false} > Date: Thu, 21 Dec 2023 22:03:33 +0100 Subject: [PATCH 017/356] Refactor dependencies of map style classes --- ...ebugStyleJson.java => DebugStyleSpec.java} | 16 +++--- .../GraphInspectorVectorTileResource.java | 50 +++++++++---------- .../apis/vectortiles/model/LayerParams.java | 15 ++++++ .../vectortiles/model/LayerStyleBuilder.java | 7 +++ .../apis/vectortiles/model/LayerType.java | 7 +++ .../{MapboxStyleJson.java => StyleSpec.java} | 8 ++- .../apis/vectortiles/model/TileSource.java | 6 +++ .../framework/io/HttpUtils.java | 6 +-- 8 files changed, 77 insertions(+), 38 deletions(-) rename src/main/java/org/opentripplanner/apis/vectortiles/{DebugStyleJson.java => DebugStyleSpec.java} (70%) create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java rename src/main/java/org/opentripplanner/apis/vectortiles/model/{MapboxStyleJson.java => StyleSpec.java} (77%) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java similarity index 70% rename from src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java rename to src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 75592cbc0cd..9121d671c06 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleJson.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -2,12 +2,12 @@ import java.util.List; import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder; -import org.opentripplanner.apis.vectortiles.model.MapboxStyleJson; +import org.opentripplanner.apis.vectortiles.model.StyleSpec; import org.opentripplanner.apis.vectortiles.model.TileSource; import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; -public class DebugStyleJson { +public class DebugStyleSpec { private static final RasterSource BACKGROUND_SOURCE = new RasterSource( "background", @@ -15,10 +15,11 @@ public class DebugStyleJson { 256 ); - static MapboxStyleJson build(String url) { - var vectorSource = new VectorSource("debug", url); - List sources = List.of(BACKGROUND_SOURCE, vectorSource); - return new MapboxStyleJson( + public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} + + static StyleSpec build(VectorSource debugSource, VectorSourceLayer regularStops) { + List sources = List.of(BACKGROUND_SOURCE, debugSource); + return new StyleSpec( "OTP Debug Tiles", sources, List.of( @@ -31,8 +32,7 @@ static MapboxStyleJson build(String url) { LayerStyleBuilder .ofId("regular-stop") .typeCircle() - .source(vectorSource) - .sourceLayer("regularStops") + .vectorSourceLayer(regularStops) .circleStroke("#140d0e", 1) .circleColor("#fcf9fa") .minZoom(13) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 6d23e533aad..7e800b5639b 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -20,7 +20,10 @@ import javax.annotation.Nonnull; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.model.TileJson; -import org.opentripplanner.apis.vectortiles.model.MapboxStyleJson; +import org.opentripplanner.apis.vectortiles.model.LayerParams; +import org.opentripplanner.apis.vectortiles.model.LayerType; +import org.opentripplanner.apis.vectortiles.model.StyleSpec; +import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; @@ -38,10 +41,19 @@ @Path("/routers/{ignoreRouterId}/inspector/vectortile") public class GraphInspectorVectorTileResource { + private static final LayerParams REGULAR_STOPS = new LayerParams( + "regularStops", + LayerType.RegularStop + ); + private static final LayerParams AREA_STOPS = new LayerParams("areaStops", LayerType.AreaStop); + private static final LayerParams GEOFENCING_ZONES = new LayerParams( + "geofencingZones", + LayerType.GeofencingZones + ); private static final List> DEBUG_LAYERS = List.of( - new LayerParams("regularStops", LayerType.RegularStop), - new LayerParams("areaStops", LayerType.AreaStop), - new LayerParams("geofencingZones", LayerType.GeofencingZones) + REGULAR_STOPS, + AREA_STOPS, + GEOFENCING_ZONES ); private final OtpServerRequestContext serverContext; @@ -106,20 +118,21 @@ public TileJson getTileJson( @GET @Path("/style.json") @Produces(MediaType.APPLICATION_JSON) - public MapboxStyleJson getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) { + public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) { var base = HttpUtils.getBaseAddress(uri, headers); final String allLayers = DEBUG_LAYERS .stream() .map(LayerParameters::name) .collect(Collectors.joining(",")); var url = - base + - "/otp/routers/" + - ignoreRouterId + - "/inspector/vectortile/" + - allLayers + - "/tilejson.json"; - return DebugStyleJson.build(url); + "%s/otp/routers/%s/inspector/vectortile/%s/tilejson.json".formatted( + base, + ignoreRouterId, + allLayers + ); + + var vectorSource = new VectorSource("debug", url); + return DebugStyleSpec.build(vectorSource, REGULAR_STOPS.toVectorSourceLayer(vectorSource)); } @Nonnull @@ -148,17 +161,4 @@ private static LayerBuilder createLayerBuilder( case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); }; } - - private enum LayerType { - RegularStop, - AreaStop, - GeofencingZones, - } - - private record LayerParams(String name, LayerType type) implements LayerParameters { - @Override - public String mapper() { - return "DebugClient"; - } - } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java new file mode 100644 index 00000000000..2f1e6eb7109 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java @@ -0,0 +1,15 @@ +package org.opentripplanner.apis.vectortiles.model; + +import org.opentripplanner.apis.vectortiles.DebugStyleSpec; +import org.opentripplanner.inspector.vector.LayerParameters; + +public record LayerParams(String name, LayerType type) implements LayerParameters { + @Override + public String mapper() { + return "DebugClient"; + } + + public DebugStyleSpec.VectorSourceLayer toVectorSourceLayer(TileSource.VectorSource source) { + return new DebugStyleSpec.VectorSourceLayer(source, name); + } +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index d549f2938e0..0e1006027f2 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Stream; +import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; import org.opentripplanner.framework.json.ObjectMappers; /** @@ -24,6 +25,12 @@ public static LayerStyleBuilder ofId(String id) { return new LayerStyleBuilder(id); } + public LayerStyleBuilder vectorSourceLayer(VectorSourceLayer source) { + source(source.vectorSource()); + sourceLayer(source.vectorLayer()); + return this; + } + public enum LayerType { Circle, Raster, diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java new file mode 100644 index 00000000000..f4cb7a636fa --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java @@ -0,0 +1,7 @@ +package org.opentripplanner.apis.vectortiles.model; + +public enum LayerType { + RegularStop, + AreaStop, + GeofencingZones, +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java similarity index 77% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java rename to src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java index 6214a5aac65..090573d467d 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/MapboxStyleJson.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java @@ -6,13 +6,17 @@ import java.util.List; import java.util.Map; -public final class MapboxStyleJson { +/** + * Represents a style specification for Maplibre/Mapbox vector tile layers. + * https://maplibre.org/maplibre-style-spec/root/ + */ +public final class StyleSpec { private final String name; private final List sources; private final List layers; - public MapboxStyleJson(String name, List sources, List layers) { + public StyleSpec(String name, List sources, List layers) { this.name = name; this.sources = sources; this.layers = layers.stream().map(LayerStyleBuilder::toJson).toList(); diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java index 2e404d9a1eb..debf3070782 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -9,6 +9,9 @@ public sealed interface TileSource { String id(); + /** + * Represents a vector tile source. + */ record VectorSource(String id, String url) implements TileSource { @Override public String type() { @@ -16,6 +19,9 @@ public String type() { } } + /** + * Represents a raster-based source for map tiles. + */ record RasterSource(String id, List tiles, int tileSize) implements TileSource { @Override public String type() { diff --git a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java b/src/main/java/org/opentripplanner/framework/io/HttpUtils.java index 3450cf0786c..4981a8ab91b 100644 --- a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java +++ b/src/main/java/org/opentripplanner/framework/io/HttpUtils.java @@ -24,16 +24,16 @@ private HttpUtils() {} public static String getBaseAddress(UriInfo uri, HttpHeaders headers) { String protocol; if (headers.getRequestHeader(HEADER_X_FORWARDED_PROTO) != null) { - protocol = headers.getRequestHeader(HEADER_X_FORWARDED_PROTO).get(0); + protocol = headers.getRequestHeader(HEADER_X_FORWARDED_PROTO).getFirst(); } else { protocol = uri.getRequestUri().getScheme(); } String host; if (headers.getRequestHeader(HEADER_X_FORWARDED_HOST) != null) { - host = headers.getRequestHeader(HEADER_X_FORWARDED_HOST).get(0); + host = headers.getRequestHeader(HEADER_X_FORWARDED_HOST).getFirst(); } else if (headers.getRequestHeader(HEADER_HOST) != null) { - host = headers.getRequestHeader(HEADER_HOST).get(0); + host = headers.getRequestHeader(HEADER_HOST).getFirst(); } else { host = uri.getBaseUri().getHost() + ":" + uri.getBaseUri().getPort(); } From ffd8ae6c80720888f8cff37ff0a772a0a28c2a9c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 22 Dec 2023 11:33:55 +0100 Subject: [PATCH 018/356] Add popup data --- .../src/components/MapView/MapView.tsx | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 258a925a142..9409a0cc68a 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -1,4 +1,4 @@ -import { LngLat, Map, NavigationControl } from 'react-map-gl'; +import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl, Popup } from 'react-map-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts'; import { NavigationMarkers } from './NavigationMarkers.tsx'; @@ -6,6 +6,7 @@ import { LegLines } from './LegLines.tsx'; import { useMapDoubleClick } from './useMapDoubleClick.ts'; import { useState } from 'react'; import { ContextMenuPopup } from './ContextMenuPopup.tsx'; +import { Table } from 'react-bootstrap'; // TODO: this should be configurable const initialViewState = { @@ -14,6 +15,13 @@ const initialViewState = { zoom: 4, }; +class PopupData { + constructor( + public coordinates: LngLat, + public feature: MapboxGeoJSONFeature, + ) {} +} + export function MapView({ tripQueryVariables, setTripQueryVariables, @@ -28,7 +36,8 @@ export function MapView({ loading: boolean; }) { const onMapDoubleClick = useMapDoubleClick({ tripQueryVariables, setTripQueryVariables }); - const [showPopup, setShowPopup] = useState(null); + const [showContextPopup, setShowContextPopup] = useState(null); + const [showPropsPopup, setShowPropsPopup] = useState(null); return (
    @@ -40,11 +49,12 @@ export function MapView({ initialViewState={initialViewState} onDblClick={onMapDoubleClick} onContextMenu={(e) => { - setShowPopup(e.lngLat); + setShowContextPopup(e.lngLat); }} - interactiveLayerIds={["regular-stop"]} - onClick={e => { - console.log(e.features); + interactiveLayerIds={['regular-stop']} + onClick={(e) => { + const props = e.features[0]; + setShowPropsPopup(new PopupData(e.lngLat, props)); }} // put lat/long in URL and pan to it on page reload hash={true} @@ -61,14 +71,31 @@ export function MapView({ {tripQueryResult?.trip.tripPatterns.length && ( )} - {showPopup && ( + {showContextPopup && ( setShowPopup(null)} + coordinates={showContextPopup} + onClose={() => setShowContextPopup(null)} /> )} + {showPropsPopup && ( + setShowPropsPopup(null)} + > + + {Object.entries(showPropsPopup.feature.properties).map(([key, value]) => ( + + + + + ))} +
    {key}{value}
    +
    + )}
    ); From da28cf241fc0cd67d634be6a0fe05e05b73a72e5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 30 Dec 2023 20:11:32 +0100 Subject: [PATCH 019/356] Remove edge layer builder --- .../vector/edge/EdgeLayerBuilder.java | 40 ------------------- .../vector/edge/EdgePropertyMapper.java | 18 --------- 2 files changed, 58 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java delete mode 100644 src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java deleted file mode 100644 index 3c1bc3436d8..00000000000 --- a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.opentripplanner.inspector.vector.edge; - -import java.util.List; -import org.locationtech.jts.geom.Envelope; -import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.framework.geometry.GeometryUtils; -import org.opentripplanner.inspector.vector.LayerBuilder; -import org.opentripplanner.inspector.vector.LayerParameters; -import org.opentripplanner.routing.graph.Graph; -import org.opentripplanner.routing.graph.index.StreetIndex; -import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.vertex.Vertex; -import org.opentripplanner.transit.model.site.AreaStop; - -/** - * A vector tile layer containing all {@link AreaStop}s inside the vector tile bounds. - */ -public class EdgeLayerBuilder extends LayerBuilder { - - private final StreetIndex streetIndex; - - public EdgeLayerBuilder(Graph graph, LayerParameters layerParameters) { - super(new EdgePropertyMapper(), layerParameters.name(), layerParameters.expansionFactor()); - this.streetIndex = graph.getStreetIndex(); - } - - @Override - protected List getGeometries(Envelope query) { - return streetIndex - .getEdgesForEnvelope(query) - .stream() - .filter(edge -> edge.getGeometry() != null) - .map(edge -> { - Geometry geometry = edge.getGeometry().copy(); - geometry.setUserData(edge); - return geometry; - }) - .toList(); - } -} diff --git a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java deleted file mode 100644 index 936c965c9f5..00000000000 --- a/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.opentripplanner.inspector.vector.edge; - -import java.util.Collection; -import java.util.List; -import org.opentripplanner.api.mapping.PropertyMapper; -import org.opentripplanner.inspector.vector.KeyValue; -import org.opentripplanner.street.model.edge.Edge; - -/** - * A {@link PropertyMapper} for the {@link EdgeLayerBuilder} for the OTP debug client. - */ -public class EdgePropertyMapper extends PropertyMapper { - - @Override - protected Collection map(Edge edge) { - return List.of(new KeyValue("java-class", edge.getClass().getSimpleName())); - } -} From 18eb243f84aab078770d66fd2f8cceff74dd47ec Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 30 Dec 2023 23:31:49 +0100 Subject: [PATCH 020/356] Make styles a but prettier --- .../src/components/MapView/MapView.tsx | 12 +++-- .../apis/vectortiles/DebugStyleSpec.java | 6 ++- .../GraphInspectorVectorTileResource.java | 15 +++--- .../inspector/vector/KeyValue.java | 6 ++- .../vector/stop/AreaStopsLayerBuilder.java | 47 ------------------- ...ayerBuilder.java => StopLayerBuilder.java} | 15 +++--- .../stop/StopLocationPropertyMapper.java | 14 +++--- 7 files changed, 39 insertions(+), 76 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java rename src/main/java/org/opentripplanner/inspector/vector/stop/{RegularStopsLayerBuilder.java => StopLayerBuilder.java} (73%) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 9409a0cc68a..a565ae22db9 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -86,12 +86,14 @@ export function MapView({ closeButton={true} onClose={() => setShowPropsPopup(null)} > - +
    {Object.entries(showPropsPopup.feature.properties).map(([key, value]) => ( - - - - + + + + + + ))}
    {key}{value}
    {key}{value}
    diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 9121d671c06..c3dfc3d06f1 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -7,6 +7,10 @@ import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; +/** + * A Mapbox/Mapblibre style specification for rendering debug information about transit and + * street data. + */ public class DebugStyleSpec { private static final RasterSource BACKGROUND_SOURCE = new RasterSource( @@ -33,7 +37,7 @@ static StyleSpec build(VectorSource debugSource, VectorSourceLayer regularStops) .ofId("regular-stop") .typeCircle() .vectorSourceLayer(regularStops) - .circleStroke("#140d0e", 1) + .circleStroke("#140d0e", 2) .circleColor("#fcf9fa") .minZoom(13) .maxZoom(22) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 7e800b5639b..c27d38b260c 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -29,8 +29,7 @@ import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.inspector.vector.VectorTileResponseFactory; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; -import org.opentripplanner.inspector.vector.stop.AreaStopsLayerBuilder; -import org.opentripplanner.inspector.vector.stop.RegularStopsLayerBuilder; +import org.opentripplanner.inspector.vector.stop.StopLayerBuilder; import org.opentripplanner.model.FeedInfo; import org.opentripplanner.standalone.api.OtpServerRequestContext; @@ -152,12 +151,16 @@ private static LayerBuilder createLayerBuilder( OtpServerRequestContext context ) { return switch (layerParameters.type()) { - case RegularStop -> new RegularStopsLayerBuilder( - context.transitService(), + case RegularStop -> new StopLayerBuilder<>( layerParameters, - locale + locale, + e -> context.transitService().findRegularStop(e) + ); + case AreaStop -> new StopLayerBuilder<>( + layerParameters, + locale, + e -> context.transitService().findAreaStops(e) ); - case AreaStop -> new AreaStopsLayerBuilder(context.transitService(), layerParameters, locale); case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); }; } diff --git a/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java b/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java index d57afd3429e..6c8b0f3aa4e 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java +++ b/src/main/java/org/opentripplanner/inspector/vector/KeyValue.java @@ -1,3 +1,7 @@ package org.opentripplanner.inspector.vector; -public record KeyValue(String key, Object value) {} +public record KeyValue(String key, Object value) { + public static KeyValue kv(String key, Object value) { + return new KeyValue(key, value); + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java deleted file mode 100644 index d1a2552e4e2..00000000000 --- a/src/main/java/org/opentripplanner/inspector/vector/stop/AreaStopsLayerBuilder.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.opentripplanner.inspector.vector.stop; - -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.function.Function; -import org.locationtech.jts.geom.Envelope; -import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.inspector.vector.LayerBuilder; -import org.opentripplanner.inspector.vector.LayerParameters; -import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitService; - -/** - * A vector tile layer containing all {@link AreaStop}s inside the vector tile bounds. - */ -public class AreaStopsLayerBuilder extends LayerBuilder { - - private final Function> findAreaStops; - - public AreaStopsLayerBuilder( - TransitService transitService, - LayerParameters layerParameters, - Locale locale - ) { - super( - new StopLocationPropertyMapper(locale), - layerParameters.name(), - layerParameters.expansionFactor() - ); - this.findAreaStops = transitService::findAreaStops; - } - - @Override - protected List getGeometries(Envelope query) { - return findAreaStops - .apply(query) - .stream() - .map(areaStop -> { - Geometry geometry = areaStop.getGeometry().copy(); - geometry.setUserData(areaStop); - return geometry; - }) - .toList(); - } -} diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/RegularStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java similarity index 73% rename from src/main/java/org/opentripplanner/inspector/vector/stop/RegularStopsLayerBuilder.java rename to src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java index f943e23eb88..40784ab5b3b 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/stop/RegularStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java @@ -10,31 +10,30 @@ import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitService; /** * A vector tile layer containing all {@link RegularStop}s inside the vector tile bounds. */ -public class RegularStopsLayerBuilder extends LayerBuilder { +public class StopLayerBuilder extends LayerBuilder { - private final Function> findAreaStops; + private final Function> findStops; - public RegularStopsLayerBuilder( - TransitService transitService, + public StopLayerBuilder( LayerParameters layerParameters, - Locale locale + Locale locale, + Function> findStops ) { super( new StopLocationPropertyMapper(locale), layerParameters.name(), layerParameters.expansionFactor() ); - this.findAreaStops = transitService::findRegularStop; + this.findStops = findStops; } @Override protected List getGeometries(Envelope query) { - return findAreaStops + return findStops .apply(query) .stream() .map(stop -> { diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java index d2e1accf483..44729bcb407 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java @@ -1,5 +1,7 @@ package org.opentripplanner.inspector.vector.stop; +import static org.opentripplanner.inspector.vector.KeyValue.kv; + import java.util.Collection; import java.util.List; import java.util.Locale; @@ -7,7 +9,6 @@ import org.opentripplanner.api.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.service.TransitService; /** * A {@link PropertyMapper} for the {@link AreaStopsLayerBuilder} for the OTP debug client. @@ -20,15 +21,12 @@ public StopLocationPropertyMapper(Locale locale) { this.i18NStringMapper = new I18NStringMapper(locale); } - public static PropertyMapper create(TransitService ignored, Locale locale) { - return new StopLocationPropertyMapper(locale); - } - @Override - protected Collection map(StopLocation input) { + protected Collection map(StopLocation stop) { return List.of( - new KeyValue("id", input.getId().toString()), - new KeyValue("name", i18NStringMapper.mapToApi(input.getName())) + kv("name", i18NStringMapper.mapToApi(stop.getName())), + kv("id", stop.getId().toString()), + kv("parentId", stop.isPartOfStation() ? stop.getParentStation().getId().toString() : null) ); } } From 7cfbae80109ecd00c9240ca9c2e803206eae8fd8 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 31 Dec 2023 00:04:49 +0100 Subject: [PATCH 021/356] Add test for debug style spec --- .../vectortiles/model/LayerStyleBuilder.java | 3 +- .../apis/vectortiles/DebugStyleSpecTest.java | 25 +++++++++++ .../vector/stop/AreaStopLayerBuilderTest.java | 16 ++------ .../test/support/ResourceLoader.java | 11 +++++ .../apis/vectortiles/style.json | 41 +++++++++++++++++++ 5 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java create mode 100644 src/test/resources/org/opentripplanner/apis/vectortiles/style.json diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index 0e1006027f2..41144611f92 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -27,8 +27,7 @@ public static LayerStyleBuilder ofId(String id) { public LayerStyleBuilder vectorSourceLayer(VectorSourceLayer source) { source(source.vectorSource()); - sourceLayer(source.vectorLayer()); - return this; + return sourceLayer(source.vectorLayer()); } public enum LayerType { diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java new file mode 100644 index 00000000000..4fd9204c2a9 --- /dev/null +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -0,0 +1,25 @@ +package org.opentripplanner.apis.vectortiles; + +import static org.opentripplanner.test.support.JsonAssertions.assertEqualJson; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; +import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; +import org.opentripplanner.framework.json.ObjectMappers; +import org.opentripplanner.test.support.ResourceLoader; + +class DebugStyleSpecTest { + + private final ResourceLoader RES = ResourceLoader.of(this); + + @Test + void spec() { + var vectorSource = new VectorSource("vectorSource", "https://example.com"); + var regularStops = new VectorSourceLayer(vectorSource, "regularStops"); + var spec = DebugStyleSpec.build(vectorSource, regularStops); + + var json = ObjectMappers.ignoringExtraFields().valueToTree(spec).toPrettyString(); + var expectation = RES.fileToString("style.json"); + assertEqualJson(expectation, json); + } +} diff --git a/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java b/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java index 3fea49ab236..231f3ddce59 100644 --- a/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java +++ b/src/test/java/org/opentripplanner/inspector/vector/stop/AreaStopLayerBuilderTest.java @@ -1,12 +1,10 @@ package org.opentripplanner.inspector.vector.stop; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Locale; import org.junit.jupiter.api.Test; -import org.locationtech.jts.geom.Coordinate; -import org.opentripplanner.framework.geometry.GeometryUtils; +import org.opentripplanner._support.geometry.Polygons; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.inspector.vector.KeyValue; @@ -17,22 +15,15 @@ class AreaStopLayerBuilderTest { - private static final Coordinate[] COORDINATES = { - new Coordinate(0, 0), - new Coordinate(0, 1), - new Coordinate(1, 1), - new Coordinate(1, 0), - new Coordinate(0, 0), - }; private static final FeedScopedId ID = new FeedScopedId("FEED", "ID"); - private static final I18NString NAME = new NonLocalizedString("Test stop"); + private static final I18NString NAME = I18NString.of("Test stop"); private final StopModelBuilder stopModelBuilder = StopModel.of(); private final AreaStop areaStop = stopModelBuilder .areaStop(ID) .withName(NAME) - .withGeometry(GeometryUtils.getGeometryFactory().createPolygon(COORDINATES)) + .withGeometry(Polygons.BERLIN) .build(); @Test @@ -41,7 +32,6 @@ void map() { var properties = subject.map(areaStop); - assertEquals(2, properties.size()); assertTrue(properties.contains(new KeyValue("id", ID.toString()))); assertTrue(properties.contains(new KeyValue("name", NAME.toString()))); } diff --git a/src/test/java/org/opentripplanner/test/support/ResourceLoader.java b/src/test/java/org/opentripplanner/test/support/ResourceLoader.java index 38fe02a8c74..5eb51cac55a 100644 --- a/src/test/java/org/opentripplanner/test/support/ResourceLoader.java +++ b/src/test/java/org/opentripplanner/test/support/ResourceLoader.java @@ -55,6 +55,17 @@ public File file(String path) { return file; } + /** + * Returns the string content of a file. + */ + public String fileToString(String p) { + try { + return Files.readString(file(p).toPath()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** * Return a URL for the given resource. */ diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json new file mode 100644 index 00000000000..f0ed87090c3 --- /dev/null +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -0,0 +1,41 @@ +{ + "name": "OTP Debug Tiles", + "sources": { + "background": { + "id": "background", + "tiles": [ + "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" + ], + "tileSize": 256, + "type": "raster" + }, + "vectorSource": { + "id": "vectorSource", + "url": "https://example.com", + "type": "vector" + } + }, + "layers": [ + { + "id": "background", + "source": "background", + "type": "raster", + "maxzoom": 22, + "minzoom": 0 + }, + { + "maxzoom": 22, + "paint": { + "circle-stroke-width": 2, + "circle-color": "#fcf9fa", + "circle-stroke-color": "#140d0e" + }, + "id": "regular-stop", + "source": "vectorSource", + "source-layer": "regularStops", + "type": "circle", + "minzoom": 13 + } + ], + "version": 8 +} From c7395d8282ea247e4d4a1d808efb740c0a6a6a79 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 31 Dec 2023 00:13:31 +0100 Subject: [PATCH 022/356] Save a JSON round trip --- .../apis/vectortiles/DebugStyleSpecTest.java | 2 +- .../test/support/JsonAssertions.java | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index 4fd9204c2a9..d685e07a2f2 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -18,7 +18,7 @@ void spec() { var regularStops = new VectorSourceLayer(vectorSource, "regularStops"); var spec = DebugStyleSpec.build(vectorSource, regularStops); - var json = ObjectMappers.ignoringExtraFields().valueToTree(spec).toPrettyString(); + var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RES.fileToString("style.json"); assertEqualJson(expectation, json); } diff --git a/src/test/java/org/opentripplanner/test/support/JsonAssertions.java b/src/test/java/org/opentripplanner/test/support/JsonAssertions.java index f3942c16f3b..2dab1e96190 100644 --- a/src/test/java/org/opentripplanner/test/support/JsonAssertions.java +++ b/src/test/java/org/opentripplanner/test/support/JsonAssertions.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.opentripplanner.standalone.config.framework.json.JsonSupport; @@ -15,9 +16,19 @@ public class JsonAssertions { */ public static void assertEqualJson(String expected, String actual) { try { - var act = MAPPER.readTree(actual); + assertEqualJson(expected, MAPPER.readTree(actual)); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + /** + * @see JsonAssertions#assertEqualJson(String, String) + */ + public static void assertEqualJson(String expected, JsonNode actual) { + try { var exp = MAPPER.readTree(expected); - assertEquals(JsonSupport.prettyPrint(exp), JsonSupport.prettyPrint(act)); + assertEquals(JsonSupport.prettyPrint(exp), JsonSupport.prettyPrint(actual)); } catch (JsonProcessingException e) { throw new RuntimeException(e); } From 934b809480f9f4976f95d7f5d93125a1d7d4e1e9 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 2 Jan 2024 16:59:58 +0100 Subject: [PATCH 023/356] Add attribution, remove client side style --- .../src/components/MapView/mapStyle.ts | 19 ------------------- .../apis/vectortiles/DebugStyleSpec.java | 3 ++- .../apis/vectortiles/model/TileSource.java | 2 +- .../apis/vectortiles/style.json | 1 + 4 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 client-next/src/components/MapView/mapStyle.ts diff --git a/client-next/src/components/MapView/mapStyle.ts b/client-next/src/components/MapView/mapStyle.ts deleted file mode 100644 index ecaa88c0354..00000000000 --- a/client-next/src/components/MapView/mapStyle.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const mapStyle = { - version: 8, - sources: { - osm: { - type: 'raster', - tiles: ['https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'], - tileSize: 256, - attribution: '© OpenStreetMap Contributors', - maxzoom: 19, - }, - }, - layers: [ - { - id: 'osm', - type: 'raster', - source: 'osm', // This must match the source key above - }, - ], -}; diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index c3dfc3d06f1..9a4fe9be123 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -16,7 +16,8 @@ public class DebugStyleSpec { private static final RasterSource BACKGROUND_SOURCE = new RasterSource( "background", List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), - 256 + 256, + "© OpenStreetMap Contributors" ); public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java index debf3070782..d9dbe50f68e 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -22,7 +22,7 @@ public String type() { /** * Represents a raster-based source for map tiles. */ - record RasterSource(String id, List tiles, int tileSize) implements TileSource { + record RasterSource(String id, List tiles, int tileSize, String attribution) implements TileSource { @Override public String type() { return "raster"; diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index f0ed87090c3..6f95471a667 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -7,6 +7,7 @@ "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" ], "tileSize": 256, + "attribution" : "© OpenStreetMap Contributors", "type": "raster" }, "vectorSource": { From 826a8429e14afe04ea48dbe8f4e5061d4cb303fd Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 2 Jan 2024 17:09:44 +0100 Subject: [PATCH 024/356] Add documentation, fix frontend code --- client-next/src/components/MapView/MapView.tsx | 10 +++++----- .../apis/vectortiles/model/LayerParams.java | 11 ++++++++--- .../apis/vectortiles/model/StyleSpec.java | 2 ++ .../apis/vectortiles/model/TileSource.java | 8 ++++++-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index a565ae22db9..c3879dd2a6b 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -87,14 +87,14 @@ export function MapView({ onClose={() => setShowPropsPopup(null)} > - {Object.entries(showPropsPopup.feature.properties).map(([key, value]) => ( - - + + {Object.entries(showPropsPopup.feature.properties).map(([key, value]) => ( + - - ))} + ))} +
    {key} {value}
    )} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java index 2f1e6eb7109..7365e8972da 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java @@ -1,6 +1,7 @@ package org.opentripplanner.apis.vectortiles.model; -import org.opentripplanner.apis.vectortiles.DebugStyleSpec; +import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; +import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.inspector.vector.LayerParameters; public record LayerParams(String name, LayerType type) implements LayerParameters { @@ -9,7 +10,11 @@ public String mapper() { return "DebugClient"; } - public DebugStyleSpec.VectorSourceLayer toVectorSourceLayer(TileSource.VectorSource source) { - return new DebugStyleSpec.VectorSourceLayer(source, name); + /** + * Convert these params to a vector source layer so that it can be used in the style for rendering + * in the frontend. + */ + public VectorSourceLayer toVectorSourceLayer(VectorSource source) { + return new VectorSourceLayer(source, name); } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java index 090573d467d..84e19f25364 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java @@ -9,6 +9,8 @@ /** * Represents a style specification for Maplibre/Mapbox vector tile layers. * https://maplibre.org/maplibre-style-spec/root/ + *

    + * Maplibre uses these to render vector maps in the browser. */ public final class StyleSpec { diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java index d9dbe50f68e..e3186cc1d99 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -3,6 +3,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.List; +/** + * Represent a data source where Maplibre can fetch data for rendering directly in the browser. + */ public sealed interface TileSource { @JsonSerialize String type(); @@ -10,7 +13,7 @@ public sealed interface TileSource { String id(); /** - * Represents a vector tile source. + * Represents a vector tile source which is rendered into a map in the browser. */ record VectorSource(String id, String url) implements TileSource { @Override @@ -20,7 +23,8 @@ public String type() { } /** - * Represents a raster-based source for map tiles. + * Represents a raster-based source for map tiles. These are used mainly for background + * map layers with vector data being rendered on top of it. */ record RasterSource(String id, List tiles, int tileSize, String attribution) implements TileSource { @Override From c8642006f32c59f94007bcb532bc2eb51f8f1804 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 2 Jan 2024 21:57:30 +0100 Subject: [PATCH 025/356] Make TS compiler happy --- client-next/src/components/MapView/MapView.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index c3879dd2a6b..d03c4869067 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -53,8 +53,10 @@ export function MapView({ }} interactiveLayerIds={['regular-stop']} onClick={(e) => { - const props = e.features[0]; - setShowPropsPopup(new PopupData(e.lngLat, props)); + if (e.features) { + const props = e.features[0]; + setShowPropsPopup(new PopupData(e.lngLat, props)); + } }} // put lat/long in URL and pan to it on page reload hash={true} @@ -79,7 +81,7 @@ export function MapView({ onClose={() => setShowContextPopup(null)} /> )} - {showPropsPopup && ( + {showPropsPopup && showPropsPopup.feature && showPropsPopup.feature.properties && ( Date: Tue, 2 Jan 2024 22:00:55 +0100 Subject: [PATCH 026/356] Convert from class to type --- client-next/src/components/MapView/MapView.tsx | 9 ++------- .../apis/vectortiles/model/TileSource.java | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index d03c4869067..9ecc35c27aa 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -15,12 +15,7 @@ const initialViewState = { zoom: 4, }; -class PopupData { - constructor( - public coordinates: LngLat, - public feature: MapboxGeoJSONFeature, - ) {} -} +type PopupData = { coordinates: LngLat; feature: MapboxGeoJSONFeature }; export function MapView({ tripQueryVariables, @@ -55,7 +50,7 @@ export function MapView({ onClick={(e) => { if (e.features) { const props = e.features[0]; - setShowPropsPopup(new PopupData(e.lngLat, props)); + setShowPropsPopup({ coordinates: e.lngLat, feature: props }); } }} // put lat/long in URL and pan to it on page reload diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java index e3186cc1d99..06af294a4f0 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -26,7 +26,8 @@ public String type() { * Represents a raster-based source for map tiles. These are used mainly for background * map layers with vector data being rendered on top of it. */ - record RasterSource(String id, List tiles, int tileSize, String attribution) implements TileSource { + record RasterSource(String id, List tiles, int tileSize, String attribution) + implements TileSource { @Override public String type() { return "raster"; From 1cbce1fcd83b0af48f8f9d5cc62c522ce621fbea Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 2 Jan 2024 22:15:40 +0100 Subject: [PATCH 027/356] Use optional chaining --- client-next/src/components/MapView/MapView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 9ecc35c27aa..95c898c4a28 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -76,7 +76,7 @@ export function MapView({ onClose={() => setShowContextPopup(null)} /> )} - {showPropsPopup && showPropsPopup.feature && showPropsPopup.feature.properties && ( + {showPropsPopup?.feature?.properties && ( Date: Thu, 4 Jan 2024 17:46:18 +0100 Subject: [PATCH 028/356] Remove GTFS-RT websocket updater --- pom.xml | 21 -- .../config/routerconfig/UpdatersConfig.java | 9 - .../WebsocketGtfsRealtimeUpdaterConfig.java | 24 -- .../updater/UpdatersParameters.java | 3 - .../configure/UpdaterConfigurator.java | 10 - .../trip/WebsocketGtfsRealtimeUpdater.java | 211 ------------------ ...ebsocketGtfsRealtimeUpdaterParameters.java | 45 ---- 7 files changed, 323 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/WebsocketGtfsRealtimeUpdaterConfig.java delete mode 100644 src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdater.java delete mode 100644 src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdaterParameters.java diff --git a/pom.xml b/pom.xml index de8baecefd9..0e03a0ccc7d 100644 --- a/pom.xml +++ b/pom.xml @@ -551,20 +551,6 @@ import - - - io.netty - netty-bom - 4.1.100.Final - pom - import - - @@ -842,13 +828,6 @@ protobuf-java - - - - org.asynchttpclient - async-http-client - 2.12.3 - org.onebusaway diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java index 0f61fa4f7a2..08371660b8a 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/UpdatersConfig.java @@ -14,7 +14,6 @@ import static org.opentripplanner.standalone.config.routerconfig.UpdatersConfig.Type.VEHICLE_PARKING; import static org.opentripplanner.standalone.config.routerconfig.UpdatersConfig.Type.VEHICLE_POSITIONS; import static org.opentripplanner.standalone.config.routerconfig.UpdatersConfig.Type.VEHICLE_RENTAL; -import static org.opentripplanner.standalone.config.routerconfig.UpdatersConfig.Type.WEBSOCKET_GTFS_RT_UPDATER; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; @@ -39,7 +38,6 @@ import org.opentripplanner.standalone.config.routerconfig.updaters.VehicleParkingUpdaterConfig; import org.opentripplanner.standalone.config.routerconfig.updaters.VehiclePositionsUpdaterConfig; import org.opentripplanner.standalone.config.routerconfig.updaters.VehicleRentalUpdaterConfig; -import org.opentripplanner.standalone.config.routerconfig.updaters.WebsocketGtfsRealtimeUpdaterConfig; import org.opentripplanner.standalone.config.routerconfig.updaters.azure.SiriAzureETUpdaterConfig; import org.opentripplanner.standalone.config.routerconfig.updaters.azure.SiriAzureSXUpdaterConfig; import org.opentripplanner.standalone.config.sandbox.VehicleRentalServiceDirectoryFetcherConfig; @@ -48,7 +46,6 @@ import org.opentripplanner.updater.alert.GtfsRealtimeAlertsUpdaterParameters; import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdaterParameters; import org.opentripplanner.updater.trip.PollingTripUpdaterParameters; -import org.opentripplanner.updater.trip.WebsocketGtfsRealtimeUpdaterParameters; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; import org.opentripplanner.updater.vehicle_position.VehiclePositionsUpdaterParameters; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdaterParameters; @@ -185,11 +182,6 @@ public List getSiriSXUpdaterParameters() { return getParameters(SIRI_SX_UPDATER); } - @Override - public List getWebsocketGtfsRealtimeUpdaterParameters() { - return getParameters(WEBSOCKET_GTFS_RT_UPDATER); - } - @Override public List getMqttGtfsRealtimeUpdaterParameters() { return getParameters(MQTT_GTFS_RT_UPDATER); @@ -222,7 +214,6 @@ public enum Type { BIKE_RENTAL(VehicleRentalUpdaterConfig::create), VEHICLE_RENTAL(VehicleRentalUpdaterConfig::create), STOP_TIME_UPDATER(PollingTripUpdaterConfig::create), - WEBSOCKET_GTFS_RT_UPDATER(WebsocketGtfsRealtimeUpdaterConfig::create), MQTT_GTFS_RT_UPDATER(MqttGtfsRealtimeUpdaterConfig::create), REAL_TIME_ALERTS(GtfsRealtimeAlertsUpdaterConfig::create), VEHICLE_POSITIONS(VehiclePositionsUpdaterConfig::create), diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/WebsocketGtfsRealtimeUpdaterConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/WebsocketGtfsRealtimeUpdaterConfig.java deleted file mode 100644 index 5f1c203ca43..00000000000 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/WebsocketGtfsRealtimeUpdaterConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.opentripplanner.standalone.config.routerconfig.updaters; - -import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V1_5; - -import org.opentripplanner.standalone.config.framework.json.NodeAdapter; -import org.opentripplanner.updater.trip.BackwardsDelayPropagationType; -import org.opentripplanner.updater.trip.WebsocketGtfsRealtimeUpdaterParameters; - -public class WebsocketGtfsRealtimeUpdaterConfig { - - public static WebsocketGtfsRealtimeUpdaterParameters create(String configRef, NodeAdapter c) { - return new WebsocketGtfsRealtimeUpdaterParameters( - configRef, - c.of("feedId").since(V1_5).summary("TODO").asString(), - c.of("url").since(V1_5).summary("TODO").asString(null), - c.of("reconnectPeriodSec").since(V1_5).summary("TODO").asInt(60), - c - .of("backwardsDelayPropagationType") - .since(V1_5) - .summary("TODO") - .asEnum(BackwardsDelayPropagationType.REQUIRED_NO_DATA) - ); - } -} diff --git a/src/main/java/org/opentripplanner/updater/UpdatersParameters.java b/src/main/java/org/opentripplanner/updater/UpdatersParameters.java index 8a7c422eb03..a955e757100 100644 --- a/src/main/java/org/opentripplanner/updater/UpdatersParameters.java +++ b/src/main/java/org/opentripplanner/updater/UpdatersParameters.java @@ -10,7 +10,6 @@ import org.opentripplanner.updater.alert.GtfsRealtimeAlertsUpdaterParameters; import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdaterParameters; import org.opentripplanner.updater.trip.PollingTripUpdaterParameters; -import org.opentripplanner.updater.trip.WebsocketGtfsRealtimeUpdaterParameters; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdaterParameters; import org.opentripplanner.updater.vehicle_position.VehiclePositionsUpdaterParameters; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdaterParameters; @@ -34,8 +33,6 @@ public interface UpdatersParameters { List getSiriSXUpdaterParameters(); - List getWebsocketGtfsRealtimeUpdaterParameters(); - List getMqttGtfsRealtimeUpdaterParameters(); List getVehicleParkingUpdaterParameters(); diff --git a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java index 037bd080f47..c755578da41 100644 --- a/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java +++ b/src/main/java/org/opentripplanner/updater/configure/UpdaterConfigurator.java @@ -23,14 +23,11 @@ import org.opentripplanner.updater.trip.MqttGtfsRealtimeUpdater; import org.opentripplanner.updater.trip.PollingTripUpdater; import org.opentripplanner.updater.trip.TimetableSnapshotSource; -import org.opentripplanner.updater.trip.WebsocketGtfsRealtimeUpdater; import org.opentripplanner.updater.vehicle_parking.VehicleParkingDataSourceFactory; import org.opentripplanner.updater.vehicle_parking.VehicleParkingUpdater; import org.opentripplanner.updater.vehicle_position.PollingVehiclePositionUpdater; import org.opentripplanner.updater.vehicle_rental.VehicleRentalUpdater; import org.opentripplanner.updater.vehicle_rental.datasources.VehicleRentalDataSourceFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Sets up and starts all the graph updaters. @@ -41,8 +38,6 @@ */ public class UpdaterConfigurator { - private static final Logger LOG = LoggerFactory.getLogger(UpdaterConfigurator.class); - private final Graph graph; private final TransitModel transitModel; private final UpdatersParameters updatersParameters; @@ -177,11 +172,6 @@ private List createUpdatersFromConfig() { for (var configItem : updatersParameters.getSiriSXUpdaterParameters()) { updaters.add(new SiriSXUpdater(configItem, transitModel)); } - for (var configItem : updatersParameters.getWebsocketGtfsRealtimeUpdaterParameters()) { - updaters.add( - new WebsocketGtfsRealtimeUpdater(configItem, provideGtfsTimetableSnapshot(), transitModel) - ); - } for (var configItem : updatersParameters.getMqttGtfsRealtimeUpdaterParameters()) { updaters.add( new MqttGtfsRealtimeUpdater(configItem, transitModel, provideGtfsTimetableSnapshot()) diff --git a/src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdater.java b/src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdater.java deleted file mode 100644 index 007c73d9b9b..00000000000 --- a/src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdater.java +++ /dev/null @@ -1,211 +0,0 @@ -package org.opentripplanner.updater.trip; - -import static org.asynchttpclient.Dsl.asyncHttpClient; - -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.transit.realtime.GtfsRealtime; -import com.google.transit.realtime.GtfsRealtime.FeedEntity; -import com.google.transit.realtime.GtfsRealtime.FeedMessage; -import com.google.transit.realtime.GtfsRealtime.TripUpdate; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; -import org.asynchttpclient.AsyncHttpClient; -import org.asynchttpclient.ws.WebSocket; -import org.asynchttpclient.ws.WebSocketListener; -import org.asynchttpclient.ws.WebSocketUpgradeHandler; -import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.TransitModel; -import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; -import org.opentripplanner.updater.spi.GraphUpdater; -import org.opentripplanner.updater.spi.UpdateResult; -import org.opentripplanner.updater.spi.WriteToGraphCallback; -import org.opentripplanner.updater.trip.metrics.TripUpdateMetrics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class starts an HTTP client which opens a websocket connection to a GTFS-RT data source. A - * callback is registered which handles incoming GTFS-RT messages as they stream in by placing a - * GTFS-RT decoder Runnable task in the single-threaded executor for handling. - * - *

    - * websocket.type = websocket-gtfs-rt-updater
    - * websocket.defaultAgencyId = agency
    - * websocket.url = ws://localhost:8088/tripUpdates
    - * 
    - */ -public class WebsocketGtfsRealtimeUpdater implements GraphUpdater { - - private static final Logger LOG = LoggerFactory.getLogger(WebsocketGtfsRealtimeUpdater.class); - - /** - * Number of seconds to wait before checking again whether we are still connected - */ - private static final int CHECK_CONNECTION_PERIOD_SEC = 1; - - /** - * Url of the websocket server - */ - private final String url; - - /** - * The ID for the static feed to which these TripUpdates are applied - */ - private final String feedId; - - /** - * The number of seconds to wait before reconnecting after a failed connection. - */ - private final int reconnectPeriodSec; - - private final String configRef; - - private final BackwardsDelayPropagationType backwardsDelayPropagationType; - - private final TimetableSnapshotSource snapshotSource; - - /** - * Parent update manager. Is used to execute graph writer runnables. - */ - private WriteToGraphCallback saveResultOnGraph; - - private GtfsRealtimeFuzzyTripMatcher fuzzyTripMatcher; - - private final Consumer recordMetrics; - - public WebsocketGtfsRealtimeUpdater( - WebsocketGtfsRealtimeUpdaterParameters parameters, - TimetableSnapshotSource snapshotSource, - TransitModel transitModel - ) { - this.configRef = parameters.configRef(); - this.url = parameters.url(); - this.feedId = parameters.feedId(); - this.reconnectPeriodSec = parameters.getReconnectPeriodSec(); - this.backwardsDelayPropagationType = parameters.getBackwardsDelayPropagationType(); - this.snapshotSource = snapshotSource; - this.fuzzyTripMatcher = - new GtfsRealtimeFuzzyTripMatcher(new DefaultTransitService(transitModel)); - this.recordMetrics = TripUpdateMetrics.streaming(parameters); - } - - @Override - public void setGraphUpdaterManager(WriteToGraphCallback saveResultOnGraph) { - this.saveResultOnGraph = saveResultOnGraph; - } - - @Override - public void run() throws InterruptedException, IOException { - while (true) { - AsyncHttpClient client = asyncHttpClient(); - WebSocketListener listener = new Listener(); - WebSocketUpgradeHandler handler = new WebSocketUpgradeHandler.Builder() - .addWebSocketListener(listener) - .build(); - WebSocket socket = null; - boolean connectionSuccessful = true; - // Try to create a websocket connection - try { - socket = client.prepareGet(url).execute(handler).get(); - LOG.info("Successfully connected to {}.", url); - } catch (ExecutionException e) { - LOG.error("Could not connect to {}: {}", url, e.getCause().getMessage()); - connectionSuccessful = false; - } catch (Exception e) { - LOG.error("Unknown exception when trying to connect to {}.", url, e); - connectionSuccessful = false; - } - - // If connection was unsuccessful, wait some time before trying again - if (!connectionSuccessful) { - Thread.sleep(reconnectPeriodSec * 1000); - } - - // Keep checking whether connection is still open - while (true) { - if (socket == null || !socket.isOpen()) { - // The connection is closed somehow, try to reconnect - if (connectionSuccessful) { - LOG.warn("Connection to {} was lost. Trying to reconnect...", url); - } - break; - } - Thread.sleep(CHECK_CONNECTION_PERIOD_SEC * 1000); - } - - client.close(); - } - } - - @Override - public String getConfigRef() { - return configRef; - } - - /** - * Auxiliary class to handle incoming messages via the websocket connection - */ - private class Listener implements WebSocketListener { - - @Override - public void onOpen(WebSocket websocket) {} - - @Override - public void onClose(WebSocket websocket, int code, String reason) {} - - @Override - public void onError(Throwable t) {} - - @Override - public void onBinaryFrame(byte[] message, boolean finalFragment, int rsv) { - FeedMessage feedMessage; - List feedEntityList; - List updates = null; - boolean fullDataset = true; - try { - // Decode message - feedMessage = FeedMessage.PARSER.parseFrom(message); - feedEntityList = feedMessage.getEntityList(); - - // Change fullDataset value if this is an incremental update - if ( - feedMessage.hasHeader() && - feedMessage.getHeader().hasIncrementality() && - feedMessage - .getHeader() - .getIncrementality() - .equals(GtfsRealtime.FeedHeader.Incrementality.DIFFERENTIAL) - ) { - fullDataset = false; - } - - // Create List of TripUpdates - updates = new ArrayList<>(feedEntityList.size()); - for (FeedEntity feedEntity : feedEntityList) { - if (feedEntity.hasTripUpdate()) { - updates.add(feedEntity.getTripUpdate()); - } - } - } catch (InvalidProtocolBufferException e) { - LOG.error("Could not decode gtfs-rt message:", e); - } - - if (updates != null) { - // Handle trip updates via graph writer runnable - TripUpdateGraphWriterRunnable runnable = new TripUpdateGraphWriterRunnable( - snapshotSource, - fuzzyTripMatcher, - backwardsDelayPropagationType, - fullDataset, - updates, - feedId, - recordMetrics - ); - saveResultOnGraph.execute(runnable); - } - } - } -} diff --git a/src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdaterParameters.java b/src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdaterParameters.java deleted file mode 100644 index d5eebd748af..00000000000 --- a/src/main/java/org/opentripplanner/updater/trip/WebsocketGtfsRealtimeUpdaterParameters.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.opentripplanner.updater.trip; - -public class WebsocketGtfsRealtimeUpdaterParameters implements UrlUpdaterParameters { - - private final String configRef; - private final String feedId; - private final String url; - private final int reconnectPeriodSec; - private final BackwardsDelayPropagationType backwardsDelayPropagationType; - - public WebsocketGtfsRealtimeUpdaterParameters( - String configRef, - String feedId, - String url, - int reconnectPeriodSec, - BackwardsDelayPropagationType backwardsDelayPropagationType - ) { - this.configRef = configRef; - this.feedId = feedId; - this.url = url; - this.reconnectPeriodSec = reconnectPeriodSec; - this.backwardsDelayPropagationType = backwardsDelayPropagationType; - } - - public String url() { - return url; - } - - public String feedId() { - return feedId; - } - - int getReconnectPeriodSec() { - return reconnectPeriodSec; - } - - /** The config name/type for the updater. Used to reference the configuration element. */ - public String configRef() { - return configRef; - } - - public BackwardsDelayPropagationType getBackwardsDelayPropagationType() { - return backwardsDelayPropagationType; - } -} From 4a29056bac782b0ee70868f6d5d136a8473ccdc5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 4 Jan 2024 17:47:52 +0100 Subject: [PATCH 029/356] Remove websocket documentation --- doc-templates/UpdaterConfig.md | 12 ----- docs/RouterConfiguration.md | 4 -- docs/UpdaterConfig.md | 50 ------------------- docs/sandbox/SiriUpdater.md | 30 +++++------ .../standalone/config/router-config.json | 5 -- 5 files changed, 15 insertions(+), 86 deletions(-) diff --git a/doc-templates/UpdaterConfig.md b/doc-templates/UpdaterConfig.md index 90c699fcf28..a239317f244 100644 --- a/doc-templates/UpdaterConfig.md +++ b/doc-templates/UpdaterConfig.md @@ -45,18 +45,6 @@ The information is downloaded in a single HTTP request and polled regularly. -### TripUpdates via WebSocket - -This updater doesn't poll a data source but opens a persistent connection to the GTFS-RT provider, -which then sends incremental updates immediately as they become available. - -The [OneBusAway GTFS-realtime exporter project](https://github.com/OneBusAway/onebusaway-gtfs-realtime-exporter) -provides this kind of streaming, incremental updates over a websocket rather than a single large -file. - - - - ### Vehicle Positions VehiclePositions give the location of some or all vehicles currently in service, in terms of diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 65f50260ee5..30e423f29b1 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -740,10 +740,6 @@ Used to group requests when monitoring OTP. "position" ] }, - { - "type" : "websocket-gtfs-rt-updater", - "feedId" : "ov" - }, { "type" : "siri-et-updater", "url" : "https://example.com/some/path", diff --git a/docs/UpdaterConfig.md b/docs/UpdaterConfig.md index 6b744794642..6c219d07ddf 100644 --- a/docs/UpdaterConfig.md +++ b/docs/UpdaterConfig.md @@ -165,56 +165,6 @@ HTTP headers to add to the request. Any header key, value can be inserted. -### TripUpdates via WebSocket - -This updater doesn't poll a data source but opens a persistent connection to the GTFS-RT provider, -which then sends incremental updates immediately as they become available. - -The [OneBusAway GTFS-realtime exporter project](https://github.com/OneBusAway/onebusaway-gtfs-realtime-exporter) -provides this kind of streaming, incremental updates over a websocket rather than a single large -file. - - - - -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|-----------------------------------------------------------------------|:---------:|--------------------------|:----------:|----------------------|:-----:| -| type = "websocket-gtfs-rt-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | -| [backwardsDelayPropagationType](#u__7__backwardsDelayPropagationType) | `enum` | TODO | *Optional* | `"required-no-data"` | 1.5 | -| feedId | `string` | TODO | *Required* | | 1.5 | -| reconnectPeriodSec | `integer` | TODO | *Optional* | `60` | 1.5 | -| url | `string` | TODO | *Optional* | | 1.5 | - - -##### Parameter details - -

    backwardsDelayPropagationType

    - -**Since version:** `1.5` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"required-no-data"` -**Path:** /updaters/[7] -**Enum values:** `required-no-data` | `required` | `always` - -TODO - - - -##### Example configuration - -```JSON -// router-config.json -{ - "updaters" : [ - { - "type" : "websocket-gtfs-rt-updater", - "feedId" : "ov" - } - ] -} -``` - - - - ### Vehicle Positions VehiclePositions give the location of some or all vehicles currently in service, in terms of diff --git a/docs/sandbox/SiriUpdater.md b/docs/sandbox/SiriUpdater.md index f6c4c3f999f..7730df67d12 100644 --- a/docs/sandbox/SiriUpdater.md +++ b/docs/sandbox/SiriUpdater.md @@ -37,16 +37,16 @@ To enable the SIRI updater you need to add it to the updaters section of the `ro | previewInterval | `duration` | TODO | *Optional* | | 2.0 | | requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | | timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | -| [url](#u__8__url) | `string` | The URL to send the HTTP requests to. | *Required* | | 2.0 | -| [headers](#u__8__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [url](#u__7__url) | `string` | The URL to send the HTTP requests to. | *Required* | | 2.0 | +| [headers](#u__7__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

    url

    +

    url

    **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[8] +**Path:** /updaters/[7] The URL to send the HTTP requests to. @@ -58,10 +58,10 @@ renamed by the loader when processed: -

    headers

    +

    headers

    **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[8] +**Path:** /updaters/[7] HTTP headers to add to the request. Any header key, value can be inserted. @@ -97,21 +97,21 @@ HTTP headers to add to the request. Any header key, value can be inserted. |---------------------------------|:---------------:|--------------------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| | type = "siri-sx-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | | blockReadinessUntilInitialized | `boolean` | Whether catching up with the updates should block the readiness check from returning a 'ready' result. | *Optional* | `false` | 2.0 | -| [earlyStart](#u__9__earlyStart) | `duration` | This value is subtracted from the actual validity defined in the message. | *Optional* | `"PT0S"` | 2.0 | +| [earlyStart](#u__8__earlyStart) | `duration` | This value is subtracted from the actual validity defined in the message. | *Optional* | `"PT0S"` | 2.0 | | feedId | `string` | The ID of the feed to apply the updates to. | *Required* | | 2.0 | | frequency | `duration` | How often the updates should be retrieved. | *Optional* | `"PT1M"` | 2.0 | | requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | | timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | -| [url](#u__9__url) | `string` | The URL to send the HTTP requests to. Supports http/https and file protocol. | *Required* | | 2.0 | -| [headers](#u__9__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [url](#u__8__url) | `string` | The URL to send the HTTP requests to. Supports http/https and file protocol. | *Required* | | 2.0 | +| [headers](#u__8__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

    earlyStart

    +

    earlyStart

    **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` -**Path:** /updaters/[9] +**Path:** /updaters/[8] This value is subtracted from the actual validity defined in the message. @@ -119,10 +119,10 @@ Normally the planned departure time is used, so setting this to 10s will cause t SX-message to be included in trip-results 10 seconds before the the planned departure time. -

    url

    +

    url

    **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[9] +**Path:** /updaters/[8] The URL to send the HTTP requests to. Supports http/https and file protocol. @@ -135,10 +135,10 @@ renamed by the loader when processed: -

    headers

    +

    headers

    **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[9] +**Path:** /updaters/[8] HTTP headers to add to the request. Any header key, value can be inserted. diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 69f859d784d..1a5eec22a28 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -295,11 +295,6 @@ "fuzzyTripMatching": false, "features": ["position"] }, - // Streaming differential GTFS-RT TripUpdates over websockets - { - "type": "websocket-gtfs-rt-updater", - "feedId": "ov" - }, // Siri-ET over HTTP { "type": "siri-et-updater", From 629ec1b0129bdfbd78f7467869a28ef13806250c Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 2 Jan 2024 17:56:47 +0100 Subject: [PATCH 030/356] feature: Filter away none optimal access/egress paths for multi-criteria Raptor --- .../transit/AccessEgressFunctions.java | 94 +++++++++++++++---- .../rangeraptor/transit/AccessPaths.java | 5 +- .../rangeraptor/transit/EgressPaths.java | 5 +- .../transit/AccessEgressFunctionsTest.java | 91 ++++++++++++++++-- .../rangeraptor/transit/EgressPathsTest.java | 11 +-- 5 files changed, 171 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java index 5059be84312..275a0f85cf3 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java @@ -5,12 +5,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.function.Predicate; import java.util.function.ToIntFunction; import java.util.stream.Collectors; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.util.paretoset.ParetoComparator; import org.opentripplanner.raptor.util.paretoset.ParetoSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class contains functions used by the {@link AccessPaths} and {@link EgressPaths} classes. @@ -23,6 +26,8 @@ */ public final class AccessEgressFunctions { + private static final Logger LOG = LoggerFactory.getLogger(AccessEgressFunctions.class); + /** * Filter standard(not multi-criteria) Raptor access and egress paths. A path is pareto optimal * for a given stop if @@ -47,32 +52,64 @@ public final class AccessEgressFunctions { * */ private static final ParetoComparator STANDARD_COMPARATOR = (l, r) -> - (l.stopReachedOnBoard() && !r.stopReachedOnBoard()) || - r.hasOpeningHours() || - (l.numberOfRides() < r.numberOfRides()) || - (l.durationInSeconds() < r.durationInSeconds()); + ( + l.stopReachedOnBoard() && + !r.stopReachedOnBoard() || + r.hasOpeningHours() || + l.numberOfRides() < r.numberOfRides() || + l.durationInSeconds() < r.durationInSeconds() + ); + + /** + * Filter Multi-criteria Raptor access and egress paths. This can be used to wash + * access/egress paths - paths that are not optimal using this should not be passed into + * Raptor - it is a bug. + */ + private static final ParetoComparator MC_COMPARATOR = (l, r) -> + ( + (l.stopReachedOnBoard() && !r.stopReachedOnBoard()) || + r.hasOpeningHours() || + l.numberOfRides() < r.numberOfRides() || + l.durationInSeconds() < r.durationInSeconds() || + l.c1() < r.c1() + ); /** private constructor to prevent instantiation of utils class. */ private AccessEgressFunctions() {} + /** + * Filter non-optimal paths away for the standard search. This method does not + * look at the c1 value. + */ static Collection removeNoneOptimalPathsForStandardRaptor( Collection paths ) { - // To avoid too many items in the pareto set we first group the paths by stop, - // for each stop we filter it down to the optimal pareto set. We could do this - // for multi-criteria as well, but it is likely not so important. The focus for - // the mc-set should be that the list of access/egress created in OTP should not - // contain to many non-optimal paths. - var mapByStop = groupByStop(paths); - var set = new ParetoSet<>(STANDARD_COMPARATOR); - Collection result = new ArrayList<>(); + return removeNoneOptimalPaths(paths, STANDARD_COMPARATOR); + } - mapByStop.forEachValue(list -> { - set.clear(); - set.addAll(list); - result.addAll(set); - return true; - }); + /** + * Filter non-optimal paths away for the multi-criteria search. This method should in theory + * not remove any paths since the caller should not pass in duplicates, but it turns out that + * this happens, so we do it. + */ + static Collection removeNoneOptimalPathsForMcRaptor( + Collection paths + ) { + var result = removeNoneOptimalPaths(paths, MC_COMPARATOR); + if (LOG.isDebugEnabled() && result.size() < paths.size()) { + var duplicates = new ArrayList<>(paths); + duplicates.removeAll(result); + // Note! This does not provide enough information to solve/debug this problem, but this is + // not a problem in Raptor, so we do not want to add more specific logging here - this does + // however document that the problem exist. Turn on debug logging and move the start/end + // coordinate around until you see this message. + // + // See https://github.com/opentripplanner/OpenTripPlanner/issues/5601 + LOG.warn( + "Duplicate access/egress paths passed into raptor:\n\t" + + duplicates.stream().map(Objects::toString).collect(Collectors.joining("\n\t")) + ); + } return result; } @@ -96,6 +133,27 @@ static TIntObjectMap> groupByStop(Collection removeNoneOptimalPaths( + Collection paths, + ParetoComparator comparator + ) { + var mapByStop = groupByStop(paths); + var set = new ParetoSet<>(comparator); + var result = new ArrayList(); + + for (int stop : mapByStop.keys()) { + var list = mapByStop.get(stop); + set.clear(); + set.addAll(list); + result.addAll(set); + } + return result; + } + private static List getOrCreate( int key, TIntObjectMap> map diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java index 940937f82db..dd757ac0415 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java @@ -1,6 +1,7 @@ package org.opentripplanner.raptor.rangeraptor.transit; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByRound; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForMcRaptor; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForStandardRaptor; import gnu.trove.map.TIntObjectMap; @@ -57,7 +58,9 @@ public int calculateMaxNumberOfRides() { * This method is static and package local to enable unit-testing. */ public static AccessPaths create(Collection paths, RaptorProfile profile) { - if (!profile.is(RaptorProfile.MULTI_CRITERIA)) { + if (profile.is(RaptorProfile.MULTI_CRITERIA)) { + paths = removeNoneOptimalPathsForMcRaptor(paths); + } else { paths = removeNoneOptimalPathsForStandardRaptor(paths); } return new AccessPaths( diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java index 2038ab543df..a1688ff8f5b 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java @@ -2,6 +2,7 @@ import static org.opentripplanner.raptor.api.request.RaptorProfile.MULTI_CRITERIA; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByStop; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForMcRaptor; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForStandardRaptor; import gnu.trove.map.TIntObjectMap; @@ -31,7 +32,9 @@ private EgressPaths(TIntObjectMap> pathsByStop) { * This method is static and package local to enable unit-testing. */ public static EgressPaths create(Collection paths, RaptorProfile profile) { - if (!MULTI_CRITERIA.is(profile)) { + if (MULTI_CRITERIA.is(profile)) { + paths = removeNoneOptimalPathsForMcRaptor(paths); + } else { paths = removeNoneOptimalPathsForStandardRaptor(paths); } return new EgressPaths(groupByStop(paths)); diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java b/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java index eab9ee418cf..041d74786d7 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java +++ b/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java @@ -6,6 +6,7 @@ import static org.opentripplanner.raptor._data.transit.TestAccessEgress.flexAndWalk; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByRound; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByStop; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForMcRaptor; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForStandardRaptor; import java.util.Arrays; @@ -24,19 +25,26 @@ class AccessEgressFunctionsTest implements RaptorTestConstants { public static final int TRANSFER_SLACK = D1m; private static final int STOP = 8; - - private static final RaptorAccessEgress WALK_10m = TestAccessEgress.walk(STOP, D10m); - private static final RaptorAccessEgress WALK_8m = TestAccessEgress.walk(STOP, D8m); - private static final RaptorAccessEgress FLEX_1x_10m = flex(STOP, D10m, 1); - private static final RaptorAccessEgress FLEX_1x_8m = flex(STOP, D8m, 1); - private static final RaptorAccessEgress FLEX_2x_8m = flex(STOP, D8m, 2); - private static final RaptorAccessEgress FLEX_AND_WALK_1x_8m = flexAndWalk(STOP, D8m, 1); + private static final int C1 = 1000; + private static final int C1_LOW = 999; + + private static final RaptorAccessEgress WALK_10m = TestAccessEgress.walk(STOP, D10m, C1); + private static final RaptorAccessEgress WALK_10m_C1_LOW = TestAccessEgress.walk( + STOP, + D10m, + C1_LOW + ); + private static final RaptorAccessEgress WALK_8m = TestAccessEgress.walk(STOP, D8m, C1); + private static final RaptorAccessEgress FLEX_1x_10m = flex(STOP, D10m, 1, C1); + private static final RaptorAccessEgress FLEX_1x_8m = flex(STOP, D8m, 1, C1); + private static final RaptorAccessEgress FLEX_2x_8m = flex(STOP, D8m, 2, C1); + private static final RaptorAccessEgress FLEX_AND_WALK_1x_8m = flexAndWalk(STOP, D8m, 1, C1); private static final RaptorAccessEgress WALK_W_OPENING_HOURS_8m = TestAccessEgress - .walk(STOP, D8m) + .walk(STOP, D8m, C1) .openingHours(T00_00, T01_00); private static final RaptorAccessEgress WALK_W_OPENING_HOURS_8m_OTHER = TestAccessEgress - .walk(STOP, D8m) + .walk(STOP, D8m, C1) .openingHours(T00_10, T01_00); @Test @@ -101,6 +109,71 @@ void removeNoneOptimalPathsForStandardRaptorTest() { ); } + @Test + void removeNoneOptimalPathsForMcRaptorTest() { + // Empty set + assertElements(List.of(), removeNoneOptimalPathsForMcRaptor(List.of())); + + // One element + assertElements(List.of(WALK_8m), removeNoneOptimalPathsForMcRaptor(List.of(WALK_8m))); + + // Lowest cost + assertElements( + List.of(WALK_10m_C1_LOW), + removeNoneOptimalPathsForMcRaptor(List.of(WALK_10m, WALK_10m_C1_LOW)) + ); + + // Shortest duration + assertElements(List.of(WALK_8m), removeNoneOptimalPathsForMcRaptor(List.of(WALK_8m, WALK_10m))); + + // Fewest rides + assertElements( + List.of(FLEX_1x_8m), + removeNoneOptimalPathsForMcRaptor(List.of(FLEX_1x_8m, FLEX_2x_8m)) + ); + + // Arriving at the stop on-board, and by-foot. + // OnBoard is better because we can do a transfer walk to nearby stops. + assertElements( + List.of(FLEX_1x_8m), + removeNoneOptimalPathsForMcRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_8m)) + ); + + // Flex+walk is faster, flex arrive on-board, both is optimal + assertElements( + List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m), + removeNoneOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m)) + ); + + // Walk has few rides, and Flex is faster - both is optimal + assertElements( + List.of(WALK_10m, FLEX_1x_8m), + removeNoneOptimalPathsForMcRaptor(List.of(WALK_10m, FLEX_1x_8m)) + ); + + // Walk without opening hours is better than with, because it can be time-shifted without + // any constraints + assertElements( + List.of(WALK_8m), + removeNoneOptimalPathsForMcRaptor(List.of(WALK_8m, WALK_W_OPENING_HOURS_8m)) + ); + + // Walk with opening hours can NOT dominate another access/egress without - even if it is + // faster. The reason is that it may not be allowed to time-shift it to the desired time. + assertElements( + List.of(WALK_10m, WALK_W_OPENING_HOURS_8m), + removeNoneOptimalPathsForMcRaptor(List.of(WALK_10m, WALK_W_OPENING_HOURS_8m)) + ); + + // If two paths both have opening hours, both should be accepted. + assertElements( + List.of(WALK_W_OPENING_HOURS_8m, WALK_W_OPENING_HOURS_8m_OTHER), + removeNoneOptimalPathsForMcRaptor( + List.of(WALK_W_OPENING_HOURS_8m, WALK_W_OPENING_HOURS_8m_OTHER) + ) + ); + } + @Test void groupByRoundTest() { // Map one element diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java b/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java index 6d3b25c1d31..144904fa3e6 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java +++ b/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPathsTest.java @@ -38,7 +38,7 @@ class EgressPathsTest { // Number of rides, smallest is better flex(STOP_D, D1m, 2), flex(STOP_D, D1m, 3), - // Opening Hours dominate each other(no check on overlapping) + // Opening Hours dominate each other (no check on overlapping) walk(STOP_E, D2m), walk(STOP_E, D1m).openingHours("10:00", "11:45"), walk(STOP_E, D1m).openingHours("11:30", "12:30"), @@ -83,18 +83,15 @@ void listAll() { """.strip(), subjectStd.listAll().stream().map(Object::toString).sorted().collect(Collectors.joining("\n")) ); + assertEquals( """ Flex 1m C₁120 1x ~ 3 Flex 1m C₁120 1x ~ 4 Flex 1m C₁120 2x ~ 5 - Flex 1m C₁120 3x ~ 5 - Flex 2m C₁240 1x ~ 3 - Flex+Walk 1m C₁120 1x ~ 4 Walk 1m C₁120 Open(10:00 11:45) ~ 6 Walk 1m C₁120 Open(11:30 12:30) ~ 6 Walk 1m C₁120 ~ 2 - Walk 2m C₁240 Open(14:00 14:00) ~ 6 Walk 2m C₁240 ~ 6 """.strip(), subjectMc.listAll().stream().map(Object::toString).sorted().collect(Collectors.joining("\n")) @@ -107,8 +104,10 @@ void walkToDestinationEgressStops() { toString(new int[] { STOP_A, STOP_E }), toString(subjectStd.egressesWitchStartByWalking()) ); + + //[2, 6] assertEquals( - toString(new int[] { STOP_A, STOP_C, STOP_E }), + toString(new int[] { STOP_A, STOP_E }), toString(subjectMc.egressesWitchStartByWalking()) ); } From 17d20c9d41a3d6345549c5fd8416fbdcd21d948e Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 3 Jan 2024 16:08:30 +0100 Subject: [PATCH 031/356] feature: Enable Raptor debug logging by event type --- .../transit/mappers/RaptorRequestMapper.java | 21 ++++++++++++++++--- .../routing/api/request/DebugEventType.java | 11 ++++++++++ .../routing/api/request/DebugRaptor.java | 19 ++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java index 75c1bcf7214..e63546a87a2 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java @@ -13,6 +13,7 @@ import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RelaxFunction; +import org.opentripplanner.raptor.api.request.DebugRequestBuilder; import org.opentripplanner.raptor.api.request.Optimization; import org.opentripplanner.raptor.api.request.PassThroughPoint; import org.opentripplanner.raptor.api.request.RaptorRequest; @@ -22,6 +23,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter; import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority.TransitPriorityGroup32n; +import org.opentripplanner.routing.api.request.DebugEventType; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.transit.model.site.StopLocation; @@ -156,10 +158,11 @@ private RaptorRequest doMap() { .addStops(raptorDebugging.stops()) .setPath(raptorDebugging.path()) .debugPathFromStopIndex(raptorDebugging.debugPathFromStopIndex()) - .stopArrivalListener(debugLogger::stopArrivalLister) - .patternRideDebugListener(debugLogger::patternRideLister) - .pathFilteringListener(debugLogger::pathFilteringListener) .logger(debugLogger); + + for (var type : raptorDebugging.eventTypes()) { + addLogListenerForEachEventTypeRequested(debug, type, debugLogger); + } } if (!request.timetableView() && request.arriveBy()) { @@ -209,4 +212,16 @@ private int relativeTime(Instant time) { } return (int) (time.getEpochSecond() - transitSearchTimeZeroEpocSecond); } + + private static void addLogListenerForEachEventTypeRequested( + DebugRequestBuilder target, + DebugEventType type, + SystemErrDebugLogger logger + ) { + switch (type) { + case STOP_ARRIVALS -> target.stopArrivalListener(logger::stopArrivalLister); + case PATTERN_RIDES -> target.patternRideDebugListener(logger::patternRideLister); + case DESTINATION_ARRIVALS -> target.pathFilteringListener(logger::pathFilteringListener); + } + } } diff --git a/src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java b/src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java new file mode 100644 index 00000000000..09f9dbbe732 --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/api/request/DebugEventType.java @@ -0,0 +1,11 @@ +package org.opentripplanner.routing.api.request; + +/** + * Raptor check paths in 3 different places. The debugger can print events + * for each of these. + */ +public enum DebugEventType { + STOP_ARRIVALS, + PATTERN_RIDES, + DESTINATION_ARRIVALS, +} diff --git a/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java b/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java index 7d6c1472eee..0b9ff4f0c30 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java +++ b/src/main/java/org/opentripplanner/routing/api/request/DebugRaptor.java @@ -3,7 +3,11 @@ import java.io.Serial; import java.io.Serializable; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; import java.util.List; +import java.util.Set; import java.util.regex.Pattern; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.slf4j.Logger; @@ -46,14 +50,16 @@ public class DebugRaptor implements Serializable { private List stops = List.of(); private List path = List.of(); private int debugPathFromStopIndex = 0; + private Set eventTypes = EnumSet.noneOf(DebugEventType.class); public DebugRaptor() {} - /** Avoid using clone(), use copy-constructor instead(Josh Bloch). */ + /** Avoid using clone(), use copy-constructor instead (Josh Bloch). */ public DebugRaptor(DebugRaptor other) { this.stops = List.copyOf(other.stops); this.path = List.copyOf(other.path); this.debugPathFromStopIndex = other.debugPathFromStopIndex; + this.eventTypes = EnumSet.copyOf(other.eventTypes); } public boolean isEnabled() { @@ -90,12 +96,23 @@ public int debugPathFromStopIndex() { return debugPathFromStopIndex; } + public Set eventTypes() { + return Collections.unmodifiableSet(eventTypes); + } + + public DebugRaptor withEventTypes(Collection eventTypes) { + this.eventTypes.clear(); + this.eventTypes.addAll(eventTypes); + return this; + } + @Override public String toString() { return ToStringBuilder .of(DebugRaptor.class) .addObj("stops", toString(stops, FIRST_STOP_INDEX)) .addObj("path", toString(path, debugPathFromStopIndex)) + .addCol("eventType", eventTypes) .toString(); } From a3e426fce2e9f35e062a5d0e5c705f5113f95af2 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 3 Jan 2024 19:21:07 +0100 Subject: [PATCH 032/356] sandbox: Extract log config and rearrange OTP Startup View --- .../InteractiveOtpMain.java | 19 ++- .../ext/interactivelauncher/Model.java | 55 ++++---- .../OtpDebugController.java | 35 +++++ .../ext/interactivelauncher/SetupResult.java | 99 ------------- .../{ => logging}/DebugLoggingSupport.java | 33 ++--- .../interactivelauncher/logging/LogModel.java | 56 ++++++++ .../interactivelauncher/logging/LogView.java | 34 +++++ .../logging/OTPDebugLoggers.java | 19 +++ .../DataSourceRootView.java} | 17 ++- .../startup/DataSourcesView.java | 133 ++++++++++++++++++ .../{views => startup}/MainView.java | 127 +++++------------ .../{views => startup}/OptionsView.java | 64 ++++----- .../StartOtpButtonView.java | 4 +- .../startup/StatusBar.java | 15 ++ .../{ => support}/SearchForOtpConfig.java | 10 +- .../{views => support}/ViewUtils.java | 23 +-- .../views/DataSourcesView.java | 84 ----------- .../interactivelauncher/views/StatusBar.java | 15 -- 18 files changed, 434 insertions(+), 408 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java delete mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/SetupResult.java rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => logging}/DebugLoggingSupport.java (61%) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{views/SearchDirectoryView.java => startup/DataSourceRootView.java} (80%) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{views => startup}/MainView.java (55%) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{views => startup}/OptionsView.java (63%) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{views => startup}/StartOtpButtonView.java (82%) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => support}/SearchForOtpConfig.java (85%) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{views => support}/ViewUtils.java (53%) delete mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/views/DataSourcesView.java delete mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StatusBar.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java index 1f9227b3be6..d61ae6bfcd3 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java @@ -1,19 +1,18 @@ package org.opentripplanner.ext.interactivelauncher; -import static org.opentripplanner.ext.interactivelauncher.DebugLoggingSupport.configureDebugLogging; - -import org.opentripplanner.ext.interactivelauncher.views.MainView; +import org.opentripplanner.ext.interactivelauncher.startup.MainView; import org.opentripplanner.standalone.OTPMain; /** - * This class provide a main method to start a GUI which can start OTPMain. + * This class provides a main method to start a GUI which can start OTPMain. *

    - * The UI allow the user to select a OTP configuration data set. The list of data location is - * created by searching the a root data source directory. + * The UI allows the user to select the OTP configuration dataset. The list of data locations is + * created by searching the root data source directory. *

    - * The user then select what he/she want OTP to do. The settings are stored in the - * .interactive_otp_main.json file in the folder InteractiveOtpMain is started. The - * settings from the last run is loaded next time InteractiveOtpMain is started. + * The user then selects what he/she wants OTP to do. + * The settings are stored in the + * .interactive_otp_main.json file in the folder InteractiveOtpMain is started. + * The settings from the last run are loaded the next time InteractiveOtpMain is started. */ public class InteractiveOtpMain { @@ -32,7 +31,7 @@ private void run() { private void startOtp() { model.save(); - configureDebugLogging(model.getDebugLogging()); + new OtpDebugController(model).start(); System.out.println("Start OTP: " + model + "\n"); OTPMain.main(model.asOtpArgs()); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java index ee2dde3e684..1550f8bc1ab 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java @@ -6,11 +6,10 @@ import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.function.Consumer; +import org.opentripplanner.ext.interactivelauncher.logging.LogModel; +import org.opentripplanner.ext.interactivelauncher.support.SearchForOtpConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,8 +19,6 @@ public class Model implements Serializable { private static final File MODEL_FILE = new File("interactive_otp_main.json"); - private final Map debugLogging = new HashMap<>(); - @JsonIgnore private transient Consumer commandLineChange; @@ -32,13 +29,16 @@ public class Model implements Serializable { private boolean saveGraph = false; private boolean serveGraph = true; private boolean visualizer = false; + private LogModel logModel; - public Model() { - setupListOfDebugLoggers(); - } + public Model() {} public static Model load() { - return MODEL_FILE.exists() ? readFromFile() : new Model(); + var model = MODEL_FILE.exists() ? readFromFile() : createNew(); + // Setup callbacks + model.logModel.init(model::save); + + return model; } public void subscribeCmdLineUpdates(Consumer commandLineChange) { @@ -134,19 +134,6 @@ public void setVisualizer(boolean visualizer) { notifyChangeListener(); } - public Map getDebugLogging() { - return debugLogging; - } - - public void setDebugLogging(Map map) { - for (Entry e : map.entrySet()) { - // Only keep entries that exist in the log config - if (debugLogging.containsKey(e.getKey())) { - debugLogging.put(e.getKey(), e.getValue()); - } - } - } - @Override public String toString() { return ( @@ -174,6 +161,10 @@ public void save() { } } + public LogModel getLogModel() { + return logModel; + } + @JsonIgnore String getDataSourceDirectory() { if (dataSource == null) { @@ -210,16 +201,26 @@ String[] asOtpArgs() { return args.toArray(new String[0]); } + private static Model createNew() { + var model = new Model(); + model.logModel = new LogModel(); + model.logModel.initFromConfig(); + model.setupCallbacks(); + return model; + } + private static Model readFromFile() { try { - return new ObjectMapper().readValue(MODEL_FILE, Model.class); + var model = new ObjectMapper().readValue(MODEL_FILE, Model.class); + model.setupCallbacks(); + return model; } catch (IOException e) { System.err.println( "Unable to read the InteractiveOtpMain state cache. If the model changed this " + "is expected, and it will work next time. Cause: " + e.getMessage() ); - return new Model(); + return createNew(); } } @@ -237,9 +238,7 @@ private boolean buildStreetOnly() { return buildStreet && !buildTransit; } - private void setupListOfDebugLoggers() { - for (String log : DebugLoggingSupport.getLogs()) { - debugLogging.put(log, Boolean.FALSE); - } + private void setupCallbacks() { + logModel.init(this::save); } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java new file mode 100644 index 00000000000..95635c5bb0c --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java @@ -0,0 +1,35 @@ +package org.opentripplanner.ext.interactivelauncher; + +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BACKGROUND; + +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import org.opentripplanner.ext.interactivelauncher.logging.LogModel; +import org.opentripplanner.ext.interactivelauncher.logging.LogView; + +public class OtpDebugController { + + private final JFrame debugFrame = new JFrame("OTP Debug Controller"); + + public OtpDebugController(Model model) { + var tabPanel = new JTabbedPane(); + tabPanel.addTab("Logging", createLogPanel(model.getLogModel())); + tabPanel.addTab("Raptor", new JPanel()); + debugFrame.add(tabPanel); + debugFrame.getContentPane().setBackground(BACKGROUND); + start(); + } + + private static JComponent createLogPanel(LogModel logModel) { + return new LogView(logModel).panel(); + } + + public void start() { + debugFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + debugFrame.pack(); + debugFrame.setLocationRelativeTo(null); + debugFrame.setVisible(true); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/SetupResult.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/SetupResult.java deleted file mode 100644 index a6ecf5e7229..00000000000 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/SetupResult.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.opentripplanner.ext.interactivelauncher; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -public class SetupResult { - - private final File configDataDir; - private final boolean buildStreet; - private final boolean buildTransit; - private final boolean saveGraph; - private final boolean serveGraph; - - public SetupResult( - File configDataDir, - boolean buildStreet, - boolean buildTransit, - boolean saveGraph, - boolean serveGraph - ) { - this.configDataDir = configDataDir; - this.buildStreet = buildStreet; - this.buildTransit = buildTransit; - this.saveGraph = saveGraph; - this.serveGraph = serveGraph; - } - - @Override - public String toString() { - return ( - "SetupResult{" + - "configDataDir=" + - configDataDir.getAbsolutePath() + - (buildStreet ? ", buildStreet" : "") + - (buildTransit ? ", buildTransit" : "") + - (saveGraph ? ", saveGraph" : "") + - (serveGraph ? ", serveGraph" : "") + - '}' - ); - } - - public String toCliString() { - return String.join(" ", asOtpArgs()); - } - - File configDataDir() { - return configDataDir; - } - - boolean buildStreet() { - return buildStreet; - } - - boolean buildTransit() { - return buildTransit; - } - - boolean buildAll() { - return buildStreet && buildTransit; - } - - boolean buildStreetOnly() { - return buildStreet && !buildTransit; - } - - boolean saveGraph() { - return saveGraph; - } - - boolean serveGraph() { - return serveGraph; - } - - String[] asOtpArgs() { - List args = new ArrayList<>(); - - if (buildAll()) { - args.add("--build"); - } else if (buildStreet) { - args.add("--buildStreet"); - } else if (buildTransit) { - args.add("--loadStreet"); - } else { - args.add("--load"); - } - - if (saveGraph && (buildTransit || buildStreet)) { - args.add("--save"); - } - if (serveGraph && !buildStreetOnly()) { - args.add("--serve"); - } - - args.add(configDataDir.getAbsolutePath()); - - return args.toArray(new String[0]); - } -} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/DebugLoggingSupport.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/DebugLoggingSupport.java similarity index 61% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/DebugLoggingSupport.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/DebugLoggingSupport.java index e0b07a8c79e..fcfa323680f 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/DebugLoggingSupport.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/DebugLoggingSupport.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.interactivelauncher; +package org.opentripplanner.ext.interactivelauncher.logging; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; @@ -10,13 +10,13 @@ import org.slf4j.LoggerFactory; /** - * Responsible for integration with the OTP Debug log configuraton, reading loggers from the slf4j + * Responsible for integration with the OTP Debug log configuration, reading loggers from the slf4j * context and setting DEBUG level on selected loggers back. *

    - * The log names are transformed to be more human readable: + * The log names are transformed to be more human-readable: *

    org.opentripplanner.routing.algorithm  -->  o.o.routing.algorithm
    */ -public class DebugLoggingSupport { +class DebugLoggingSupport { private static final String OTP = Pattern.quote("org.opentripplanner.") + ".*"; private static final String GRAPHQL = Pattern.quote("fea"); @@ -26,29 +26,26 @@ public class DebugLoggingSupport { "(" + OTP + "|" + GRAPHQL + "|" + NAMED_LOGGERS + ")" ); - public static List getLogs() { + static List getDebugLoggers() { List result = new ArrayList<>(); LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); for (Logger log : context.getLoggerList()) { var name = log.getName(); - if (!name.equals("ROOT") && LOG_MATCHER_PATTERN.matcher(name).matches()) { - result.add(logDisplayName(name)); + if (name.equals("ROOT") || log.getLevel() == null) { + continue; + } + if (log.getLevel().toInt() <= Level.DEBUG.toInt()) { + if (LOG_MATCHER_PATTERN.matcher(name).matches()) { + result.add(name); + } } } return result; } - public static void configureDebugLogging(Map loggers) { + static void configureDebugLogging(String logger, boolean debug) { LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); - for (Logger log : context.getLoggerList()) { - var name = logDisplayName(log.getName()); - if (loggers.getOrDefault(name, false)) { - log.setLevel(Level.DEBUG); - } - } - } - - private static String logDisplayName(String name) { - return name.replace("org.opentripplanner.", "o.o."); + var log = context.getLogger(logger); + log.setLevel(debug ? Level.DEBUG : Level.INFO); } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java new file mode 100644 index 00000000000..536c8d1dc87 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java @@ -0,0 +1,56 @@ +package org.opentripplanner.ext.interactivelauncher.logging; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.io.Serializable; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Responsible for storing the selected loggers to debug. This is + * serialized to store the user preferences between runs. + */ +public class LogModel implements Serializable { + + private final Set activeLoggers = new HashSet<>(); + + @JsonIgnore + private Runnable saveCallback; + + public LogModel() {} + + /** Need to set this manually to support JSON serialization. */ + public void init(Runnable saveCallback) { + this.saveCallback = saveCallback; + } + + /** Needed to do JSON serialization. */ + public Collection getActiveLoggers() { + return List.copyOf(activeLoggers); + } + + /** Needed to do JSON serialization. */ + public void setActiveLoggers(Collection loggers) { + this.activeLoggers.clear(); + this.activeLoggers.addAll(loggers); + } + + public void initFromConfig() { + activeLoggers.addAll(DebugLoggingSupport.getDebugLoggers()); + } + + boolean isLoggerEnabled(String name) { + return activeLoggers.contains(name); + } + + void turnLoggerOnOff(String name, boolean enable) { + if (enable) { + activeLoggers.add(name); + } else { + activeLoggers.remove(name); + } + DebugLoggingSupport.configureDebugLogging(name, enable); + saveCallback.run(); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java new file mode 100644 index 00000000000..a71f90eb697 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java @@ -0,0 +1,34 @@ +package org.opentripplanner.ext.interactivelauncher.logging; + +import javax.swing.Box; +import javax.swing.JCheckBox; +import javax.swing.JComponent; + +/** + * Display a list of loggers to turn on/off. + */ +public class LogView { + + private final Box panel = Box.createVerticalBox(); + private final LogModel model; + + public LogView(LogModel model) { + this.model = model; + OTPDebugLoggers.list().forEach(this::add); + } + + public JComponent panel() { + return panel; + } + + private void add(OTPDebugLoggers logger) { + var box = new JCheckBox(logger.label()); + box.setSelected(model.isLoggerEnabled(logger.logger())); + box.addActionListener(e -> selectLogger(logger.logger(), box.isSelected())); + panel.add(box); + } + + private void selectLogger(String logger, boolean selected) { + model.turnLoggerOnOff(logger, selected); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java new file mode 100644 index 00000000000..4663b6017de --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java @@ -0,0 +1,19 @@ +package org.opentripplanner.ext.interactivelauncher.logging; + +import java.util.List; + +record OTPDebugLoggers(String label, String logger) { + static List list() { + return List.of( + of("Data import issues", "DATA_IMPORT_ISSUES"), + of("All OTP debuggers", "org.opentripplanner"), + of("OTP request/response", "org.opentripplanner.routing.service.DefaultRoutingService"), + of("Raptor request/response", "org.opentripplanner.raptor.RaptorService"), + of("Transfer Optimization", "org.opentripplanner.routing.algorithm.transferoptimization") + ); + } + + private static OTPDebugLoggers of(String label, String logger) { + return new OTPDebugLoggers(label, logger); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/SearchDirectoryView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java similarity index 80% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/views/SearchDirectoryView.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java index ef054e2c879..e5ba9136e9d 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/SearchDirectoryView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourceRootView.java @@ -1,7 +1,7 @@ -package org.opentripplanner.ext.interactivelauncher.views; +package org.opentripplanner.ext.interactivelauncher.startup; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.BG_STATUS_BAR; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.FG_STATUS_BAR; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BG_STATUS_BAR; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.FG_STATUS_BAR; import java.awt.Component; import java.awt.Dimension; @@ -9,18 +9,20 @@ import java.util.function.Consumer; import javax.swing.Box; import javax.swing.JButton; +import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JTextField; +import org.opentripplanner.ext.interactivelauncher.support.ViewUtils; -public class SearchDirectoryView { +class DataSourceRootView { private final Box panel; private final JTextField fileTxt = new JTextField(); private final JButton searchBtn = new JButton("Open"); private final Consumer rootDirChangedListener; - public SearchDirectoryView(String dir, Consumer rootDirChangedListener) { + DataSourceRootView(String dir, Consumer rootDirChangedListener) { this.fileTxt.setText(dir); this.rootDirChangedListener = rootDirChangedListener; @@ -35,9 +37,6 @@ public SearchDirectoryView(String dir, Consumer rootDirChangedListener) fileTxt.setEditable(false); fileTxt.setBackground(BG_STATUS_BAR); fileTxt.setForeground(FG_STATUS_BAR); - //var d = minWidth(fileTxt.getPreferredSize(), 460); - //fileTxt.setMinimumSize(d); - //fileTxt.setPreferredSize(d); // Add text field and open button Box box = Box.createHorizontalBox(); @@ -48,7 +47,7 @@ public SearchDirectoryView(String dir, Consumer rootDirChangedListener) panel.add(box); } - public Box panel() { + public JComponent panel() { return panel; } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java new file mode 100644 index 00000000000..07052b9cd29 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java @@ -0,0 +1,133 @@ +package org.opentripplanner.ext.interactivelauncher.startup; + +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addComp; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addHorizontalGlue; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addVerticalSectionSpace; + +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.util.List; +import javax.swing.Box; +import javax.swing.ButtonGroup; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JRadioButton; +import org.opentripplanner.ext.interactivelauncher.Model; +import org.opentripplanner.ext.interactivelauncher.support.ViewUtils; + +class DataSourcesView { + + /* + |-----------------------------------------------| + | Label | + |-----------------------------------------------| + | ( ) List 1 | ( ) List 2 | ( ) List 3 | + | ( ) List 1 | ( ) List 2 | ( ) List 3 | + |-----------------------------------------------| + */ + + private final Box mainPanel = Box.createVerticalBox(); + private final Box listPanel = Box.createHorizontalBox(); + private final Model model; + + public DataSourcesView(Model model) { + this.model = model; + setupDataSources(); + + JLabel label = new JLabel("Select data source"); + + listPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + + addComp(label, mainPanel); + addVerticalSectionSpace(mainPanel); + addComp(listPanel, mainPanel); + } + + public JComponent panel() { + return mainPanel; + } + + public void onRootDirChange() { + model.setDataSource(null); + listPanel.removeAll(); + setupDataSources(); + listPanel.repaint(); + } + + public void onDataSourceChange(ActionEvent e) { + model.setDataSource(e.getActionCommand()); + } + + private void setupDataSources() { + final List values = model.getDataSourceOptions(); + + if (values.isEmpty()) { + model.setDataSource(null); + JLabel label = new JLabel(""); + label.setBackground(ViewUtils.BG_STATUS_BAR); + label.setForeground(ViewUtils.FG_STATUS_BAR); + addComp(label, listPanel); + return; + } + + String selectedValue = model.getDataSource(); + + if (selectedValue == null) { + selectedValue = values.get(0); + model.setDataSource(selectedValue); + } + + ButtonGroup selectDataSourceRadioGroup = new ButtonGroup(); + + List valuesSorted = values.stream().sorted().toList(); + int size = valuesSorted.size(); + + // Split the list of configuration in one, two or three columns depending on the + // number of configurations found. + if (size <= 10) { + addListPanel(valuesSorted, selectedValue, selectDataSourceRadioGroup); + } else if (size <= 20) { + int half = size / 2; + addListPanel(valuesSorted.subList(0, half), selectedValue, selectDataSourceRadioGroup); + addHorizontalGlue(listPanel); + addListPanel(valuesSorted.subList(half, size), selectedValue, selectDataSourceRadioGroup); + } else { + int third = size / 3; + addListPanel(valuesSorted.subList(0, third), selectedValue, selectDataSourceRadioGroup); + addHorizontalGlue(listPanel); + addListPanel( + valuesSorted.subList(third, third * 2), + selectedValue, + selectDataSourceRadioGroup + ); + addHorizontalGlue(listPanel); + addListPanel( + valuesSorted.subList(third * 2, size), + selectedValue, + selectDataSourceRadioGroup + ); + } + } + + private void addListPanel( + List values, + String selectedValue, + ButtonGroup selectDataSourceRadioGroup + ) { + Box column = Box.createVerticalBox(); + + for (String name : values) { + boolean selected = selectedValue.equals(name); + JRadioButton radioBtn = newRadioBtn(selectDataSourceRadioGroup, name, selected); + radioBtn.addActionListener(this::onDataSourceChange); + addComp(radioBtn, column); + } + addComp(column, listPanel); + } + + private static JRadioButton newRadioBtn(ButtonGroup group, String name, boolean selected) { + JRadioButton radioButton = new JRadioButton(name, selected); + group.add(radioButton); + return radioButton; + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/MainView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java similarity index 55% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/views/MainView.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java index 44ede02e3eb..d147624aa61 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/MainView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java @@ -1,11 +1,10 @@ -package org.opentripplanner.ext.interactivelauncher.views; +package org.opentripplanner.ext.interactivelauncher.startup; import static java.awt.GridBagConstraints.BOTH; import static java.awt.GridBagConstraints.CENTER; -import static java.awt.GridBagConstraints.NONE; -import static java.awt.GridBagConstraints.NORTH; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.BACKGROUND; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.debugLayout; +import static java.awt.GridBagConstraints.HORIZONTAL; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BACKGROUND; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.debugLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -18,101 +17,32 @@ public class MainView { - /** Margins between components (IN) */ private static final int M_IN = 10; - - /** Margins around frame boarder (OUT) */ private static final int M_OUT = 2 * M_IN; + private static final Insets DEFAULT_INSETS = new Insets(M_OUT, M_OUT, M_IN, M_OUT); + private static final Insets SMALL_INSETS = new Insets(M_OUT, M_OUT, M_IN, M_OUT); + private static int Y = 0; /* - The application have the following 4 panels: + The application have the following panels: + +-----------------------------------+ + | Root dir [Open] | + +-----------------------------------+ + | Config Dirs Panel | + +-----------------------------------+ + | Options Panel | +-----------------------------------+ - | Root dir [Open] | - +-------------------+---------------+ - | | | - | Config Dirs Panel | Options Panel | - | | | - +-------------------+---------------+ - | Start OTP Main Panel | + | [ Start OTP ] | +-----------------------------------+ | Status Bar | +-----------------------------------+ */ - // Root dir view - private static final GridBagConstraints CONFIG_SOURCE_DIR_PANEL_CONSTRAINTS = new GridBagConstraints( - 0, - 0, - 2, - 1, - 1.0, - 0.0, - NORTH, - BOTH, - new Insets(M_OUT, M_OUT, M_IN, M_IN), - 0, - 0 - ); - - // List of locations - private static final GridBagConstraints CONFIG_DIRS_PANEL_CONSTRAINTS = new GridBagConstraints( - 0, - 1, - 1, - 1, - 1.0, - 1.0, - NORTH, - NONE, - new Insets(M_OUT, M_OUT, M_IN, M_IN), - 0, - 0 - ); - - // Options panel - private static final GridBagConstraints OPTIONS_PANEL_CONSTRAINTS = new GridBagConstraints( - 1, - 1, - 1, - 1, - 1.0, - 1.0, - NORTH, - NONE, - new Insets(M_OUT, M_IN, M_IN, M_OUT), - 0, - 0 - ); - - // Run btn and status - private static final GridBagConstraints START_OTP_BUTTON_PANEL_CONSTRAINTS = new GridBagConstraints( - 0, - 2, - 2, - 1, - 1.0, - 1.0, - CENTER, - BOTH, - new Insets(M_IN, M_OUT, M_IN, M_OUT), - 0, - 0 - ); - - // Run btn and status - private static final GridBagConstraints STATUS_BAR_CONSTRAINTS = new GridBagConstraints( - 0, - 3, - 2, - 1, - 1.0, - 0.0, - CENTER, - BOTH, - new Insets(M_IN, 0, 0, 0), - 40, - 0 - ); + private static final GridBagConstraints DATA_SOURCE_ROOT_PANEL_CONSTRAINTS = gbc(0f); + private static final GridBagConstraints DATA_SOURCE_LIST_PANEL_CONSTRAINTS = gbc(1f); + private static final GridBagConstraints OPTIONS_PANEL_CONSTRAINTS = gbc(1f); + private static final GridBagConstraints START_BUTTON_PANEL_CONSTRAINTS = gbc(0f); + private static final GridBagConstraints STATUS_BAR_CONSTRAINTS = gbc(0f, SMALL_INSETS, 40); private final JFrame mainFrame = new JFrame("Setup and Run OTP Main"); @@ -134,7 +64,7 @@ public MainView(Runnable otpStarter, Model model) throws HeadlessException { innerPanel.setLayout(layout); innerPanel.setBackground(BACKGROUND); - var sourceDirectoryView = new SearchDirectoryView( + var sourceDirectoryView = new DataSourceRootView( model.getRootDirectory(), this::onRootDirChanged ); @@ -142,16 +72,17 @@ public MainView(Runnable otpStarter, Model model) throws HeadlessException { this.optionsView = new OptionsView(model); this.startOtpButtonView = new StartOtpButtonView(); - innerPanel.add(sourceDirectoryView.panel(), CONFIG_SOURCE_DIR_PANEL_CONSTRAINTS); - innerPanel.add(dataSourcesView.panel(), CONFIG_DIRS_PANEL_CONSTRAINTS); + innerPanel.add(sourceDirectoryView.panel(), DATA_SOURCE_ROOT_PANEL_CONSTRAINTS); + innerPanel.add(dataSourcesView.panel(), DATA_SOURCE_LIST_PANEL_CONSTRAINTS); innerPanel.add(optionsView.panel(), OPTIONS_PANEL_CONSTRAINTS); - innerPanel.add(startOtpButtonView.panel(), START_OTP_BUTTON_PANEL_CONSTRAINTS); + innerPanel.add(startOtpButtonView.panel(), START_BUTTON_PANEL_CONSTRAINTS); innerPanel.add(statusBarTxt, STATUS_BAR_CONSTRAINTS); // Setup action listeners startOtpButtonView.addActionListener(e -> startOtp()); debugLayout( + sourceDirectoryView.panel(), dataSourcesView.panel(), optionsView.panel(), startOtpButtonView.panel(), @@ -186,4 +117,12 @@ private void startOtp() { mainFrame.dispose(); otpStarter.run(); } + + private static GridBagConstraints gbc(float weighty) { + return gbc(weighty, DEFAULT_INSETS, 0); + } + + private static GridBagConstraints gbc(float weighty, Insets insets, int ipadx) { + return new GridBagConstraints(0, Y++, 1, 1, 1.0, weighty, CENTER, HORIZONTAL, insets, ipadx, 0); + } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/OptionsView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java similarity index 63% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/views/OptionsView.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java index 08923f3af88..3d98bbf0cfc 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/OptionsView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java @@ -1,20 +1,18 @@ -package org.opentripplanner.ext.interactivelauncher.views; +package org.opentripplanner.ext.interactivelauncher.startup; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.addComp; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.addSectionDoubleSpace; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.addSectionSpace; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addComp; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addVerticalSectionSpace; -import java.util.List; import java.util.function.Consumer; -import java.util.stream.Collectors; import javax.swing.Box; import javax.swing.JCheckBox; +import javax.swing.JComponent; import javax.swing.JLabel; import org.opentripplanner.ext.interactivelauncher.Model; class OptionsView { - private final Box panel = Box.createVerticalBox(); + private final Box panel = Box.createHorizontalBox(); private final JCheckBox buildStreetGraphChk; private final JCheckBox buildTransitGraphChk; private final JCheckBox saveGraphChk; @@ -30,28 +28,41 @@ class OptionsView { this.startOptServerChk = new JCheckBox("Serve graph", model.isServeGraph()); this.startOptVisualizerChk = new JCheckBox("Visualizer", model.isVisualizer()); - addComp(new JLabel("Build graph"), panel); - addSectionSpace(panel); - addComp(buildStreetGraphChk, panel); - addComp(buildTransitGraphChk, panel); - addSectionDoubleSpace(panel); + panel.add(Box.createGlue()); + addComp(createBuildBox(), panel); + panel.add(Box.createGlue()); + addComp(createActionBox(), panel); + panel.add(Box.createGlue()); // Toggle [ ] save on/off buildStreetGraphChk.addActionListener(e -> onBuildGraphChkChanged()); buildTransitGraphChk.addActionListener(e -> onBuildGraphChkChanged()); startOptServerChk.addActionListener(e -> onStartOptServerChkChanged()); - addComp(new JLabel("Actions"), panel); - addSectionSpace(panel); - addComp(saveGraphChk, panel); - addComp(startOptServerChk, panel); - addComp(startOptVisualizerChk, panel); - - addDebugCheckBoxes(model); - addSectionDoubleSpace(panel); + //addSectionDoubleSpace(panel); bindCheckBoxesToModel(); } + private JComponent createBuildBox() { + var buildBox = Box.createVerticalBox(); + addComp(new JLabel("Build graph"), buildBox); + addVerticalSectionSpace(buildBox); + addComp(buildStreetGraphChk, buildBox); + addComp(buildTransitGraphChk, buildBox); + buildBox.add(Box.createVerticalGlue()); + return buildBox; + } + + private JComponent createActionBox() { + var actionBox = Box.createVerticalBox(); + addComp(new JLabel("Actions"), actionBox); + addVerticalSectionSpace(actionBox); + addComp(saveGraphChk, actionBox); + addComp(startOptServerChk, actionBox); + addComp(startOptVisualizerChk, actionBox); + return actionBox; + } + Box panel() { return panel; } @@ -64,19 +75,6 @@ void bind(JCheckBox box, Consumer modelUpdate) { box.addActionListener(l -> modelUpdate.accept(box.isSelected() && box.isEnabled())); } - private void addDebugCheckBoxes(Model model) { - addSectionSpace(panel); - addComp(new JLabel("Debug logging"), panel); - addSectionSpace(panel); - var entries = model.getDebugLogging(); - List keys = entries.keySet().stream().sorted().collect(Collectors.toList()); - for (String name : keys) { - JCheckBox box = new JCheckBox(name, entries.get(name)); - box.addActionListener(l -> model.getDebugLogging().put(name, box.isSelected())); - addComp(box, panel); - } - } - private void bindCheckBoxesToModel() { bind(buildStreetGraphChk, model::setBuildStreet); bind(buildTransitGraphChk, model::setBuildTransit); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StartOtpButtonView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java similarity index 82% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StartOtpButtonView.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java index 5c0c1e7a621..3050b7c5c62 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StartOtpButtonView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartOtpButtonView.java @@ -1,6 +1,6 @@ -package org.opentripplanner.ext.interactivelauncher.views; +package org.opentripplanner.ext.interactivelauncher.startup; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.adjustSize; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.adjustSize; import java.awt.event.ActionListener; import javax.swing.Box; diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java new file mode 100644 index 00000000000..f88c77c9f75 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StatusBar.java @@ -0,0 +1,15 @@ +package org.opentripplanner.ext.interactivelauncher.startup; + +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BG_STATUS_BAR; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.FG_STATUS_BAR; + +import javax.swing.JTextField; + +class StatusBar extends JTextField { + + public StatusBar() { + setEditable(false); + setBackground(BG_STATUS_BAR); + setForeground(FG_STATUS_BAR); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/SearchForOtpConfig.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java similarity index 85% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/SearchForOtpConfig.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java index ccf6be72e20..6b0574f0fdf 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/SearchForOtpConfig.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/SearchForOtpConfig.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.interactivelauncher; +package org.opentripplanner.ext.interactivelauncher.support; import java.io.File; import java.util.Arrays; @@ -10,17 +10,17 @@ /** * Search for directories containing OTP configuration files. The search is recursive and searches - * sub-directories 10 levels deep. + * subdirectories 10 levels deep. */ -class SearchForOtpConfig { +public class SearchForOtpConfig { private static final int DEPTH_LIMIT = 10; private static final Pattern EXCLUDE_DIR = Pattern.compile( "(otp1|archive|\\..*|te?mp|target|docs?|src|source|resource)" ); - static List search(File rootDir) { - return recursiveSearch(rootDir, DEPTH_LIMIT).collect(Collectors.toUnmodifiableList()); + public static List search(File rootDir) { + return recursiveSearch(rootDir, DEPTH_LIMIT).toList(); } @SuppressWarnings("ConstantConditions") diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/ViewUtils.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java similarity index 53% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/views/ViewUtils.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java index 14f6f589109..1e0c94fb588 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/ViewUtils.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java @@ -1,35 +1,36 @@ -package org.opentripplanner.ext.interactivelauncher.views; +package org.opentripplanner.ext.interactivelauncher.support; import java.awt.Color; +import java.awt.Container; import java.awt.Dimension; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JComponent; -final class ViewUtils { +public final class ViewUtils { private static final boolean DEBUG_LAYOUT = false; static final int SECTION_SPACE = 10; - static final Color BACKGROUND = new Color(0xe0, 0xf0, 0xff); - static final Color BG_STATUS_BAR = new Color(0xd0, 0xe0, 0xf0); - static final Color FG_STATUS_BAR = new Color(0, 0, 0x80); + public static final Color BACKGROUND = new Color(0xe0, 0xf0, 0xff); + public static final Color BG_STATUS_BAR = new Color(0xd0, 0xe0, 0xf0); + public static final Color FG_STATUS_BAR = new Color(0, 0, 0x80); - static void addSectionSpace(Box panel) { + public static void addVerticalSectionSpace(Box panel) { panel.add(Box.createVerticalStrut(SECTION_SPACE)); } - static void addSectionDoubleSpace(Box panel) { - panel.add(Box.createVerticalStrut(2 * SECTION_SPACE)); + public static void addHorizontalGlue(Box box) { + box.add(Box.createHorizontalGlue()); } - static void addComp(JComponent c, Box panel) { + public static void addComp(JComponent c, Container panel) { if (DEBUG_LAYOUT) { c.setBorder(BorderFactory.createLineBorder(Color.green)); } panel.add(c); } - static void debugLayout(JComponent... components) { + public static void debugLayout(JComponent... components) { if (DEBUG_LAYOUT) { for (JComponent c : components) { c.setBorder(BorderFactory.createLineBorder(Color.red)); @@ -37,7 +38,7 @@ static void debugLayout(JComponent... components) { } } - static void adjustSize(JComponent c, int dWidth, int dHeight) { + public static void adjustSize(JComponent c, int dWidth, int dHeight) { Dimension d0 = c.getPreferredSize(); Dimension d = new Dimension(d0.width + dWidth, d0.height + dHeight); c.setMinimumSize(d); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/DataSourcesView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/DataSourcesView.java deleted file mode 100644 index c7faa43779d..00000000000 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/DataSourcesView.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.opentripplanner.ext.interactivelauncher.views; - -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.addComp; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.addSectionDoubleSpace; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.addSectionSpace; - -import java.awt.event.ActionEvent; -import java.util.List; -import java.util.stream.Collectors; -import javax.swing.Box; -import javax.swing.ButtonGroup; -import javax.swing.JLabel; -import javax.swing.JRadioButton; -import org.opentripplanner.ext.interactivelauncher.Model; - -class DataSourcesView { - - private final Box panel = Box.createVerticalBox(); - private final Box dataSourceSelectionPanel = Box.createVerticalBox(); - private final Model model; - - public DataSourcesView(Model model) { - this.model = model; - - setupDataSources(); - - addComp(new JLabel("Select data source"), panel); - addSectionSpace(panel); - addComp(dataSourceSelectionPanel, panel); - addSectionDoubleSpace(panel); - } - - public Box panel() { - return panel; - } - - public void onRootDirChange() { - model.setDataSource(null); - dataSourceSelectionPanel.removeAll(); - setupDataSources(); - panel.repaint(); - } - - public void onDataSourceChange(ActionEvent e) { - model.setDataSource(e.getActionCommand()); - } - - private static JRadioButton newRadioBtn(ButtonGroup group, String name, boolean selected) { - JRadioButton radioButton = new JRadioButton(name, selected); - group.add(radioButton); - return radioButton; - } - - private void setupDataSources() { - final List values = model.getDataSourceOptions(); - - if (values.isEmpty()) { - model.setDataSource(null); - JLabel label = new JLabel(""); - label.setBackground(ViewUtils.BG_STATUS_BAR); - label.setForeground(ViewUtils.FG_STATUS_BAR); - addComp(label, dataSourceSelectionPanel); - return; - } - - String selectedValue = model.getDataSource(); - - if (selectedValue == null) { - selectedValue = values.get(0); - model.setDataSource(selectedValue); - } - - ButtonGroup selectDataSourceRadioGroup = new ButtonGroup(); - - List valuesSorted = values.stream().sorted().collect(Collectors.toList()); - - for (String name : valuesSorted) { - boolean selected = selectedValue.equals(name); - JRadioButton radioBtn = newRadioBtn(selectDataSourceRadioGroup, name, selected); - radioBtn.addActionListener(this::onDataSourceChange); - addComp(radioBtn, dataSourceSelectionPanel); - } - } -} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StatusBar.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StatusBar.java deleted file mode 100644 index faffa9d87d2..00000000000 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/views/StatusBar.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.opentripplanner.ext.interactivelauncher.views; - -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.BG_STATUS_BAR; -import static org.opentripplanner.ext.interactivelauncher.views.ViewUtils.FG_STATUS_BAR; - -import javax.swing.JTextField; - -public class StatusBar extends JTextField { - - public StatusBar() { - setEditable(false); - setBackground(BG_STATUS_BAR); - setForeground(FG_STATUS_BAR); - } -} From cb10208be9e800d93bb2b8c1621698d12740cc3e Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 01:38:18 +0100 Subject: [PATCH 033/356] refactor: Extend the main code, so the interactive launcher can intercept the request. --- .../api/LauncherRequestDecorator.java | 15 ++++++++++++++ .../InteractiveLauncherModule.java | 20 +++++++++++++++++++ .../ConstructApplicationFactory.java | 2 ++ .../configure/ConstructApplicationModule.java | 8 ++++++-- 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java new file mode 100644 index 00000000000..99c28bad260 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/api/LauncherRequestDecorator.java @@ -0,0 +1,15 @@ +package org.opentripplanner.ext.interactivelauncher.api; + +import org.opentripplanner.routing.api.request.RouteRequest; + +/** + * Allow the interactive launcher intercept planing requests. + */ +public interface LauncherRequestDecorator { + /** + * The launcher may use this method to change the default plan request. Note! It is the DEFAULT + * request witch is passed in here, then the request-specific values are applied on top + * of that. + */ + RouteRequest intercept(RouteRequest defaultRequest); +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java new file mode 100644 index 00000000000..2df46b74127 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java @@ -0,0 +1,20 @@ +package org.opentripplanner.ext.interactivelauncher.configuration; + +import dagger.Module; +import dagger.Provides; +import org.opentripplanner.ext.interactivelauncher.api.LauncherRequestDecorator; + +@Module +public class InteractiveLauncherModule { + + static LauncherRequestDecorator decorator = request -> request; + + static void enable(LauncherRequestDecorator decorator) { + InteractiveLauncherModule.decorator = decorator; + } + + @Provides + LauncherRequestDecorator requestDecorator() { + return decorator; + } +} diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java index 097fcfb4f7a..a4f0ee49652 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java +++ b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationFactory.java @@ -6,6 +6,7 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.emissions.EmissionsDataModel; import org.opentripplanner.ext.emissions.EmissionsServiceModule; +import org.opentripplanner.ext.interactivelauncher.configuration.InteractiveLauncherModule; import org.opentripplanner.ext.ridehailing.configure.RideHailingServicesModule; import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.configure.StopConsolidationServiceModule; @@ -50,6 +51,7 @@ RideHailingServicesModule.class, EmissionsServiceModule.class, StopConsolidationServiceModule.class, + InteractiveLauncherModule.class, } ) public interface ConstructApplicationFactory { diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java index 2ff6de29b3d..c9d7253b0be 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java +++ b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java @@ -7,6 +7,7 @@ import javax.annotation.Nullable; import org.opentripplanner.astar.spi.TraverseVisitor; import org.opentripplanner.ext.emissions.EmissionsService; +import org.opentripplanner.ext.interactivelauncher.api.LauncherRequestDecorator; import org.opentripplanner.ext.ridehailing.RideHailingService; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.raptor.configure.RaptorConfig; @@ -36,11 +37,14 @@ OtpServerRequestContext providesServerContext( List rideHailingServices, @Nullable StopConsolidationService stopConsolidationService, @Nullable TraverseVisitor traverseVisitor, - EmissionsService emissionsService + EmissionsService emissionsService, + LauncherRequestDecorator launcherRequestDecorator ) { + var defaultRequest = launcherRequestDecorator.intercept(routerConfig.routingRequestDefaults()); + return DefaultServerRequestContext.create( routerConfig.transitTuningConfig(), - routerConfig.routingRequestDefaults(), + defaultRequest, raptorConfig, graph, transitService, From bd16e4046bd85c00ca35e7113fde8b6fe0b588b6 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 14:07:19 +0100 Subject: [PATCH 034/356] refactor: Cleanup SystemErrDebugLogger --- .../raptor/rangeraptor/SystemErrDebugLogger.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java index 060d3a2e018..951721f81a7 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/SystemErrDebugLogger.java @@ -43,14 +43,14 @@ public class SystemErrDebugLogger implements DebugLogger { private final Table arrivalTable = Table .of() .withAlights(Center, Center, Right, Right, Right, Right, Left, Left) - .withHeaders("ARRIVAL", "LEG", "RND", "STOP", "ARRIVE", "COST", "TRIP", "DETAILS") + .withHeaders("ARRIVAL", "LEG", "RND", "STOP", "ARRIVE", "C₁", "TRIP", "DETAILS") .withMinWidths(9, 7, 3, 5, 8, 9, 24, 0) .build(); private final Table pathTable = Table .of() .withAlights(Center, Center, Right, Right, Right, Right, Right, Right, Left) - .withHeaders(">>> PATH", "TR", "FROM", "TO", "START", "END", "DURATION", "COST", "DETAILS") - .withMinWidths(9, 2, 5, 5, 8, 8, 8, 6, 0) + .withHeaders(">>> PATH", "TR", "FROM", "TO", "START", "END", "DURATION", "C₁", "DETAILS") + .withMinWidths(9, 2, 5, 5, 8, 8, 8, 9, 0) .build(); private boolean forwardSearch = true; private int lastIterationTime = NOT_SET; @@ -112,6 +112,7 @@ public void pathFilteringListener(DebugEvent> e) { RaptorPath p = e.element(); var aLeg = p.accessLeg(); var eLeg = p.egressLeg(); + println( pathTable.rowAsText( e.action().toString(), From eb259ee3b247095206bfaff0876f00bd733250b9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 15:59:41 +0100 Subject: [PATCH 035/356] refactor: Create a separate model for StartUp --- .../InteractiveOtpMain.java | 6 +- .../ext/interactivelauncher/Model.java | 187 +----------------- .../startup/DataSourcesView.java | 5 +- .../interactivelauncher/startup/MainView.java | 6 +- .../startup/OptionsView.java | 5 +- .../startup/StartupModel.java | 178 +++++++++++++++++ 6 files changed, 192 insertions(+), 195 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java index d61ae6bfcd3..f5621c45278 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java @@ -24,16 +24,14 @@ public static void main(String[] args) { private void run() { this.model = Model.load(); - MainView frame = new MainView(new Thread(this::startOtp)::start, model); + MainView frame = new MainView(new Thread(this::startOtp)::start, model.getStartupModel()); frame.start(); } private void startOtp() { model.save(); - new OtpDebugController(model).start(); - System.out.println("Start OTP: " + model + "\n"); - OTPMain.main(model.asOtpArgs()); + OTPMain.main(model.getStartupModel().asOtpArgs()); } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java index 1550f8bc1ab..8e0c2b353a7 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java @@ -1,34 +1,17 @@ package org.opentripplanner.ext.interactivelauncher; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.IOException; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; import org.opentripplanner.ext.interactivelauncher.logging.LogModel; -import org.opentripplanner.ext.interactivelauncher.support.SearchForOtpConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opentripplanner.ext.interactivelauncher.startup.StartupModel; public class Model implements Serializable { - private static final Logger LOG = LoggerFactory.getLogger(Model.class); - private static final File MODEL_FILE = new File("interactive_otp_main.json"); - @JsonIgnore - private transient Consumer commandLineChange; - - private String rootDirectory = null; - private String dataSource = null; - private boolean buildStreet = false; - private boolean buildTransit = true; - private boolean saveGraph = false; - private boolean serveGraph = true; - private boolean visualizer = false; + private StartupModel startupModel; private LogModel logModel; public Model() {} @@ -41,116 +24,12 @@ public static Model load() { return model; } - public void subscribeCmdLineUpdates(Consumer commandLineChange) { - this.commandLineChange = commandLineChange; - } - - @SuppressWarnings("AccessOfSystemProperties") - public String getRootDirectory() { - return rootDirectory == null ? System.getProperty("user.dir") : rootDirectory; - } - - public void setRootDirectory(String rootDirectory) { - // If the persisted JSON do not contain the rootDirectory, then avoid setting it - if (rootDirectory != null) { - this.rootDirectory = rootDirectory; - } - notifyChangeListener(); - } - - public String getDataSource() { - return dataSource; - } - - public void setDataSource(String dataSource) { - this.dataSource = dataSource; - notifyChangeListener(); - } - - @JsonIgnore - public List getDataSourceOptions() { - List dataSourceOptions = new ArrayList<>(); - File rootDir = new File(getRootDirectory()); - List dirs = SearchForOtpConfig.search(rootDir); - // Add 1 char for the path-separator-character - int length = rootDir.getAbsolutePath().length() + 1; - - for (File dir : dirs) { - var path = dir.getAbsolutePath(); - if (path.length() <= length) { - LOG.warn( - "The root directory contains a config file, choose " + - "the parent directory or delete the config file." - ); - continue; - } - dataSourceOptions.add(path.substring(length)); - } - return dataSourceOptions; - } - - public boolean isBuildStreet() { - return buildStreet; - } - - public void setBuildStreet(boolean buildStreet) { - this.buildStreet = buildStreet; - notifyChangeListener(); - } - - public boolean isBuildTransit() { - return buildTransit; - } - - public void setBuildTransit(boolean buildTransit) { - this.buildTransit = buildTransit; - notifyChangeListener(); - } - - public boolean isSaveGraph() { - return saveGraph; - } - - public void setSaveGraph(boolean saveGraph) { - this.saveGraph = saveGraph; - notifyChangeListener(); - } - - public boolean isServeGraph() { - return serveGraph; - } - - public void setServeGraph(boolean serveGraph) { - this.serveGraph = serveGraph; - notifyChangeListener(); + public StartupModel getStartupModel() { + return startupModel; } - public boolean isVisualizer() { - return visualizer; - } - - public void setVisualizer(boolean visualizer) { - this.visualizer = visualizer; - notifyChangeListener(); - } - - @Override - public String toString() { - return ( - "(" + - "data-source-dir: " + - getDataSourceDirectory() + - (buildStreet ? ", buildStreet" : "") + - (buildTransit ? ", buildTransit" : "") + - (saveGraph ? ", saveGraph" : "") + - (serveGraph ? ", serveGraph" : "") + - (visualizer ? ", visualizer" : "") + - ')' - ); - } - - public String toCliString() { - return String.join(" ", asOtpArgs()); + public LogModel getLogModel() { + return logModel; } public void save() { @@ -161,46 +40,6 @@ public void save() { } } - public LogModel getLogModel() { - return logModel; - } - - @JsonIgnore - String getDataSourceDirectory() { - if (dataSource == null) { - return "DATA_SOURCE_NOT_SET"; - } - return rootDirectory + File.separatorChar + dataSource; - } - - String[] asOtpArgs() { - List args = new ArrayList<>(); - - if (buildAll()) { - args.add("--build"); - } else if (buildStreet) { - args.add("--buildStreet"); - } else if (buildTransit) { - args.add("--loadStreet"); - } else { - args.add("--load"); - } - - if (saveGraph && (buildTransit || buildStreet)) { - args.add("--save"); - } - if (serveGraph && !buildStreetOnly()) { - args.add("--serve"); - } - if (serveGraph && !buildStreetOnly() && visualizer) { - args.add("--visualize"); - } - - args.add(getDataSourceDirectory()); - - return args.toArray(new String[0]); - } - private static Model createNew() { var model = new Model(); model.logModel = new LogModel(); @@ -224,20 +63,6 @@ private static Model readFromFile() { } } - private void notifyChangeListener() { - if (commandLineChange != null) { - commandLineChange.accept(toCliString()); - } - } - - private boolean buildAll() { - return buildStreet && buildTransit; - } - - private boolean buildStreetOnly() { - return buildStreet && !buildTransit; - } - private void setupCallbacks() { logModel.init(this::save); } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java index 07052b9cd29..d8787287681 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java @@ -12,7 +12,6 @@ import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JRadioButton; -import org.opentripplanner.ext.interactivelauncher.Model; import org.opentripplanner.ext.interactivelauncher.support.ViewUtils; class DataSourcesView { @@ -28,9 +27,9 @@ class DataSourcesView { private final Box mainPanel = Box.createVerticalBox(); private final Box listPanel = Box.createHorizontalBox(); - private final Model model; + private final StartupModel model; - public DataSourcesView(Model model) { + public DataSourcesView(StartupModel model) { this.model = model; setupDataSources(); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java index d147624aa61..6db2508196c 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/MainView.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.interactivelauncher.startup; -import static java.awt.GridBagConstraints.BOTH; import static java.awt.GridBagConstraints.CENTER; import static java.awt.GridBagConstraints.HORIZONTAL; import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BACKGROUND; @@ -13,7 +12,6 @@ import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; -import org.opentripplanner.ext.interactivelauncher.Model; public class MainView { @@ -50,9 +48,9 @@ public class MainView { private final OptionsView optionsView; private final StartOtpButtonView startOtpButtonView; private final Runnable otpStarter; - private final Model model; + private final StartupModel model; - public MainView(Runnable otpStarter, Model model) throws HeadlessException { + public MainView(Runnable otpStarter, StartupModel model) throws HeadlessException { var innerPanel = new JPanel(); var statusBarTxt = new StatusBar(); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java index 3d98bbf0cfc..a8c4327a2d4 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java @@ -8,7 +8,6 @@ import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; -import org.opentripplanner.ext.interactivelauncher.Model; class OptionsView { @@ -18,9 +17,9 @@ class OptionsView { private final JCheckBox saveGraphChk; private final JCheckBox startOptServerChk; private final JCheckBox startOptVisualizerChk; - private final Model model; + private final StartupModel model; - OptionsView(Model model) { + OptionsView(StartupModel model) { this.model = model; this.buildStreetGraphChk = new JCheckBox("Street graph", model.isBuildStreet()); this.buildTransitGraphChk = new JCheckBox("Transit graph", model.isBuildTransit()); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java new file mode 100644 index 00000000000..5b803b2318c --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/StartupModel.java @@ -0,0 +1,178 @@ +package org.opentripplanner.ext.interactivelauncher.startup; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import org.opentripplanner.ext.interactivelauncher.support.SearchForOtpConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StartupModel { + + private static final Logger LOG = LoggerFactory.getLogger(StartupModel.class); + + @JsonIgnore + private transient Consumer commandLineChange; + + private String rootDirectory = null; + private String dataSource = null; + private boolean buildStreet = false; + private boolean buildTransit = true; + private boolean saveGraph = false; + private boolean serveGraph = true; + private boolean visualizer = false; + + public void subscribeCmdLineUpdates(Consumer commandLineChange) { + this.commandLineChange = commandLineChange; + } + + @SuppressWarnings("AccessOfSystemProperties") + public String getRootDirectory() { + return rootDirectory == null ? System.getProperty("user.dir") : rootDirectory; + } + + public void setRootDirectory(String rootDirectory) { + // If the persisted JSON do not contain the rootDirectory, then avoid setting it + if (rootDirectory != null) { + this.rootDirectory = rootDirectory; + } + notifyChangeListener(); + } + + public String getDataSource() { + return dataSource; + } + + public void setDataSource(String dataSource) { + this.dataSource = dataSource; + notifyChangeListener(); + } + + @JsonIgnore + public List getDataSourceOptions() { + List dataSourceOptions = new ArrayList<>(); + File rootDir = new File(getRootDirectory()); + List dirs = SearchForOtpConfig.search(rootDir); + // Add 1 char for the path-separator-character + int length = rootDir.getAbsolutePath().length() + 1; + + for (File dir : dirs) { + var path = dir.getAbsolutePath(); + if (path.length() <= length) { + LOG.warn( + "The root directory contains a config file, choose " + + "the parent directory or delete the config file." + ); + continue; + } + dataSourceOptions.add(path.substring(length)); + } + return dataSourceOptions; + } + + public boolean isBuildStreet() { + return buildStreet; + } + + public void setBuildStreet(boolean buildStreet) { + this.buildStreet = buildStreet; + notifyChangeListener(); + } + + public boolean isBuildTransit() { + return buildTransit; + } + + public void setBuildTransit(boolean buildTransit) { + this.buildTransit = buildTransit; + notifyChangeListener(); + } + + public boolean isSaveGraph() { + return saveGraph; + } + + public void setSaveGraph(boolean saveGraph) { + this.saveGraph = saveGraph; + notifyChangeListener(); + } + + public boolean isServeGraph() { + return serveGraph; + } + + public void setServeGraph(boolean serveGraph) { + this.serveGraph = serveGraph; + notifyChangeListener(); + } + + public boolean isVisualizer() { + return visualizer; + } + + public void setVisualizer(boolean visualizer) { + this.visualizer = visualizer; + notifyChangeListener(); + } + + @Override + public String toString() { + return String.join("", asOtpArgs()); + } + + public String toCliString() { + return String.join(" ", asOtpArgs()); + } + + private void notifyChangeListener() { + if (commandLineChange != null) { + commandLineChange.accept(toCliString()); + } + } + + @JsonIgnore + String getDataSourceDirectory() { + if (dataSource == null) { + return "DATA_SOURCE_NOT_SET"; + } + return getRootDirectory() + File.separatorChar + dataSource; + } + + public String[] asOtpArgs() { + List args = new ArrayList<>(); + + if (buildAll()) { + args.add("--build"); + } else if (buildStreet) { + args.add("--buildStreet"); + } else if (buildTransit) { + args.add("--loadStreet"); + } else { + args.add("--load"); + } + + if (saveGraph && (buildTransit || buildStreet)) { + args.add("--save"); + } + if (serveGraph && !buildStreetOnly()) { + args.add("--serve"); + } + if (serveGraph && !buildStreetOnly() && visualizer) { + args.add("--visualize"); + } + + args.add(getDataSourceDirectory()); + + return args.toArray(new String[0]); + } + + private boolean buildAll() { + return buildStreet && buildTransit; + } + + private boolean buildStreetOnly() { + return buildStreet && !buildTransit; + } +} From 50cc04e15678ca3d74cc3931cf3c6ccb436a67c2 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:02:52 +0100 Subject: [PATCH 036/356] refactor: Create debug package in o.o.ext.interactivelauncher --- .../org/opentripplanner/ext/interactivelauncher/Model.java | 2 +- .../ext/interactivelauncher/OtpDebugController.java | 4 ++-- .../{ => debug}/logging/DebugLoggingSupport.java | 3 +-- .../ext/interactivelauncher/{ => debug}/logging/LogModel.java | 2 +- .../ext/interactivelauncher/{ => debug}/logging/LogView.java | 2 +- .../{ => debug}/logging/OTPDebugLoggers.java | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => debug}/logging/DebugLoggingSupport.java (95%) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => debug}/logging/LogModel.java (95%) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => debug}/logging/LogView.java (92%) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => debug}/logging/OTPDebugLoggers.java (90%) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java index 8e0c2b353a7..d44e7c0e340 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java @@ -4,7 +4,7 @@ import java.io.File; import java.io.IOException; import java.io.Serializable; -import org.opentripplanner.ext.interactivelauncher.logging.LogModel; +import org.opentripplanner.ext.interactivelauncher.debug.logging.LogModel; import org.opentripplanner.ext.interactivelauncher.startup.StartupModel; public class Model implements Serializable { diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java index 95635c5bb0c..57ef7f70644 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java @@ -6,8 +6,8 @@ import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTabbedPane; -import org.opentripplanner.ext.interactivelauncher.logging.LogModel; -import org.opentripplanner.ext.interactivelauncher.logging.LogView; +import org.opentripplanner.ext.interactivelauncher.debug.logging.LogModel; +import org.opentripplanner.ext.interactivelauncher.debug.logging.LogView; public class OtpDebugController { diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/DebugLoggingSupport.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/DebugLoggingSupport.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java index fcfa323680f..9985f8eb079 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/DebugLoggingSupport.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java @@ -1,11 +1,10 @@ -package org.opentripplanner.ext.interactivelauncher.logging; +package org.opentripplanner.ext.interactivelauncher.debug.logging; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.regex.Pattern; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java similarity index 95% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java index 536c8d1dc87..7f7695ad2e5 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogModel.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.interactivelauncher.logging; +package org.opentripplanner.ext.interactivelauncher.debug.logging; import com.fasterxml.jackson.annotation.JsonIgnore; import java.io.Serializable; diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java index a71f90eb697..d4cea4d0baf 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/LogView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.interactivelauncher.logging; +package org.opentripplanner.ext.interactivelauncher.debug.logging; import javax.swing.Box; import javax.swing.JCheckBox; diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/OTPDebugLoggers.java similarity index 90% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/OTPDebugLoggers.java index 4663b6017de..a38cb5cab58 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/logging/OTPDebugLoggers.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/OTPDebugLoggers.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.interactivelauncher.logging; +package org.opentripplanner.ext.interactivelauncher.debug.logging; import java.util.List; From 6d890c774d5a3a8379f520e0a7b50b44c15d4de1 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:04:59 +0100 Subject: [PATCH 037/356] refactor: Rename OTPDebugLoggers to DebugLoggers --- .../logging/{OTPDebugLoggers.java => DebugLoggers.java} | 8 ++++---- .../ext/interactivelauncher/debug/logging/LogView.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/{OTPDebugLoggers.java => DebugLoggers.java} (71%) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/OTPDebugLoggers.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java similarity index 71% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/OTPDebugLoggers.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java index a38cb5cab58..0635b9a3675 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/OTPDebugLoggers.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java @@ -2,8 +2,8 @@ import java.util.List; -record OTPDebugLoggers(String label, String logger) { - static List list() { +record DebugLoggers(String label, String logger) { + static List list() { return List.of( of("Data import issues", "DATA_IMPORT_ISSUES"), of("All OTP debuggers", "org.opentripplanner"), @@ -13,7 +13,7 @@ static List list() { ); } - private static OTPDebugLoggers of(String label, String logger) { - return new OTPDebugLoggers(label, logger); + private static DebugLoggers of(String label, String logger) { + return new DebugLoggers(label, logger); } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java index d4cea4d0baf..6417e487ca7 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java @@ -14,14 +14,14 @@ public class LogView { public LogView(LogModel model) { this.model = model; - OTPDebugLoggers.list().forEach(this::add); + DebugLoggers.list().forEach(this::add); } public JComponent panel() { return panel; } - private void add(OTPDebugLoggers logger) { + private void add(DebugLoggers logger) { var box = new JCheckBox(logger.label()); box.setSelected(model.isLoggerEnabled(logger.logger())); box.addActionListener(e -> selectLogger(logger.logger(), box.isSelected())); From 578cc48867fea053193b9c37697022de23f49561 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:09:31 +0100 Subject: [PATCH 038/356] refactor: Extract addLabel utility method --- .../ext/interactivelauncher/startup/DataSourcesView.java | 9 ++++----- .../ext/interactivelauncher/startup/OptionsView.java | 6 +++--- .../ext/interactivelauncher/support/ViewUtils.java | 5 +++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java index d8787287681..e7b1814faa2 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/DataSourcesView.java @@ -2,6 +2,7 @@ import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addComp; import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addHorizontalGlue; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addLabel; import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addVerticalSectionSpace; import java.awt.Component; @@ -33,12 +34,10 @@ public DataSourcesView(StartupModel model) { this.model = model; setupDataSources(); - JLabel label = new JLabel("Select data source"); + addLabel("Select data source", mainPanel); + addVerticalSectionSpace(mainPanel); listPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - - addComp(label, mainPanel); - addVerticalSectionSpace(mainPanel); addComp(listPanel, mainPanel); } @@ -62,7 +61,7 @@ private void setupDataSources() { if (values.isEmpty()) { model.setDataSource(null); - JLabel label = new JLabel(""); + var label = new JLabel(""); label.setBackground(ViewUtils.BG_STATUS_BAR); label.setForeground(ViewUtils.FG_STATUS_BAR); addComp(label, listPanel); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java index a8c4327a2d4..08907346a76 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/startup/OptionsView.java @@ -1,13 +1,13 @@ package org.opentripplanner.ext.interactivelauncher.startup; import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addComp; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addLabel; import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addVerticalSectionSpace; import java.util.function.Consumer; import javax.swing.Box; import javax.swing.JCheckBox; import javax.swing.JComponent; -import javax.swing.JLabel; class OptionsView { @@ -44,7 +44,7 @@ class OptionsView { private JComponent createBuildBox() { var buildBox = Box.createVerticalBox(); - addComp(new JLabel("Build graph"), buildBox); + addLabel("Build graph", buildBox); addVerticalSectionSpace(buildBox); addComp(buildStreetGraphChk, buildBox); addComp(buildTransitGraphChk, buildBox); @@ -54,7 +54,7 @@ private JComponent createBuildBox() { private JComponent createActionBox() { var actionBox = Box.createVerticalBox(); - addComp(new JLabel("Actions"), actionBox); + addLabel("Actions", actionBox); addVerticalSectionSpace(actionBox); addComp(saveGraphChk, actionBox); addComp(startOptServerChk, actionBox); diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java index 1e0c94fb588..f906f063058 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/support/ViewUtils.java @@ -6,6 +6,7 @@ import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JComponent; +import javax.swing.JLabel; public final class ViewUtils { @@ -23,6 +24,10 @@ public static void addHorizontalGlue(Box box) { box.add(Box.createHorizontalGlue()); } + public static void addLabel(String label, Container panel) { + addComp(new JLabel(label), panel); + } + public static void addComp(JComponent c, Container panel) { if (DEBUG_LAYOUT) { c.setBorder(BorderFactory.createLineBorder(Color.green)); From 0756cad80168ce9ca6e43b464a4dfcb86382239e Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:13:21 +0100 Subject: [PATCH 039/356] InteractiveLauncherModule --- .../configuration/InteractiveLauncherModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java index 2df46b74127..9acd0298122 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/configuration/InteractiveLauncherModule.java @@ -9,7 +9,7 @@ public class InteractiveLauncherModule { static LauncherRequestDecorator decorator = request -> request; - static void enable(LauncherRequestDecorator decorator) { + public static void setRequestInterceptor(LauncherRequestDecorator decorator) { InteractiveLauncherModule.decorator = decorator; } From 5b131b2992348b3ebb5b308b0053803bfb2b6e55 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:31:25 +0100 Subject: [PATCH 040/356] refactor: Cleanup Model in interactive launcher This fixes a few small bugs/improve the JSON serialization --- .../ext/interactivelauncher/Model.java | 32 ++++++++++--------- .../debug/logging/LogModel.java | 14 +++++--- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java index d44e7c0e340..45d8583f66d 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java @@ -1,6 +1,8 @@ package org.opentripplanner.ext.interactivelauncher; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import java.io.File; import java.io.IOException; import java.io.Serializable; @@ -17,11 +19,7 @@ public class Model implements Serializable { public Model() {} public static Model load() { - var model = MODEL_FILE.exists() ? readFromFile() : createNew(); - // Setup callbacks - model.logModel.init(model::save); - - return model; + return MODEL_FILE.exists() ? readFromFile() : createNew(); } public StartupModel getStartupModel() { @@ -34,25 +32,22 @@ public LogModel getLogModel() { public void save() { try { - new ObjectMapper().writeValue(MODEL_FILE, this); + var mapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); + mapper.writeValue(MODEL_FILE, this); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } private static Model createNew() { - var model = new Model(); - model.logModel = new LogModel(); - model.logModel.initFromConfig(); - model.setupCallbacks(); - return model; + return new Model().initSubModels(); } private static Model readFromFile() { try { - var model = new ObjectMapper().readValue(MODEL_FILE, Model.class); - model.setupCallbacks(); - return model; + var mapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper.readValue(MODEL_FILE, Model.class).initSubModels(); } catch (IOException e) { System.err.println( "Unable to read the InteractiveOtpMain state cache. If the model changed this " + @@ -63,7 +58,14 @@ private static Model readFromFile() { } } - private void setupCallbacks() { + private Model initSubModels() { + if (startupModel == null) { + startupModel = new StartupModel(); + } + if (logModel == null) { + logModel = LogModel.createFromConfig(); + } logModel.init(this::save); + return this; } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java index 7f7695ad2e5..d6500fa060f 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java @@ -20,6 +20,12 @@ public class LogModel implements Serializable { public LogModel() {} + public static LogModel createFromConfig() { + var model = new LogModel(); + model.initFromConfig(); + return model; + } + /** Need to set this manually to support JSON serialization. */ public void init(Runnable saveCallback) { this.saveCallback = saveCallback; @@ -36,10 +42,6 @@ public void setActiveLoggers(Collection loggers) { this.activeLoggers.addAll(loggers); } - public void initFromConfig() { - activeLoggers.addAll(DebugLoggingSupport.getDebugLoggers()); - } - boolean isLoggerEnabled(String name) { return activeLoggers.contains(name); } @@ -53,4 +55,8 @@ void turnLoggerOnOff(String name, boolean enable) { DebugLoggingSupport.configureDebugLogging(name, enable); saveCallback.run(); } + + private void initFromConfig() { + activeLoggers.addAll(DebugLoggingSupport.getDebugLoggers()); + } } From dc06bb91ba827d3753ff1a41259e162d24ec398d Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:34:33 +0100 Subject: [PATCH 041/356] refactor: Cleanup interactive launcher debug loggers --- .../debug/logging/DebugLoggers.java | 15 +++++--- .../debug/logging/DebugLoggingSupport.java | 2 +- .../debug/logging/LogModel.java | 34 +++++++++++++++---- .../debug/logging/LogView.java | 8 ++--- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java index 0635b9a3675..48f87abf2ab 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggers.java @@ -2,8 +2,9 @@ import java.util.List; -record DebugLoggers(String label, String logger) { - static List list() { +class DebugLoggers { + + static List list() { return List.of( of("Data import issues", "DATA_IMPORT_ISSUES"), of("All OTP debuggers", "org.opentripplanner"), @@ -13,7 +14,13 @@ static List list() { ); } - private static DebugLoggers of(String label, String logger) { - return new DebugLoggers(label, logger); + static List listLoggers() { + return list().stream().map(Entry::logger).toList(); + } + + private static Entry of(String label, String logger) { + return new Entry(label, logger); } + + record Entry(String label, String logger) {} } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java index 9985f8eb079..09eddcfdf78 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/DebugLoggingSupport.java @@ -25,7 +25,7 @@ class DebugLoggingSupport { "(" + OTP + "|" + GRAPHQL + "|" + NAMED_LOGGERS + ")" ); - static List getDebugLoggers() { + static List listConfiguredDebugLoggers() { List result = new ArrayList<>(); LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); for (Logger log : context.getLoggerList()) { diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java index d6500fa060f..df59ccaa968 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogModel.java @@ -31,15 +31,18 @@ public void init(Runnable saveCallback) { this.saveCallback = saveCallback; } - /** Needed to do JSON serialization. */ + /** Used by JSON serialization. */ public Collection getActiveLoggers() { return List.copyOf(activeLoggers); } - /** Needed to do JSON serialization. */ + /** Used by JSON deserialization. */ public void setActiveLoggers(Collection loggers) { this.activeLoggers.clear(); this.activeLoggers.addAll(loggers); + for (var logger : activeLoggers) { + DebugLoggingSupport.configureDebugLogging(logger, true); + } } boolean isLoggerEnabled(String name) { @@ -48,15 +51,32 @@ boolean isLoggerEnabled(String name) { void turnLoggerOnOff(String name, boolean enable) { if (enable) { - activeLoggers.add(name); + if (!activeLoggers.contains(name)) { + activeLoggers.add(name); + DebugLoggingSupport.configureDebugLogging(name, enable); + save(); + } } else { - activeLoggers.remove(name); + if (activeLoggers.contains(name)) { + activeLoggers.remove(name); + DebugLoggingSupport.configureDebugLogging(name, enable); + save(); + } } - DebugLoggingSupport.configureDebugLogging(name, enable); - saveCallback.run(); } private void initFromConfig() { - activeLoggers.addAll(DebugLoggingSupport.getDebugLoggers()); + var debugLoggers = DebugLoggers.listLoggers(); + for (var logger : DebugLoggingSupport.listConfiguredDebugLoggers()) { + if (debugLoggers.contains(logger)) { + activeLoggers.add(logger); + } + } + } + + private void save() { + if (saveCallback != null) { + saveCallback.run(); + } } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java index 6417e487ca7..52c1774c019 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java @@ -21,10 +21,10 @@ public JComponent panel() { return panel; } - private void add(DebugLoggers logger) { - var box = new JCheckBox(logger.label()); - box.setSelected(model.isLoggerEnabled(logger.logger())); - box.addActionListener(e -> selectLogger(logger.logger(), box.isSelected())); + private void add(DebugLoggers.Entry entry) { + var box = new JCheckBox(entry.label()); + box.setSelected(model.isLoggerEnabled(entry.logger())); + box.addActionListener(e -> selectLogger(entry.logger(), box.isSelected())); panel.add(box); } From 61af2c9aa13b89b389743637444b2be8eb6b89e0 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 16:38:47 +0100 Subject: [PATCH 042/356] refactor: move OtpDebugController to o.o.ext.interactivelauncher.debug --- .../interactivelauncher/{ => debug}/OtpDebugController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/ext/java/org/opentripplanner/ext/interactivelauncher/{ => debug}/OtpDebugController.java (90%) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java similarity index 90% rename from src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java rename to src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java index 57ef7f70644..25e3c8c7629 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/OtpDebugController.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.interactivelauncher; +package org.opentripplanner.ext.interactivelauncher.debug; import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BACKGROUND; @@ -6,6 +6,7 @@ import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTabbedPane; +import org.opentripplanner.ext.interactivelauncher.Model; import org.opentripplanner.ext.interactivelauncher.debug.logging.LogModel; import org.opentripplanner.ext.interactivelauncher.debug.logging.LogView; From 39f2c39ae43990712a81f7e526e6da2f9383eff9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 17:03:17 +0100 Subject: [PATCH 043/356] feature: Ann UI to set Raptor debug parameters The UI is used to instrument the Raptor search and log events at decision points during routing. --- .../InteractiveOtpMain.java | 9 +- .../ext/interactivelauncher/Model.java | 24 +++-- .../debug/OtpDebugController.java | 25 ++--- .../debug/raptor/RaptorDebugModel.java | 97 +++++++++++++++++++ .../debug/raptor/RaptorDebugView.java | 87 +++++++++++++++++ 5 files changed, 222 insertions(+), 20 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java create mode 100644 src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java index f5621c45278..43061ee2b62 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/InteractiveOtpMain.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.interactivelauncher; +import org.opentripplanner.ext.interactivelauncher.configuration.InteractiveLauncherModule; +import org.opentripplanner.ext.interactivelauncher.debug.OtpDebugController; import org.opentripplanner.ext.interactivelauncher.startup.MainView; import org.opentripplanner.standalone.OTPMain; @@ -29,9 +31,14 @@ private void run() { } private void startOtp() { - model.save(); + startDebugControllerAndSetupRequestInterceptor(); System.out.println("Start OTP: " + model + "\n"); OTPMain.main(model.getStartupModel().asOtpArgs()); } + + private void startDebugControllerAndSetupRequestInterceptor() { + new OtpDebugController(model).start(); + InteractiveLauncherModule.setRequestInterceptor(model.getRaptorDebugModel()); + } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java index 45d8583f66d..59682082b90 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/Model.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.Serializable; import org.opentripplanner.ext.interactivelauncher.debug.logging.LogModel; +import org.opentripplanner.ext.interactivelauncher.debug.raptor.RaptorDebugModel; import org.opentripplanner.ext.interactivelauncher.startup.StartupModel; public class Model implements Serializable { @@ -15,6 +16,7 @@ public class Model implements Serializable { private StartupModel startupModel; private LogModel logModel; + private RaptorDebugModel raptorDebugModel; public Model() {} @@ -30,13 +32,8 @@ public LogModel getLogModel() { return logModel; } - public void save() { - try { - var mapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); - mapper.writeValue(MODEL_FILE, this); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } + public RaptorDebugModel getRaptorDebugModel() { + return raptorDebugModel; } private static Model createNew() { @@ -58,6 +55,15 @@ private static Model readFromFile() { } } + private void save() { + try { + var mapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); + mapper.writeValue(MODEL_FILE, this); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + private Model initSubModels() { if (startupModel == null) { startupModel = new StartupModel(); @@ -65,7 +71,11 @@ private Model initSubModels() { if (logModel == null) { logModel = LogModel.createFromConfig(); } + if (raptorDebugModel == null) { + raptorDebugModel = new RaptorDebugModel(); + } logModel.init(this::save); + raptorDebugModel.init(this::save); return this; } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java index 25e3c8c7629..9e41fe3412d 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/OtpDebugController.java @@ -2,29 +2,23 @@ import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.BACKGROUND; -import javax.swing.JComponent; import javax.swing.JFrame; -import javax.swing.JPanel; import javax.swing.JTabbedPane; import org.opentripplanner.ext.interactivelauncher.Model; -import org.opentripplanner.ext.interactivelauncher.debug.logging.LogModel; import org.opentripplanner.ext.interactivelauncher.debug.logging.LogView; +import org.opentripplanner.ext.interactivelauncher.debug.raptor.RaptorDebugView; +/** + * This controller/UI allows changing the debug loggers and setting the raptor + * debug parameters for incoming rute requests. + */ public class OtpDebugController { private final JFrame debugFrame = new JFrame("OTP Debug Controller"); public OtpDebugController(Model model) { - var tabPanel = new JTabbedPane(); - tabPanel.addTab("Logging", createLogPanel(model.getLogModel())); - tabPanel.addTab("Raptor", new JPanel()); - debugFrame.add(tabPanel); + debugFrame.add(createTabbedPane(model)); debugFrame.getContentPane().setBackground(BACKGROUND); - start(); - } - - private static JComponent createLogPanel(LogModel logModel) { - return new LogView(logModel).panel(); } public void start() { @@ -33,4 +27,11 @@ public void start() { debugFrame.setLocationRelativeTo(null); debugFrame.setVisible(true); } + + private static JTabbedPane createTabbedPane(Model model) { + var tabPanel = new JTabbedPane(); + tabPanel.addTab("Logging", new LogView(model.getLogModel()).panel()); + tabPanel.addTab("Raptor", new RaptorDebugView(model.getRaptorDebugModel()).panel()); + return tabPanel; + } } diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java new file mode 100644 index 00000000000..41d6ed6be1a --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugModel.java @@ -0,0 +1,97 @@ +package org.opentripplanner.ext.interactivelauncher.debug.raptor; + +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Objects; +import java.util.Set; +import javax.annotation.Nullable; +import org.opentripplanner.ext.interactivelauncher.api.LauncherRequestDecorator; +import org.opentripplanner.framework.lang.StringUtils; +import org.opentripplanner.routing.api.request.DebugEventType; +import org.opentripplanner.routing.api.request.RouteRequest; + +public class RaptorDebugModel implements LauncherRequestDecorator { + + private final Set eventTypes = EnumSet.noneOf(DebugEventType.class); + private String stops = null; + private String path = null; + private Runnable saveCallback; + + public RaptorDebugModel() {} + + public void init(Runnable saveCallback) { + this.saveCallback = saveCallback; + } + + /** Used by JSON serialization */ + public Set getEventTypes() { + return Collections.unmodifiableSet(eventTypes); + } + + /** Used by JSON serialization */ + public void setEventTypes(Collection eventTypes) { + this.eventTypes.clear(); + this.eventTypes.addAll(eventTypes); + } + + public void enableEventTypes(DebugEventType eventType, boolean enable) { + if (enable) { + if (!isEventTypeSet(eventType)) { + this.eventTypes.add(eventType); + save(); + } + } else { + if (isEventTypeSet(eventType)) { + this.eventTypes.remove(eventType); + save(); + } + } + } + + @Nullable + public String getStops() { + return stops; + } + + public void setStops(@Nullable String stops) { + stops = StringUtils.hasValue(stops) ? stops : null; + if (!Objects.equals(this.stops, stops)) { + this.stops = stops; + save(); + } + } + + @Nullable + public String getPath() { + return path; + } + + public void setPath(@Nullable String path) { + path = StringUtils.hasValue(path) ? path : null; + if (!Objects.equals(this.path, path)) { + this.path = path; + save(); + } + } + + public boolean isEventTypeSet(DebugEventType eventType) { + return eventTypes.contains(eventType); + } + + @Override + public RouteRequest intercept(RouteRequest defaultRequest) { + var newRequest = defaultRequest.clone(); + var debug = newRequest.journey().transit().raptorDebugging(); + debug.withEventTypes(eventTypes); + debug.withStops(stops); + debug.withPath(path); + return newRequest; + } + + private void save() { + if (saveCallback != null) { + saveCallback.run(); + } + } +} diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java new file mode 100644 index 00000000000..186b8d14837 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/raptor/RaptorDebugView.java @@ -0,0 +1,87 @@ +package org.opentripplanner.ext.interactivelauncher.debug.raptor; + +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addComp; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addLabel; +import static org.opentripplanner.ext.interactivelauncher.support.ViewUtils.addVerticalSectionSpace; +import static org.opentripplanner.routing.api.request.DebugEventType.DESTINATION_ARRIVALS; +import static org.opentripplanner.routing.api.request.DebugEventType.PATTERN_RIDES; +import static org.opentripplanner.routing.api.request.DebugEventType.STOP_ARRIVALS; + +import java.awt.Component; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.util.function.Consumer; +import javax.swing.Box; +import javax.swing.JCheckBox; +import javax.swing.JTextField; +import org.opentripplanner.routing.api.request.DebugEventType; + +/** + * This UI is used to set Raptor debug parameters, instrument the Raptor + * search, and log event at decision points during routing. + */ +public class RaptorDebugView { + + private final RaptorDebugModel model; + private final Box panel = Box.createVerticalBox(); + private final JCheckBox logStopArrivalsChk = new JCheckBox("Stop arrivals"); + private final JCheckBox logPatternRidesChk = new JCheckBox("Pattern rides"); + private final JCheckBox logDestinationArrivalsChk = new JCheckBox("Destination arrivals"); + private final JTextField stopsTxt = new JTextField(40); + private final JTextField pathTxt = new JTextField(40); + + public RaptorDebugView(RaptorDebugModel model) { + this.model = model; + + addLabel("Log Raptor events for", panel); + addComp(logStopArrivalsChk, panel); + addComp(logPatternRidesChk, panel); + addComp(logDestinationArrivalsChk, panel); + addVerticalSectionSpace(panel); + + addLabel("A list of stops to debug", panel); + addComp(stopsTxt, panel); + addVerticalSectionSpace(panel); + addLabel("A a path (as a list of stops) to debug", panel); + addComp(pathTxt, panel); + addVerticalSectionSpace(panel); + + initValues(); + setupActionListeners(); + } + + private void initValues() { + logStopArrivalsChk.setSelected(model.isEventTypeSet(STOP_ARRIVALS)); + logPatternRidesChk.setSelected(model.isEventTypeSet(PATTERN_RIDES)); + logDestinationArrivalsChk.setSelected(model.isEventTypeSet(DESTINATION_ARRIVALS)); + stopsTxt.setText(model.getStops()); + pathTxt.setText(model.getPath()); + } + + private void setupActionListeners() { + setupActionListenerChkBox(logStopArrivalsChk, STOP_ARRIVALS); + setupActionListenerChkBox(logPatternRidesChk, PATTERN_RIDES); + setupActionListenerChkBox(logDestinationArrivalsChk, DESTINATION_ARRIVALS); + setupActionListenerTextField(stopsTxt, model::setStops); + setupActionListenerTextField(pathTxt, model::setPath); + } + + public Component panel() { + return panel; + } + + private void setupActionListenerChkBox(JCheckBox box, DebugEventType type) { + box.addActionListener(l -> model.enableEventTypes(type, box.isSelected())); + } + + private static void setupActionListenerTextField(JTextField txtField, Consumer model) { + txtField.addFocusListener( + new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + model.accept(txtField.getText()); + } + } + ); + } +} From c4d2e6ea7d74e73e7ec9a397b597068764f98fa3 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 18:13:41 +0100 Subject: [PATCH 044/356] refactor: Add tooltip to debug loggers --- .../ext/interactivelauncher/debug/logging/LogView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java index 52c1774c019..ae8be59b07d 100644 --- a/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java +++ b/src/ext/java/org/opentripplanner/ext/interactivelauncher/debug/logging/LogView.java @@ -23,6 +23,7 @@ public JComponent panel() { private void add(DebugLoggers.Entry entry) { var box = new JCheckBox(entry.label()); + box.setToolTipText("Logger: " + entry.logger()); box.setSelected(model.isLoggerEnabled(entry.logger())); box.addActionListener(e -> selectLogger(entry.logger(), box.isSelected())); panel.add(box); From 10da47f62ba8cb1e78dfea65a7979c119dc76c5d Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 4 Jan 2024 18:18:13 +0100 Subject: [PATCH 045/356] Apply suggestions from code review Co-authored-by: Johan Torin --- .../apis/transmodel/model/plan/RelaxCostType.java | 8 ++++---- .../org/opentripplanner/apis/transmodel/schema.graphql | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java index d3455083695..41435c83a2f 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RelaxCostType.java @@ -46,8 +46,8 @@ public class RelaxCostType { .newInputObjectField() .name(CONSTANT) .description( - "The constant value to add to the limit. Must be a positive number. The value is" + - "equivalent to transit-cost-seconds. Integers is treated as seconds, but you may use " + + "The constant value to add to the limit. Must be a positive number. The value is " + + "equivalent to transit-cost-seconds. Integers are treated as seconds, but you may use " + "the duration format. Example: '3665 = 'DT1h1m5s' = '1h1m5s'." ) .defaultValueProgrammatic("0s") @@ -66,8 +66,8 @@ public static ObjectValue valueOf(CostLinearFunction value) { ObjectField .newObjectField() .name(CONSTANT) - // We only use this to display default value (this is an input type), so using the - // lenient OTP version of duration is ok - it is slightly more readable. + // We only use this to display the default value (this is an input type), so using + // the lenient OTP version of duration is ok - it is slightly more readable. .value(StringValue.of(DurationUtils.durationToStr(value.constant().asDuration()))) .build() ) diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index b5d1dc00a39..e73b074df3f 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -2035,7 +2035,7 @@ the default. We can express the RelaxCost as a function `f(t) = constant + ratio `f(t)=t` is the NORMAL function. """ input RelaxCostInput { - "The constant value to add to the limit. Must be a positive number. The value isequivalent to transit-cost-seconds. Integers is treated as seconds, but you may use the duration format. Example: '3665 = 'DT1h1m5s' = '1h1m5s'." + "The constant value to add to the limit. Must be a positive number. The value is equivalent to transit-cost-seconds. Integers are treated as seconds, but you may use the duration format. Example: '3665 = 'DT1h1m5s' = '1h1m5s'." constant: Cost = "0s" "The factor to multiply with the 'other cost'. Minimum value is 1.0." ratio: Float = 1.0 From 15ed36cb487c771710ccd9b7fcae4ed847485a04 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:25:45 +0100 Subject: [PATCH 046/356] doc: Fix JavaDoc in ItineraryListFilter --- .../routing/algorithm/filterchain/ItineraryListFilter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java index 883e6c48339..e18ee023b05 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java @@ -8,11 +8,11 @@ * List. It should treat the list as immutable. Do not change the list passed into the filter, * instead make a copy, change it and return the copy. It is allowed to return the list unchanged. *

    - * A filter should do only one thing! For example do not change the itineraries and delete elements + * A filter should do only one thing! For example, do not change the itineraries and delete elements * in the same filter. Instead, create two filters and insert them after each other in the filter * chain. *

    - * This allows decoration of each filter and make it easier to reuse logic. Like the {@link + * This allows decoration of each filter and makes it easier to reuse logic. Like the {@link * org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter} is reused in * several places. */ @@ -21,7 +21,7 @@ public interface ItineraryListFilter { * Process the given itineraries returning the result. *

    * This function should not change the List instance passed in, but may change the elements. It - * must return a List with all the elements passed in (and possibly new elements). Note! that the + * must return a List with all the elements passed in (and possibly new elements). Note! The * list passed into the filter might be immutable. *

    * This can be achieved using streams. Example: From 102cc45ae2b4f80d30d5fda85540c2a83aa5fe6c Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:31:46 +0100 Subject: [PATCH 047/356] refactor: Create an spi package in filterchain --- .../ext/accessibilityscore/AccessibilityScoreFilter.java | 2 +- .../org/opentripplanner/ext/emissions/EmissionsFilter.java | 2 +- src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java | 2 +- .../opentripplanner/ext/ridehailing/RideHailingFilter.java | 2 +- .../ext/stopconsolidation/ConsolidatedStopNameFilter.java | 2 +- .../algorithm/filterchain/ItineraryListFilterChain.java | 1 + .../filterchain/ItineraryListFilterChainBuilder.java | 1 + .../deletionflagger/RemoveItinerariesWithShortStreetLeg.java | 2 +- .../algorithm/filterchain/filter/DeletionFlaggingFilter.java | 2 +- .../routing/algorithm/filterchain/filter/GroupByFilter.java | 4 ++-- .../filter/RemoveDeletionFlagForLeastTransfersItinerary.java | 2 +- .../routing/algorithm/filterchain/filter/SortingFilter.java | 2 +- .../algorithm/filterchain/filter/TransitAlertFilter.java | 2 +- .../filterchain/groupids/GroupByAllSameStations.java | 1 + .../algorithm/filterchain/groupids/GroupByDistance.java | 1 + .../filterchain/groupids/GroupBySameFirstOrLastTrip.java | 1 + .../filterchain/groupids/GroupBySameRoutesAndStops.java | 1 + .../algorithm/filterchain/{groupids => spi}/GroupId.java | 2 +- .../algorithm/filterchain/{ => spi}/ItineraryListFilter.java | 2 +- .../algorithm/filterchain/filter/GroupByFilterTest.java | 2 +- 20 files changed, 21 insertions(+), 15 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{groupids => spi}/GroupId.java (98%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => spi}/ItineraryListFilter.java (95%) diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java b/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java index 46862b020d5..0ea16e6935f 100644 --- a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java +++ b/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.WalkStep; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.WheelchairTraversalInformation; import org.opentripplanner.transit.model.basic.Accessibility; diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java b/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java index 19a27d248af..d565304b908 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java +++ b/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java @@ -10,7 +10,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.framework.FeedScopedId; diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java b/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java index 8d344db8eb2..1831e58f5af 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java +++ b/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Objects; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.routing.fares.FareService; /** diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java b/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java index 730275d5952..6946e6d2ca8 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java +++ b/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java @@ -7,7 +7,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java index c28d1de91b6..b360afaaa21 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java @@ -5,7 +5,7 @@ import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopLeg; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ScheduledTransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; /** * A decorating filter that checks if a transit leg contains any primary stops and if it does, diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java index 2d3a65e3bbd..0a6fe2db825 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.routing.api.response.RoutingError; public class ItineraryListFilterChain { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 872bad6b4ae..14c43ba39ca 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -43,6 +43,7 @@ import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByAllSameStations; import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByDistance; import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameRoutesAndStops; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.services.TransitAlertService; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java index 2d45c46140b..0ab2e0114a8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java @@ -3,7 +3,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.street.search.TraverseMode; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java index 43009b5012e..ad508df2b62 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java @@ -5,8 +5,8 @@ import java.util.stream.Collectors; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; /** * This class is responsible for flagging itineraries for deletion based on a predicate in the diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java index 8084f4ced19..8db2ec945a1 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.function.Function; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; -import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; /** * This filter groups the itineraries using a group-id and filter each group by the given {@code diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java index 42630fdf934..c44f13b0fc7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java @@ -7,7 +7,7 @@ import java.util.Set; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; /** * This filter makes sure that the itinerary with the least amount of transfers is not marked for diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java index 3f1bae9049e..c2adcd56cb5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; /** * This is a filter to sort itineraries. To create a filter, provide a comparator as a constructor diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java index 06fb28716e6..bdcf035acd0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java @@ -4,7 +4,7 @@ import java.util.function.Function; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.routing.algorithm.mapping.AlertToLegMapper; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.site.MultiModalStation; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java index f5199a597cb..6a47cabb109 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java @@ -4,6 +4,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; import org.opentripplanner.transit.model.framework.FeedScopedId; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java index bbc9b764d15..d71e52d5503 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java @@ -7,6 +7,7 @@ import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; +import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; /** * This class create a group identifier for an itinerary based on the longest legs which together diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java index c8b942f1387..21ea75b7bf0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; import org.opentripplanner.transit.model.framework.FeedScopedId; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java index 338ec98b1ff..9b147757de7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java @@ -4,6 +4,7 @@ import java.util.stream.Stream; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; import org.opentripplanner.transit.model.framework.FeedScopedId; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupId.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/GroupId.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupId.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/GroupId.java index c83d3f4a9a7..eb5702ce5b5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupId.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/GroupId.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.spi; /** * A group-id identify a group of elements(itineraries). Group-ids can be arranged in a hierarchy diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryListFilter.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryListFilter.java index e18ee023b05..521a8120157 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryListFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain; +package org.opentripplanner.routing.algorithm.filterchain.spi; import java.util.List; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java index 447e9f0ab8e..d2e8c2b861b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java @@ -11,7 +11,7 @@ import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; -import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; public class GroupByFilterTest implements PlanTestConstants { From ea35203fa7c9b2e395414e227d6524c37b0fb7a9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:33:46 +0100 Subject: [PATCH 048/356] refactor: Rename comparator to sort --- .../org/opentripplanner/model/plan/ItinerarySortKey.java | 2 +- .../filterchain/ItineraryListFilterChainBuilder.java | 4 ++-- .../algorithm/filterchain/deletionflagger/PagingFilter.java | 2 +- .../RemoveDeletionFlagForLeastTransfersItinerary.java | 2 +- .../{comparator => sort}/SortOnGeneralizedCost.java | 2 +- .../{comparator => sort}/SortOrderComparator.java | 2 +- .../filterchain/deletionflagger/PagingFilterTest.java | 2 +- .../algorithm/filterchain/filter/GroupByFilterTest.java | 2 +- .../algorithm/filterchain/filter/SortingFilterTest.java | 2 +- .../{comparator => sort}/SortOnGeneralizedCostTest.java | 4 ++-- .../{comparator => sort}/SortOnNumberOfTransfersTest.java | 4 ++-- .../{comparator => sort}/SortOrderComparatorTest.java | 6 +++--- .../org/opentripplanner/service/paging/TestPagingModel.java | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{comparator => sort}/SortOnGeneralizedCost.java (88%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{comparator => sort}/SortOrderComparator.java (98%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{comparator => sort}/SortOnGeneralizedCostTest.java (94%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{comparator => sort}/SortOnNumberOfTransfersTest.java (91%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{comparator => sort}/SortOrderComparatorTest.java (96%) diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java index b9165270444..1ddbf6b9f95 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java @@ -2,8 +2,8 @@ import java.time.Instant; import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; -import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.filter.SortingFilter; +import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; /** * This interface is used to sort itineraries and other instances that we might want to sort among diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 14c43ba39ca..b156b3d3699 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -1,6 +1,6 @@ package org.opentripplanner.routing.algorithm.filterchain; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.generalizedCostComparator; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.generalizedCostComparator; import java.time.Duration; import java.time.Instant; @@ -18,7 +18,6 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; -import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NonTransitGeneralizedCostFilter; @@ -43,6 +42,7 @@ import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByAllSameStations; import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByDistance; import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameRoutesAndStops; +import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java index 893a239b46b..0677fadd2a2 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java @@ -7,7 +7,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; -import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; /** * This class is used to enforce the cut/limit between two pages. It removes potential duplicates diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java index c44f13b0fc7..44339b62ca9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java @@ -1,6 +1,6 @@ package org.opentripplanner.routing.algorithm.filterchain.filter; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.numberOfTransfersComparator; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.numberOfTransfersComparator; import java.util.HashSet; import java.util.List; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCost.java similarity index 88% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnGeneralizedCost.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCost.java index 364f9fddfff..a434e764d27 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCost.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.comparator; +package org.opentripplanner.routing.algorithm.filterchain.sort; import org.opentripplanner.framework.collection.CompositeComparator; import org.opentripplanner.model.plan.ItinerarySortKey; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOrderComparator.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparator.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOrderComparator.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparator.java index e52e53ab1c7..d4702949892 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOrderComparator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparator.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.comparator; +package org.opentripplanner.routing.algorithm.filterchain.sort; import static java.util.Comparator.comparing; import static java.util.Comparator.comparingInt; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java index 965889bdefc..c53e856e095 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java @@ -19,7 +19,7 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.SortOrder; -import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; import org.opentripplanner.transit.model._data.TransitModelForTest; public class PagingFilterTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java index d2e8c2b861b..086c4dacc76 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java @@ -9,8 +9,8 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; +import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; public class GroupByFilterTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java index 1d5f12aba98..f587c6e1df1 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.generalizedCostComparator; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.generalizedCostComparator; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnGeneralizedCostTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCostTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnGeneralizedCostTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCostTest.java index ac5ec5128c4..71913a0e7d3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnGeneralizedCostTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCostTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.routing.algorithm.filterchain.comparator; +package org.opentripplanner.routing.algorithm.filterchain.sort; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.generalizedCostComparator; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.generalizedCostComparator; import java.util.List; import java.util.stream.Collectors; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnNumberOfTransfersTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnNumberOfTransfersTest.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnNumberOfTransfersTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnNumberOfTransfersTest.java index 8a91c918c4b..942199110c3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOnNumberOfTransfersTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnNumberOfTransfersTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.routing.algorithm.filterchain.comparator; +package org.opentripplanner.routing.algorithm.filterchain.sort; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.numberOfTransfersComparator; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.numberOfTransfersComparator; import java.util.List; import java.util.stream.Collectors; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOrderComparatorTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparatorTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOrderComparatorTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparatorTest.java index d69bc119c76..e6014c80ea0 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/comparator/SortOrderComparatorTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparatorTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.routing.algorithm.filterchain.comparator; +package org.opentripplanner.routing.algorithm.filterchain.sort; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.defaultComparatorArriveBy; -import static org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator.defaultComparatorDepartAfter; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.defaultComparatorArriveBy; +import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.defaultComparatorDepartAfter; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java b/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java index f47e3444264..b97ff6a4fc9 100644 --- a/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java +++ b/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java @@ -13,7 +13,7 @@ import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.TestItineraryBuilder; import org.opentripplanner.model.plan.paging.cursor.PageCursor; -import org.opentripplanner.routing.algorithm.filterchain.comparator.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; import org.opentripplanner.transit.model._data.TransitModelForTest; class TestPagingModel { From 0189d5fe4edb976bf389bdb67c64eec36d6dc9c4 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:37:23 +0100 Subject: [PATCH 049/356] refactor: Move ItineraryDeletionFlagger to spi --- .../filterchain/ItineraryListFilterChainBuilder.java | 2 +- .../filterchain/deletionflagger/MaxLimitFilter.java | 1 + .../deletionflagger/NonTransitGeneralizedCostFilter.java | 1 + .../filterchain/deletionflagger/NumItinerariesFilter.java | 1 + .../OtherThanSameLegsMaxGeneralizedCostFilter.java | 1 + .../deletionflagger/OutsideSearchWindowFilter.java | 1 + .../algorithm/filterchain/deletionflagger/PagingFilter.java | 1 + .../RemoveBikerentalWithMostlyWalkingFilter.java | 1 + .../RemoveParkAndRideWithMostlyWalkingFilter.java | 1 + .../RemoveTransitIfStreetOnlyIsBetterFilter.java | 4 +--- .../RemoveTransitIfWalkingIsBetterFilter.java | 6 +----- .../filterchain/deletionflagger/RemoveWalkOnlyFilter.java | 1 + .../deletionflagger/TransitGeneralizedCostFilter.java | 1 + .../filterchain/filter/DeletionFlaggingFilter.java | 2 +- .../filterchain/filter/SameFirstOrLastTripFilter.java | 2 +- .../{deletionflagger => spi}/ItineraryDeletionFlagger.java | 2 +- .../RemoveTransitIfStreetOnlyIsBetterFilterTest.java | 1 + 17 files changed, 17 insertions(+), 12 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => spi}/ItineraryDeletionFlagger.java (96%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index b156b3d3699..9694ca95783 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -18,7 +18,6 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NonTransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilter; @@ -43,6 +42,7 @@ import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByDistance; import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameRoutesAndStops; import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java index 3a9d1422d34..5ff084a9db7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java @@ -2,6 +2,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * Flags the itineraries at the end of the list for removal. The list should be sorted on the diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java index da46b99f203..80802d0d95d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java index b939dd8ca68..484328aeb88 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java @@ -4,6 +4,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * Flag all itineraries after the provided limit. This flags the itineraries at the end of the list diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java index b8ed8e90de2..a4353184126 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java @@ -8,6 +8,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.routing.algorithm.filterchain.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.transit.model.timetable.Trip; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java index dc189efbc33..24382fc75cc 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java @@ -4,6 +4,7 @@ import java.time.Instant; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * This filter will remove all itineraries that are outside the search-window. In some diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java index 0677fadd2a2..3b2ac845efa 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java @@ -8,6 +8,7 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * This class is used to enforce the cut/limit between two pages. It removes potential duplicates diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java index 74ce88bc379..3aa599ddf43 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java @@ -3,6 +3,7 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * This is used to filter out bike rental itineraries that contain mostly walking. The value diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java index ad8c08ce7ec..bde47ee43a5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StreetLeg; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.street.search.TraverseMode; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java index 08307c16ade..70f05a1de98 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java @@ -1,13 +1,11 @@ package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; -import java.util.Comparator; import java.util.List; -import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java index 4b645e45a79..6895b94c419 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java @@ -1,14 +1,10 @@ package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; -import java.util.Comparator; import java.util.List; -import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.stream.Collectors; -import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * Filter itineraries which have a higher generalized-cost than a pure walk itinerary. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java index abac48563f8..792f4a55f1d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java @@ -2,6 +2,7 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * Filter itineraries and remove all itineraries where all legs are walking. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java index f296ca0f7c1..d000467a08c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java @@ -7,6 +7,7 @@ import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java index ad508df2b62..304d7d14c4a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java index a556530cb36..bf875f6055b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameFirstOrLastTrip; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; /** * This filter ensures that no more than one itinerary begins or ends with same trip. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/ItineraryDeletionFlagger.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryDeletionFlagger.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/ItineraryDeletionFlagger.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryDeletionFlagger.java index c6db9c14cf6..a51e9faeb49 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/ItineraryDeletionFlagger.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryDeletionFlagger.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.spi; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java index 9cbba961e71..3ea6b6d9016 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; public class RemoveTransitIfStreetOnlyIsBetterFilterTest implements PlanTestConstants { From 79214a6ca1478d824a62b2396a53c92238d4cdb2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 15:22:28 +0100 Subject: [PATCH 050/356] Take isFinal() into account when counting stops --- .../java/org/opentripplanner/astar/model/BinHeap.java | 6 ++++-- .../opentripplanner/astar/model/ShortestPathTree.java | 4 ---- .../astar/strategy/MaxCountSkipEdgeStrategy.java | 10 +++++----- .../graph_builder/module/NearbyStopFinder.java | 8 ++++---- .../street/search/StreetSearchBuilder.java | 3 +-- .../strategy/EuclideanRemainingWeightHeuristic.java | 1 - 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/opentripplanner/astar/model/BinHeap.java b/src/main/java/org/opentripplanner/astar/model/BinHeap.java index 9bc2b0762a8..f1c39f12b61 100644 --- a/src/main/java/org/opentripplanner/astar/model/BinHeap.java +++ b/src/main/java/org/opentripplanner/astar/model/BinHeap.java @@ -1,6 +1,7 @@ package org.opentripplanner.astar.model; import java.util.Arrays; +import org.opentripplanner.framework.tostring.ToStringBuilder; public class BinHeap { @@ -136,7 +137,8 @@ public void resize(int capacity) { elem = Arrays.copyOf(elem, capacity + 1); } - public int getCapacity() { - return capacity; + @Override + public String toString() { + return ToStringBuilder.of().addNum("size", size).toString(); } } diff --git a/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java b/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java index e373f9c785e..a6d7123cdfe 100644 --- a/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java +++ b/src/main/java/org/opentripplanner/astar/model/ShortestPathTree.java @@ -244,10 +244,6 @@ public void setAborted() { aborted = true; } - public boolean isAborted() { - return aborted; - } - public String toString() { return "ShortestPathTree(" + this.stateSets.size() + " vertices)"; } diff --git a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java index bcae9dcdb86..f719ed371ac 100644 --- a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java +++ b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java @@ -1,12 +1,12 @@ package org.opentripplanner.astar.strategy; -import java.util.function.Function; +import java.util.function.Predicate; import org.opentripplanner.astar.spi.AStarEdge; import org.opentripplanner.astar.spi.AStarState; import org.opentripplanner.astar.spi.SkipEdgeStrategy; /** - * Skips edges when the specified number of desired vertices have been visited + * Skips edges when the specified number of desired vertices have been visited. */ public class MaxCountSkipEdgeStrategy< State extends AStarState, Edge extends AStarEdge @@ -14,11 +14,11 @@ public class MaxCountSkipEdgeStrategy< implements SkipEdgeStrategy { private final int maxCount; - private final Function shouldIncreaseCount; + private final Predicate shouldIncreaseCount; private int visited; - public MaxCountSkipEdgeStrategy(int count, Function shouldIncreaseCount) { + public MaxCountSkipEdgeStrategy(int count, Predicate shouldIncreaseCount) { this.maxCount = count; this.shouldIncreaseCount = shouldIncreaseCount; this.visited = 0; @@ -26,7 +26,7 @@ public MaxCountSkipEdgeStrategy(int count, Function shouldIncrea @Override public boolean shouldSkipEdge(State current, Edge edge) { - if (this.shouldIncreaseCount.apply(current)) { + if (current.isFinal() && shouldIncreaseCount.test(current)) { visited++; } return visited > maxCount; diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index ba776ac5243..4caa04d7892 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -227,15 +227,15 @@ public List findNearbyStopsViaStreets( for (State state : spt.getAllStates()) { Vertex targetVertex = state.getVertex(); if (originVertices.contains(targetVertex)) continue; - if (targetVertex instanceof TransitStopVertex && state.isFinal()) { + if (targetVertex instanceof TransitStopVertex tsv && state.isFinal()) { stopsFound.add( - NearbyStop.nearbyStopForState(state, ((TransitStopVertex) targetVertex).getStop()) + NearbyStop.nearbyStopForState(state, tsv.getStop()) ); } if ( OTPFeature.FlexRouting.isOn() && - targetVertex instanceof StreetVertex && - !((StreetVertex) targetVertex).areaStops().isEmpty() + targetVertex instanceof StreetVertex streetVertex && + !streetVertex.areaStops().isEmpty() ) { for (AreaStop areaStop : ((StreetVertex) targetVertex).areaStops()) { // This is for a simplification, so that we only return one vertex from each diff --git a/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java b/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java index b4ac98674d0..079cd29706f 100644 --- a/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java +++ b/src/main/java/org/opentripplanner/street/search/StreetSearchBuilder.java @@ -102,7 +102,7 @@ protected void prepareInitialStates(Collection initialStates) { @Override protected void initializeHeuristic( RemainingWeightHeuristic heuristic, - Set origin, + Set ignored, Set destination, boolean arriveBy ) { @@ -111,7 +111,6 @@ protected void initializeHeuristic( } else if (heuristic instanceof EuclideanRemainingWeightHeuristic euclideanHeuristic) { euclideanHeuristic.initialize( streetRequest.mode(), - origin, destination, arriveBy, routeRequest.preferences() diff --git a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java b/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java index 36e4a57f8ec..e43278901d4 100644 --- a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java +++ b/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java @@ -26,7 +26,6 @@ public class EuclideanRemainingWeightHeuristic implements RemainingWeightHeurist // not work correctly. public void initialize( StreetMode streetMode, - Set fromVertices, Set toVertices, boolean arriveBy, RoutingPreferences preferences From 12381a542c196b12479960da9d3c46f113e954ee Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:43:06 +0100 Subject: [PATCH 051/356] refactor: Organize framework package --- .../AccessibilityScoreFilter.java | 2 +- .../ext/emissions/EmissionsFilter.java | 2 +- .../ext/fares/FaresFilter.java | 2 +- .../ext/ridehailing/RideHailingFilter.java | 2 +- .../ConsolidatedStopNameFilter.java | 2 +- .../model/plan/ItinerarySortKey.java | 4 ++-- .../filterchain/ItineraryListFilterChain.java | 2 +- .../ItineraryListFilterChainBuilder.java | 20 +++++++++---------- .../deletionflagger/MaxLimitFilter.java | 2 +- .../NonTransitGeneralizedCostFilter.java | 2 +- .../deletionflagger/NumItinerariesFilter.java | 2 +- ...rThanSameLegsMaxGeneralizedCostFilter.java | 4 ++-- .../OutsideSearchWindowFilter.java | 2 +- .../deletionflagger/PagingFilter.java | 4 ++-- ...moveBikerentalWithMostlyWalkingFilter.java | 2 +- .../RemoveItinerariesWithShortStreetLeg.java | 2 +- ...oveParkAndRideWithMostlyWalkingFilter.java | 2 +- ...moveTransitIfStreetOnlyIsBetterFilter.java | 2 +- .../RemoveTransitIfWalkingIsBetterFilter.java | 2 +- .../deletionflagger/RemoveWalkOnlyFilter.java | 2 +- .../TransitGeneralizedCostFilter.java | 2 +- ...eletionFlagForLeastTransfersItinerary.java | 4 ++-- .../filter/SameFirstOrLastTripFilter.java | 6 +++--- .../filter/TransitAlertFilter.java | 2 +- .../filter/DeletionFlaggingFilter.java | 6 +++--- .../{ => framework}/filter/GroupByFilter.java | 6 +++--- .../{ => framework}/filter/SortingFilter.java | 4 ++-- .../groupids/GroupByAllSameStations.java | 4 ++-- .../groupids/GroupByDistance.java | 4 ++-- .../groupids/GroupBySameFirstOrLastTrip.java | 4 ++-- .../groupids/GroupBySameRoutesAndStops.java | 4 ++-- .../sort/SortOnGeneralizedCost.java | 2 +- .../sort/SortOrderComparator.java | 2 +- .../{ => framework}/spi/GroupId.java | 2 +- .../spi/ItineraryDeletionFlagger.java | 2 +- .../spi/ItineraryListFilter.java | 2 +- .../deletionflagger/PagingFilterTest.java | 2 +- ...TransitIfStreetOnlyIsBetterFilterTest.java | 2 +- .../filterchain/filter/GroupByFilterTest.java | 7 +++++-- .../filterchain/filter/SortingFilterTest.java | 3 ++- .../groupids/GroupByAllSameStationsTest.java | 2 +- .../groupids/GroupByDistanceTest.java | 6 +++--- .../GroupBySameFirstOrLastTripTest.java | 2 +- .../GroupBySameRoutesAndStopsTest.java | 2 +- .../sort/SortOnGeneralizedCostTest.java | 4 ++-- .../sort/SortOnNumberOfTransfersTest.java | 4 ++-- .../sort/SortOrderComparatorTest.java | 6 +++--- .../service/paging/TestPagingModel.java | 2 +- 48 files changed, 83 insertions(+), 79 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/filter/DeletionFlaggingFilter.java (84%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/filter/GroupByFilter.java (90%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/filter/SortingFilter.java (84%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupByAllSameStations.java (91%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupByDistance.java (97%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupBySameFirstOrLastTrip.java (92%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupBySameRoutesAndStops.java (90%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/sort/SortOnGeneralizedCost.java (87%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/sort/SortOrderComparator.java (97%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/spi/GroupId.java (98%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/spi/ItineraryDeletionFlagger.java (97%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/spi/ItineraryListFilter.java (94%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupByAllSameStationsTest.java (97%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupByDistanceTest.java (97%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupBySameFirstOrLastTripTest.java (98%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/groupids/GroupBySameRoutesAndStopsTest.java (97%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/sort/SortOnGeneralizedCostTest.java (94%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/sort/SortOnNumberOfTransfersTest.java (90%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/sort/SortOrderComparatorTest.java (96%) diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java b/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java index 0ea16e6935f..b0ced6e00c5 100644 --- a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java +++ b/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.WalkStep; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.WheelchairTraversalInformation; import org.opentripplanner.transit.model.basic.Accessibility; diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java b/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java index d565304b908..2186339a4e6 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java +++ b/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java @@ -10,7 +10,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.framework.FeedScopedId; diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java b/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java index 1831e58f5af..cc3a956ef16 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java +++ b/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Objects; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.fares.FareService; /** diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java b/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java index 6946e6d2ca8..bbaa707a00b 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java +++ b/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java @@ -7,7 +7,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java index b360afaaa21..6165732e122 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java @@ -5,7 +5,7 @@ import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopLeg; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ScheduledTransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; /** * A decorating filter that checks if a transit leg contains any primary stops and if it does, diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java index 1ddbf6b9f95..9c4879b0184 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java @@ -2,8 +2,8 @@ import java.time.Instant; import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; -import org.opentripplanner.routing.algorithm.filterchain.filter.SortingFilter; -import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; /** * This interface is used to sort itineraries and other instances that we might want to sort among diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java index 0a6fe2db825..4f07d5377b9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.api.response.RoutingError; public class ItineraryListFilterChain { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 9694ca95783..f1fc7335e2d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -1,6 +1,6 @@ package org.opentripplanner.routing.algorithm.filterchain; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.generalizedCostComparator; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.generalizedCostComparator; import java.time.Duration; import java.time.Instant; @@ -32,18 +32,18 @@ import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfWalkingIsBetterFilter; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveWalkOnlyFilter; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.TransitGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.filter.DeletionFlaggingFilter; -import org.opentripplanner.routing.algorithm.filterchain.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.filter.RemoveDeletionFlagForLeastTransfersItinerary; import org.opentripplanner.routing.algorithm.filterchain.filter.SameFirstOrLastTripFilter; -import org.opentripplanner.routing.algorithm.filterchain.filter.SortingFilter; import org.opentripplanner.routing.algorithm.filterchain.filter.TransitAlertFilter; -import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByAllSameStations; -import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByDistance; -import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameRoutesAndStops; -import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DeletionFlaggingFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByAllSameStations; +import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByDistance; +import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupBySameRoutesAndStops; +import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.services.TransitAlertService; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java index 5ff084a9db7..f5c36cab82f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java @@ -2,7 +2,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * Flags the itineraries at the end of the list for removal. The list should be sorted on the diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java index 80802d0d95d..5f7326088ed 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java index 484328aeb88..5234ed4d408 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java @@ -4,7 +4,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * Flag all itineraries after the provided limit. This flags the itineraries at the end of the list diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java index a4353184126..ad89e8b023a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java @@ -7,8 +7,8 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.filter.GroupByFilter; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.transit.model.timetable.Trip; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java index 24382fc75cc..ebca3f523eb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java @@ -4,7 +4,7 @@ import java.time.Instant; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * This filter will remove all itineraries that are outside the search-window. In some diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java index 3b2ac845efa..f7bb96b88ca 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java @@ -7,8 +7,8 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; -import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * This class is used to enforce the cut/limit between two pages. It removes potential duplicates diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java index 3aa599ddf43..d9ae1586f53 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java @@ -3,7 +3,7 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * This is used to filter out bike rental itineraries that contain mostly walking. The value diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java index 0ab2e0114a8..dc392fc3c1c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java @@ -3,7 +3,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.street.search.TraverseMode; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java index bde47ee43a5..4516d02cc77 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.street.search.TraverseMode; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java index 70f05a1de98..c39b20339b1 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java index 6895b94c419..4dabbcabe64 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java @@ -4,7 +4,7 @@ import java.util.OptionalInt; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * Filter itineraries which have a higher generalized-cost than a pure walk itinerary. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java index 792f4a55f1d..411ed6f754e 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java @@ -2,7 +2,7 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * Filter itineraries and remove all itineraries where all legs are walking. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java index d000467a08c..55f8e4c5f0c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java @@ -7,7 +7,7 @@ import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java index 44339b62ca9..8ffd9986708 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java @@ -1,13 +1,13 @@ package org.opentripplanner.routing.algorithm.filterchain.filter; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.numberOfTransfersComparator; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.numberOfTransfersComparator; import java.util.HashSet; import java.util.List; import java.util.Set; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; /** * This filter makes sure that the itinerary with the least amount of transfers is not marked for diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java index bf875f6055b..4365131bc8c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java @@ -3,14 +3,14 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameFirstOrLastTrip; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupBySameFirstOrLastTrip; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; /** * This filter ensures that no more than one itinerary begins or ends with same trip. * It loops through itineraries from top to bottom. If itinerary matches with any other itinerary * from above, it is removed from list. - * Uses {@link org.opentripplanner.routing.algorithm.filterchain.groupids.GroupBySameFirstOrLastTrip}. + * Uses {@link GroupBySameFirstOrLastTrip}. * for matching itineraries. */ public class SameFirstOrLastTripFilter implements ItineraryDeletionFlagger { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java index bdcf035acd0..c50f7c17957 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java @@ -4,7 +4,7 @@ import java.util.function.Function; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.algorithm.mapping.AlertToLegMapper; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.site.MultiModalStation; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DeletionFlaggingFilter.java similarity index 84% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DeletionFlaggingFilter.java index 304d7d14c4a..c3b0fd66c45 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/DeletionFlaggingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DeletionFlaggingFilter.java @@ -1,12 +1,12 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; /** * This class is responsible for flagging itineraries for deletion based on a predicate in the diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java index 8db2ec945a1..73f84625750 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilter.java @@ -1,11 +1,11 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import java.util.ArrayList; import java.util.List; import java.util.function.Function; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; /** * This filter groups the itineraries using a group-id and filter each group by the given {@code diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java similarity index 84% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java index c2adcd56cb5..0b2664ccf26 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilter.java @@ -1,11 +1,11 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; /** * This is a filter to sort itineraries. To create a filter, provide a comparator as a constructor diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java index 6a47cabb109..83a5e15c802 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStations.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStations.java @@ -1,10 +1,10 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import java.util.List; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; import org.opentripplanner.transit.model.framework.FeedScopedId; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java index d71e52d5503..7ab605fb792 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistance.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistance.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import java.util.Comparator; import java.util.List; @@ -7,7 +7,7 @@ import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; /** * This class create a group identifier for an itinerary based on the longest legs which together diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java similarity index 92% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java index 21ea75b7bf0..cd8c776ef66 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTrip.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTrip.java @@ -1,11 +1,11 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; import org.opentripplanner.transit.model.framework.FeedScopedId; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java index 9b147757de7..ac95ae87db7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStops.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStops.java @@ -1,10 +1,10 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import java.util.List; import java.util.stream.Stream; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; import org.opentripplanner.transit.model.framework.FeedScopedId; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java similarity index 87% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCost.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java index a434e764d27..10c10362c46 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.sort; +package org.opentripplanner.routing.algorithm.filterchain.framework.sort; import org.opentripplanner.framework.collection.CompositeComparator; import org.opentripplanner.model.plan.ItinerarySortKey; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparator.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparator.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java index d4702949892..475309eeae4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.sort; +package org.opentripplanner.routing.algorithm.filterchain.framework.sort; import static java.util.Comparator.comparing; import static java.util.Comparator.comparingInt; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/GroupId.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/GroupId.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java index eb5702ce5b5..cb2b72f93ee 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/GroupId.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/GroupId.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.spi; +package org.opentripplanner.routing.algorithm.filterchain.framework.spi; /** * A group-id identify a group of elements(itineraries). Group-ids can be arranged in a hierarchy diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryDeletionFlagger.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDeletionFlagger.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryDeletionFlagger.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDeletionFlagger.java index a51e9faeb49..ba33971988f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryDeletionFlagger.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDeletionFlagger.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.spi; +package org.opentripplanner.routing.algorithm.filterchain.framework.spi; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryListFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java index 521a8120157..99366cee4d1 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/spi/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.spi; +package org.opentripplanner.routing.algorithm.filterchain.framework.spi; import java.util.List; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java index c53e856e095..1829e5c7802 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java @@ -19,7 +19,7 @@ import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.SortOrder; -import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; import org.opentripplanner.transit.model._data.TransitModelForTest; public class PagingFilterTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java index 3ea6b6d9016..a44462b0a93 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; public class RemoveTransitIfStreetOnlyIsBetterFilterTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java index 086c4dacc76..a79edeb3a4f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java @@ -10,8 +10,11 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; -import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; -import org.opentripplanner.routing.algorithm.filterchain.spi.GroupId; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DeletionFlaggingFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; public class GroupByFilterTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java index f587c6e1df1..550b85d92a8 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java @@ -3,12 +3,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.generalizedCostComparator; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.generalizedCostComparator; import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; public class SortingFilterTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStationsTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStationsTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java index 280fe43f3c8..692f3a61ca7 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByAllSameStationsTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByAllSameStationsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistanceTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistanceTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java index 76d3b34fb5d..cc17305af6d 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupByDistanceTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupByDistanceTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -6,8 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByDistance.calculateTotalDistance; -import static org.opentripplanner.routing.algorithm.filterchain.groupids.GroupByDistance.createKeySetOfLegsByLimit; +import static org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByDistance.calculateTotalDistance; +import static org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByDistance.createKeySetOfLegsByLimit; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTripTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java similarity index 98% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTripTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java index 6e19fff5bbc..436c1568852 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameFirstOrLastTripTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameFirstOrLastTripTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStopsTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStopsTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java index ea9b9c5d38b..26d3ca1d04b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/groupids/GroupBySameRoutesAndStopsTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/groupids/GroupBySameRoutesAndStopsTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.groupids; +package org.opentripplanner.routing.algorithm.filterchain.framework.groupids; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertSame; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCostTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCostTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java index 71913a0e7d3..c0e53de3381 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnGeneralizedCostTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCostTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.routing.algorithm.filterchain.sort; +package org.opentripplanner.routing.algorithm.filterchain.framework.sort; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.generalizedCostComparator; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.generalizedCostComparator; import java.util.List; import java.util.stream.Collectors; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnNumberOfTransfersTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java similarity index 90% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnNumberOfTransfersTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java index 942199110c3..40b7550b1a0 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOnNumberOfTransfersTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnNumberOfTransfersTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.routing.algorithm.filterchain.sort; +package org.opentripplanner.routing.algorithm.filterchain.framework.sort; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.numberOfTransfersComparator; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.numberOfTransfersComparator; import java.util.List; import java.util.stream.Collectors; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparatorTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparatorTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java index e6014c80ea0..c96ddede578 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/sort/SortOrderComparatorTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparatorTest.java @@ -1,9 +1,9 @@ -package org.opentripplanner.routing.algorithm.filterchain.sort; +package org.opentripplanner.routing.algorithm.filterchain.framework.sort; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.defaultComparatorArriveBy; -import static org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator.defaultComparatorDepartAfter; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.defaultComparatorArriveBy; +import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.defaultComparatorDepartAfter; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java b/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java index b97ff6a4fc9..938a201576f 100644 --- a/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java +++ b/src/test/java/org/opentripplanner/service/paging/TestPagingModel.java @@ -13,7 +13,7 @@ import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.TestItineraryBuilder; import org.opentripplanner.model.plan.paging.cursor.PageCursor; -import org.opentripplanner.routing.algorithm.filterchain.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; import org.opentripplanner.transit.model._data.TransitModelForTest; class TestPagingModel { From 530e5d41bd4821ed8ee2ba33d42aa5e499e5e303 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:46:14 +0100 Subject: [PATCH 052/356] refactor: Rename deletionflagger package to filters --- .../routing/algorithm/RoutingWorker.java | 2 +- .../filterchain/DeleteResultHandler.java | 2 +- .../ItineraryListFilterChainBuilder.java | 28 +++++++++---------- .../filterchain/RoutingErrorsAttacher.java | 6 ++-- .../TransitGeneralizedCostFilterParams.java | 2 +- .../MaxLimitFilter.java | 2 +- .../NonTransitGeneralizedCostFilter.java | 2 +- .../NumItinerariesFilter.java | 2 +- .../NumItinerariesFilterResults.java | 2 +- ...rThanSameLegsMaxGeneralizedCostFilter.java | 2 +- .../OutsideSearchWindowFilter.java | 2 +- .../PagingFilter.java | 2 +- ...moveBikerentalWithMostlyWalkingFilter.java | 2 +- .../RemoveItinerariesWithShortStreetLeg.java | 2 +- ...oveParkAndRideWithMostlyWalkingFilter.java | 2 +- ...moveTransitIfStreetOnlyIsBetterFilter.java | 2 +- .../RemoveTransitIfWalkingIsBetterFilter.java | 2 +- .../RemoveWalkOnlyFilter.java | 2 +- .../TransitGeneralizedCostFilter.java | 2 +- .../framework/spi/ItineraryListFilter.java | 2 +- .../mapping/PagingServiceFactory.java | 2 +- .../RouteRequestToFilterChainMapper.java | 2 +- .../service/paging/PagingService.java | 2 +- .../filterchain/DeleteResultHandlerTest.java | 4 +-- .../RoutingErrorsAttacherTest.java | 2 +- .../filterchain/filter/GroupByFilterTest.java | 2 +- .../MaxLimitFilterTest.java | 2 +- .../NumItinerariesFilterTest.java | 2 +- ...nSameLegsMaxGeneralizedCostFilterTest.java | 2 +- .../OutsideSearchWindowFilterTest.java | 2 +- .../PagingFilterTest.java | 2 +- ...RemoveBikeRentalWithMostlyWalkingTest.java | 2 +- ...moveItinerariesWithShortStreetLegTest.java | 2 +- ...emoveParkAndRideWithMostlyWalkingTest.java | 2 +- ...TransitIfStreetOnlyIsBetterFilterTest.java | 2 +- .../RemoveTransitIfWalkingIsBetterTest.java | 2 +- .../RemoveWalkOnlyFilterTest.java | 2 +- .../TransitGeneralizedCostFilterTest.java | 2 +- .../service/paging/TestDriver.java | 8 +++--- 39 files changed, 58 insertions(+), 58 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/MaxLimitFilter.java (91%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/NonTransitGeneralizedCostFilter.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/NumItinerariesFilter.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/NumItinerariesFilterResults.java (97%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/OtherThanSameLegsMaxGeneralizedCostFilter.java (97%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/OutsideSearchWindowFilter.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/PagingFilter.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveBikerentalWithMostlyWalkingFilter.java (95%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveItinerariesWithShortStreetLeg.java (95%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveParkAndRideWithMostlyWalkingFilter.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveTransitIfStreetOnlyIsBetterFilter.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveTransitIfWalkingIsBetterFilter.java (94%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveWalkOnlyFilter.java (87%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/TransitGeneralizedCostFilter.java (96%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/MaxLimitFilterTest.java (95%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/NumItinerariesFilterTest.java (97%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/OtherThanSameLegsMaxGeneralizedCostFilterTest.java (91%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/OutsideSearchWindowFilterTest.java (97%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/PagingFilterTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveBikeRentalWithMostlyWalkingTest.java (95%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveItinerariesWithShortStreetLegTest.java (96%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveParkAndRideWithMostlyWalkingTest.java (95%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveTransitIfStreetOnlyIsBetterFilterTest.java (96%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveTransitIfWalkingIsBetterTest.java (95%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/RemoveWalkOnlyFilterTest.java (95%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{deletionflagger => filters}/TransitGeneralizedCostFilterTest.java (98%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java b/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java index ad2c4c92639..bb688f27be9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java @@ -19,7 +19,7 @@ import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.api.request.SearchParams; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilterResults; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.algorithm.mapping.PagingServiceFactory; import org.opentripplanner.routing.algorithm.mapping.RouteRequestToFilterChainMapper; import org.opentripplanner.routing.algorithm.mapping.RoutingResponseMapper; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java index c09af943564..2bd26c6b7d4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java @@ -4,7 +4,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index f1fc7335e2d..6d197bf1169 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -18,23 +18,23 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NonTransitGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilterResults; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.OtherThanSameLegsMaxGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.OutsideSearchWindowFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.PagingFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveBikerentalWithMostlyWalkingFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveItinerariesWithShortStreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveParkAndRideWithMostlyWalkingFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfStreetOnlyIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfWalkingIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveWalkOnlyFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.filter.RemoveDeletionFlagForLeastTransfersItinerary; import org.opentripplanner.routing.algorithm.filterchain.filter.SameFirstOrLastTripFilter; import org.opentripplanner.routing.algorithm.filterchain.filter.TransitAlertFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.NonTransitGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; +import org.opentripplanner.routing.algorithm.filterchain.filters.OtherThanSameLegsMaxGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveBikerentalWithMostlyWalkingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveItinerariesWithShortStreetLeg; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveParkAndRideWithMostlyWalkingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveWalkOnlyFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DeletionFlaggingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java index 63191fdb88e..532868019eb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java @@ -9,9 +9,9 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.OutsideSearchWindowFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfStreetOnlyIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfWalkingIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; import org.opentripplanner.routing.api.response.RoutingError; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java index 5a460e6fa82..eb4085c5c0c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.filterchain.api; import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.TransitGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java index f5c36cab82f..f77512f54f4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java index 5f7326088ed..56f094386b3 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NonTransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.OptionalInt; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java index 5234ed4d408..89f82962f32 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.function.Consumer; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilterResults.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterResults.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilterResults.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterResults.java index 7226c19535b..04c8fcc039c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilterResults.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterResults.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.time.Instant; import java.util.List; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java similarity index 97% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java index ad89e8b023a..4b316f9802a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.OptionalInt; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java index ebca3f523eb..374bc33164c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.time.Duration; import java.time.Instant; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java index f7bb96b88ca..2c4f79d45e5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.Comparator; import java.util.List; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java index d9ae1586f53..9293c4d4072 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikerentalWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLeg.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLeg.java index dc392fc3c1c..5223704bbea 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLeg.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java index 4516d02cc77..c5ba7ff8c2d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.function.Predicate; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java index c39b20339b1..e3d90c24a83 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.OptionalInt; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java index 4dabbcabe64..7062957e500 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.OptionalInt; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java similarity index 87% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java index 411ed6f754e..a1a01dfc159 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java index 55f8e4c5f0c..9e8a79004d7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.time.temporal.ChronoUnit; import java.util.Comparator; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java index 99366cee4d1..7821779fabf 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java @@ -13,7 +13,7 @@ * chain. *

    * This allows decoration of each filter and makes it easier to reuse logic. Like the {@link - * org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter} is reused in + * org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter} is reused in * several places. */ public interface ItineraryListFilter { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java index 8b122e6cf24..3e3ebc2967c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java @@ -6,7 +6,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.api.request.SearchParams; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilterResults; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.service.paging.PagingService; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java index b379480bc33..76f9146f522 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java @@ -12,7 +12,7 @@ import org.opentripplanner.routing.algorithm.filterchain.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChainBuilder; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilterResults; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; diff --git a/src/main/java/org/opentripplanner/service/paging/PagingService.java b/src/main/java/org/opentripplanner/service/paging/PagingService.java index e8f09acf4d4..2734049e940 100644 --- a/src/main/java/org/opentripplanner/service/paging/PagingService.java +++ b/src/main/java/org/opentripplanner/service/paging/PagingService.java @@ -12,7 +12,7 @@ import org.opentripplanner.model.plan.paging.cursor.PageCursor; import org.opentripplanner.model.plan.paging.cursor.PageCursorFactory; import org.opentripplanner.model.plan.paging.cursor.PageType; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilterResults; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.api.response.TripSearchMetadata; public class PagingService { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java index beca0632114..32bcae2b86f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java @@ -21,8 +21,8 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; class DeleteResultHandlerTest { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java index 238604a66ad..eace7bc5cd9 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfStreetOnlyIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; import org.opentripplanner.routing.api.response.RoutingErrorCode; class RoutingErrorsAttacherTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java index a79edeb3a4f..87cd29167c1 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.MaxLimitFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DeletionFlaggingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilterTest.java index b4418de6c68..86814b4fc27 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/MaxLimitFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java index 879edd784b0..9ef7da991ff 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/NumItinerariesFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilterTest.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilterTest.java index e955b0ae04e..0bb2265c8a5 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OtherThanSameLegsMaxGeneralizedCostFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilterTest.java similarity index 97% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilterTest.java index 207210092b7..2ce7bbccf8c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/OutsideSearchWindowFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilterTest.java index 1829e5c7802..82df57ee7a6 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/PagingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.framework.collection.ListUtils.first; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikeRentalWithMostlyWalkingTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikeRentalWithMostlyWalkingTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikeRentalWithMostlyWalkingTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikeRentalWithMostlyWalkingTest.java index 5fe2bce098b..58cecb82810 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveBikeRentalWithMostlyWalkingTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikeRentalWithMostlyWalkingTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.opentripplanner.model.plan.TestItineraryBuilder.A; import static org.opentripplanner.model.plan.TestItineraryBuilder.B; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLegTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLegTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLegTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLegTest.java index 9b6df6bb1aa..72d88ec2469 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveItinerariesWithShortStreetLegTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLegTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingTest.java index 2c65f882473..8fdfb3c6de6 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveParkAndRideWithMostlyWalkingTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.opentripplanner.model.plan.TestItineraryBuilder.A; import static org.opentripplanner.model.plan.TestItineraryBuilder.B; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java index a44462b0a93..bb881bdc07d 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfStreetOnlyIsBetterFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterTest.java index 9b008993ba3..af2e5a68965 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveTransitIfWalkingIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilterTest.java index 62029ca389f..2ede3ccac10 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/RemoveWalkOnlyFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.A; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilterTest.java similarity index 98% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilterTest.java index 37faa5f2feb..f55b0c8d0b3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/deletionflagger/TransitGeneralizedCostFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.deletionflagger; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/service/paging/TestDriver.java b/src/test/java/org/opentripplanner/service/paging/TestDriver.java index 0b40b140139..70e47f31a75 100644 --- a/src/test/java/org/opentripplanner/service/paging/TestDriver.java +++ b/src/test/java/org/opentripplanner/service/paging/TestDriver.java @@ -11,10 +11,10 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.paging.cursor.PageCursor; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NumItinerariesFilterResults; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.OutsideSearchWindowFilter; -import org.opentripplanner.routing.algorithm.filterchain.deletionflagger.PagingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; +import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; /** * This class simulate/mock the context the paging is operating in. From b8a0f0ab3015734cd4d89ed832737419f5375d51 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 14:57:35 +0100 Subject: [PATCH 053/356] refactor: Use remove consistent, not delete --- .../filterchain/ItineraryListFilterChain.java | 1 + .../ItineraryListFilterChainBuilder.java | 13 +++++++------ .../filterchain/{ => api}/GroupBySimilarity.java | 3 ++- .../filter/SameFirstOrLastTripFilter.java | 4 ++-- .../filterchain/filters/MaxLimitFilter.java | 4 ++-- .../filters/NonTransitGeneralizedCostFilter.java | 4 ++-- .../filterchain/filters/NumItinerariesFilter.java | 4 ++-- .../OtherThanSameLegsMaxGeneralizedCostFilter.java | 4 ++-- .../filters/OutsideSearchWindowFilter.java | 4 ++-- .../algorithm/filterchain/filters/PagingFilter.java | 4 ++-- .../RemoveBikerentalWithMostlyWalkingFilter.java | 4 ++-- .../RemoveParkAndRideWithMostlyWalkingFilter.java | 4 ++-- .../RemoveTransitIfStreetOnlyIsBetterFilter.java | 4 ++-- .../RemoveTransitIfWalkingIsBetterFilter.java | 4 ++-- .../filterchain/filters/RemoveWalkOnlyFilter.java | 4 ++-- .../filters/TransitGeneralizedCostFilter.java | 4 ++-- .../errorhandling}/RoutingErrorsAttacher.java | 6 +++--- ...eletionFlaggingFilter.java => RemoveFilter.java} | 8 ++++---- ...tionFlagger.java => RemoveItineraryFlagger.java} | 4 ++-- .../mapping/RouteRequestToFilterChainMapper.java | 2 +- .../filterchain/ItineraryListFilterChainTest.java | 1 + .../filterchain/RoutingErrorsAttacherTest.java | 1 + .../filterchain/filter/GroupByFilterTest.java | 8 +++----- ...RemoveTransitIfStreetOnlyIsBetterFilterTest.java | 6 +++--- 24 files changed, 54 insertions(+), 51 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => api}/GroupBySimilarity.java (96%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework/errorhandling}/RoutingErrorsAttacher.java (95%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/{DeletionFlaggingFilter.java => RemoveFilter.java} (86%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/{ItineraryDeletionFlagger.java => RemoveItineraryFlagger.java} (94%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java index 4f07d5377b9..744e7b80906 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.framework.errorhandling.RoutingErrorsAttacher; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.api.response.RoutingError; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 6d197bf1169..3ee85669381 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -17,6 +17,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.algorithm.filterchain.filter.RemoveDeletionFlagForLeastTransfersItinerary; import org.opentripplanner.routing.algorithm.filterchain.filter.SameFirstOrLastTripFilter; @@ -35,15 +36,15 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveWalkOnlyFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DeletionFlaggingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByAllSameStations; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByDistance; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupBySameRoutesAndStops; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.services.TransitAlertService; @@ -516,7 +517,7 @@ private List buildGroupBySameRoutesAndStopsFilter() { GroupBySameRoutesAndStops::new, List.of( new SortingFilter(SortOrderComparator.comparator(sortOrder)), - new DeletionFlaggingFilter(new MaxLimitFilter(GroupBySameRoutesAndStops.TAG, 1)) + new RemoveFilter(new MaxLimitFilter(GroupBySameRoutesAndStops.TAG, 1)) ) ) ); @@ -560,7 +561,7 @@ private List buildGroupByTripIdAndDistanceFilters() { GroupByAllSameStations::new, List.of( new SortingFilter(generalizedCostComparator()), - new DeletionFlaggingFilter(new MaxLimitFilter(innerGroupName, 1)) + new RemoveFilter(new MaxLimitFilter(innerGroupName, 1)) ) ) ); @@ -592,8 +593,8 @@ private ListSection deduplicateSection() { private static void addRmFilter( List filters, - ItineraryDeletionFlagger removeFilter + RemoveItineraryFlagger removeFilter ) { - filters.add(new DeletionFlaggingFilter(removeFilter)); + filters.add(new RemoveFilter(removeFilter)); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/GroupBySimilarity.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java similarity index 96% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/GroupBySimilarity.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java index e98587d9f3f..0f671524a06 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/GroupBySimilarity.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/GroupBySimilarity.java @@ -1,6 +1,7 @@ -package org.opentripplanner.routing.algorithm.filterchain; +package org.opentripplanner.routing.algorithm.filterchain.api; import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChainBuilder; /** * Group itineraries by similarity and reduce the number of itineraries down to an given maximum diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java index 4365131bc8c..3d0f550eb0b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java @@ -4,7 +4,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupBySameFirstOrLastTrip; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * This filter ensures that no more than one itinerary begins or ends with same trip. @@ -13,7 +13,7 @@ * Uses {@link GroupBySameFirstOrLastTrip}. * for matching itineraries. */ -public class SameFirstOrLastTripFilter implements ItineraryDeletionFlagger { +public class SameFirstOrLastTripFilter implements RemoveItineraryFlagger { @Override public String name() { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java index f77512f54f4..b8c7991f30f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java @@ -2,13 +2,13 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * Flags the itineraries at the end of the list for removal. The list should be sorted on the * desired key before this filter is applied. */ -public class MaxLimitFilter implements ItineraryDeletionFlagger { +public class MaxLimitFilter implements RemoveItineraryFlagger { private final String name; private final int maxLimit; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java index 56f094386b3..f7aad5f2b59 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; @@ -20,7 +20,7 @@ * * @see ItineraryFilterPreferences#nonTransitGeneralizedCostLimit() */ -public class NonTransitGeneralizedCostFilter implements ItineraryDeletionFlagger { +public class NonTransitGeneralizedCostFilter implements RemoveItineraryFlagger { private final CostLinearFunction costLimitFunction; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java index 89f82962f32..1aa942afa19 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java @@ -4,7 +4,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * Flag all itineraries after the provided limit. This flags the itineraries at the end of the list @@ -12,7 +12,7 @@ *

    * This filter reports information about the removed itineraries in the results consumer. */ -public class NumItinerariesFilter implements ItineraryDeletionFlagger { +public class NumItinerariesFilter implements RemoveItineraryFlagger { public static final String TAG = "number-of-itineraries-filter"; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java index 4b316f9802a..74a395379c8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.transit.model.timetable.Trip; /** @@ -17,7 +17,7 @@ * TransitGeneralizedCostFilter}, but is used together with {@link GroupByFilter} to filter within * the groups. */ -public class OtherThanSameLegsMaxGeneralizedCostFilter implements ItineraryDeletionFlagger { +public class OtherThanSameLegsMaxGeneralizedCostFilter implements RemoveItineraryFlagger { /** * How much higher cost do we allow for the non-shared legs before we filter out the itinerary. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java index 374bc33164c..bbaba7be22e 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java @@ -4,7 +4,7 @@ import java.time.Instant; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * This filter will remove all itineraries that are outside the search-window. In some @@ -15,7 +15,7 @@ * Itineraries matching the start(earliest-departure-time) are included and itineraries matching * the end(latest-departure-time) are not. The filter is {@code [inclusive, exclusive]}. */ -public class OutsideSearchWindowFilter implements ItineraryDeletionFlagger { +public class OutsideSearchWindowFilter implements RemoveItineraryFlagger { public static final String TAG = "outside-search-window"; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java index 2c4f79d45e5..1e9813735ef 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * This class is used to enforce the cut/limit between two pages. It removes potential duplicates @@ -20,7 +20,7 @@ * potential duplicates will appear at the bottom of the list. If the previous results were cropped * at the bottom, then the potential duplicates will appear at the top of the list. */ -public class PagingFilter implements ItineraryDeletionFlagger { +public class PagingFilter implements RemoveItineraryFlagger { public static final String TAG = "paging-filter"; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java index 9293c4d4072..370d9d57984 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java @@ -3,7 +3,7 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * This is used to filter out bike rental itineraries that contain mostly walking. The value @@ -12,7 +12,7 @@ *

    * This filter is turned off by default (bikeRentalDistanceRatio == 0) */ -public class RemoveBikerentalWithMostlyWalkingFilter implements ItineraryDeletionFlagger { +public class RemoveBikerentalWithMostlyWalkingFilter implements RemoveItineraryFlagger { private final double bikeRentalDistanceRatio; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java index c5ba7ff8c2d..1c14de7686b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.street.search.TraverseMode; /** @@ -15,7 +15,7 @@ *

    * This filter is turned off by default (parkAndRideDurationRatio == 0) */ -public class RemoveParkAndRideWithMostlyWalkingFilter implements ItineraryDeletionFlagger { +public class RemoveParkAndRideWithMostlyWalkingFilter implements RemoveItineraryFlagger { private final double parkAndRideDurationRatio; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java index e3d90c24a83..84a6f4e75b3 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** @@ -13,7 +13,7 @@ * it exist). If an itinerary cost exceeds the limit computed from the best all-the-way-on-street itinerary, then the * transit itinerary is removed. */ -public class RemoveTransitIfStreetOnlyIsBetterFilter implements ItineraryDeletionFlagger { +public class RemoveTransitIfStreetOnlyIsBetterFilter implements RemoveItineraryFlagger { private final CostLinearFunction costLimitFunction; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java index 7062957e500..f57d065e35a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java @@ -4,12 +4,12 @@ import java.util.OptionalInt; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * Filter itineraries which have a higher generalized-cost than a pure walk itinerary. */ -public class RemoveTransitIfWalkingIsBetterFilter implements ItineraryDeletionFlagger { +public class RemoveTransitIfWalkingIsBetterFilter implements RemoveItineraryFlagger { /** * Required for {@link org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain}, diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java index a1a01dfc159..3ec64f4b731 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java @@ -2,12 +2,12 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * Filter itineraries and remove all itineraries where all legs are walking. */ -public class RemoveWalkOnlyFilter implements ItineraryDeletionFlagger { +public class RemoveWalkOnlyFilter implements RemoveItineraryFlagger { @Override public String name() { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java index 9e8a79004d7..b3e6fb1c01d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java @@ -7,7 +7,7 @@ import org.opentripplanner.framework.lang.IntUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** @@ -15,7 +15,7 @@ * computed by the {@link #costLimitFunction} plus the wait cost given by * {@link TransitGeneralizedCostFilter#getWaitTimeCost}. */ -public class TransitGeneralizedCostFilter implements ItineraryDeletionFlagger { +public class TransitGeneralizedCostFilter implements RemoveItineraryFlagger { private final CostLinearFunction costLimitFunction; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/errorhandling/RoutingErrorsAttacher.java similarity index 95% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/errorhandling/RoutingErrorsAttacher.java index 532868019eb..c95ad4e9ff1 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/errorhandling/RoutingErrorsAttacher.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain; +package org.opentripplanner.routing.algorithm.filterchain.framework.errorhandling; import static org.opentripplanner.routing.api.response.InputField.DATE_TIME; import static org.opentripplanner.routing.api.response.RoutingErrorCode.NO_TRANSIT_CONNECTION_IN_SEARCH_WINDOW; @@ -18,7 +18,7 @@ * Computes {@link org.opentripplanner.routing.api.response.RoutingError} instances from itinerary * before and after they have been through the filter chain. */ -class RoutingErrorsAttacher { +public class RoutingErrorsAttacher { /** * Computes error codes from the itineraries. @@ -28,7 +28,7 @@ class RoutingErrorsAttacher { * have the {@link org.opentripplanner.model.SystemNotice}s to look up * the error from. */ - static List computeErrors( + public static List computeErrors( List originalItineraries, List filteredItineraries ) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DeletionFlaggingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java similarity index 86% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DeletionFlaggingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java index c3b0fd66c45..b53edf05a79 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DeletionFlaggingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java @@ -5,19 +5,19 @@ import java.util.stream.Collectors; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** * This class is responsible for flagging itineraries for deletion based on a predicate in the * supplied ItineraryDeletionFlagger. The itineraries are not actually deleted at this point, just * flagged. They are typically deleted later if debug mode is disabled. */ -public class DeletionFlaggingFilter implements ItineraryListFilter { +public class RemoveFilter implements ItineraryListFilter { - private final ItineraryDeletionFlagger flagger; + private final RemoveItineraryFlagger flagger; - public DeletionFlaggingFilter(ItineraryDeletionFlagger flagger) { + public RemoveFilter(RemoveItineraryFlagger flagger) { this.flagger = flagger; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDeletionFlagger.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java similarity index 94% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDeletionFlagger.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java index ba33971988f..4918f440d1f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDeletionFlagger.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/RemoveItineraryFlagger.java @@ -16,7 +16,7 @@ *

  • {@link #flagForRemoval(List)}}) - If you need more than one itinerary to decide which to delete.
  • * */ -public interface ItineraryDeletionFlagger { +public interface RemoveItineraryFlagger { /** * A name used for debugging the itinerary list filter chain. *

    @@ -47,7 +47,7 @@ default List flagForRemoval(List itineraries) { /** * Should itineraries already marked for deletion by previous deletionflagger be removed from the - * list passed to {@link ItineraryDeletionFlagger#flagForRemoval(List)}. The default value + * list passed to {@link RemoveItineraryFlagger#flagForRemoval(List)}. The default value * is true, as usually the already removed itineraries are not needed further in the filter * chain. */ diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java index 76f9146f522..1a2469de595 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java @@ -9,9 +9,9 @@ import org.opentripplanner.ext.ridehailing.RideHailingFilter; import org.opentripplanner.ext.stopconsolidation.ConsolidatedStopNameFilter; import org.opentripplanner.framework.application.OTPFeature; -import org.opentripplanner.routing.algorithm.filterchain.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChainBuilder; +import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java index 1ce1aec36bd..0591ae7ce4e 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java @@ -30,6 +30,7 @@ import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.TestItineraryBuilder; import org.opentripplanner.routing.alertpatch.StopCondition; +import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.response.RoutingError; import org.opentripplanner.routing.api.response.RoutingErrorCode; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java index eace7bc5cd9..215d04aef67 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java @@ -9,6 +9,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.errorhandling.RoutingErrorsAttacher; import org.opentripplanner.routing.api.response.RoutingErrorCode; class RoutingErrorsAttacherTest implements PlanTestConstants { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java index 87cd29167c1..8b6fea0e029 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java @@ -10,8 +10,8 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DeletionFlaggingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; @@ -41,7 +41,7 @@ public void aSimpleTestGroupByMatchingTripIdsNoMerge() { assertFalse(i2a.isFlaggedForDeletion()); assertTrue(i2b.isFlaggedForDeletion()); - // Remove an none existing set of tags + // Remove a none existing set of tags i2b.removeDeletionFlags(Set.of("ANY_TAG")); assertTrue(i2b.isFlaggedForDeletion()); @@ -101,9 +101,7 @@ private GroupByFilter createFilter(int maxNumberOfItinerariesPrGroup) i -> new AGroupId(i.firstLeg().getTrip().getId().getId()), List.of( new SortingFilter(SortOrderComparator.defaultComparatorDepartAfter()), - new DeletionFlaggingFilter( - new MaxLimitFilter(TEST_FILTER_TAG, maxNumberOfItinerariesPrGroup) - ) + new RemoveFilter(new MaxLimitFilter(TEST_FILTER_TAG, maxNumberOfItinerariesPrGroup)) ) ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java index bb881bdc07d..1541afc623b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDeletionFlagger; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; public class RemoveTransitIfStreetOnlyIsBetterFilterTest implements PlanTestConstants { @@ -21,7 +21,7 @@ public void filterAwayNothingIfNoWalking() { Itinerary i2 = newItinerary(A).rail(110, 6, 9, E).build(); // When: - ItineraryDeletionFlagger flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( + RemoveItineraryFlagger flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( CostLinearFunction.of(Duration.ofSeconds(200), 1.2) ); List result = flagger.removeMatchesForTest(List.of(i1, i2)); @@ -49,7 +49,7 @@ public void filterAwayLongTravelTimeWithoutWaitTime() { i2.setGeneralizedCost(360); // When: - ItineraryDeletionFlagger flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( + RemoveItineraryFlagger flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( CostLinearFunction.of(Duration.ofSeconds(60), 1.2) ); List result = flagger.removeMatchesForTest(List.of(i2, bicycle, walk, i1)); From 07158aff74ff58b9a2a5fb276a760095e36aeb65 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 15:03:22 +0100 Subject: [PATCH 054/356] refactor: Move filter-chain supporting classes to framework.filterchain package --- .../algorithm/filterchain/ItineraryListFilterChain.java | 3 ++- .../filterchain/ItineraryListFilterChainBuilder.java | 1 + .../{ => framework/filterchain}/DeleteResultHandler.java | 4 ++-- .../{errorhandling => filterchain}/RoutingErrorsAttacher.java | 2 +- .../{ => framework/filterchain}/DeleteResultHandlerTest.java | 2 +- .../filterchain}/RoutingErrorsAttacherTest.java | 3 +-- 6 files changed, 8 insertions(+), 7 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework/filterchain}/DeleteResultHandler.java (91%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/{errorhandling => filterchain}/RoutingErrorsAttacher.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework/filterchain}/DeleteResultHandlerTest.java (98%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework/filterchain}/RoutingErrorsAttacherTest.java (91%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java index 744e7b80906..cbea827e52b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.java @@ -3,7 +3,8 @@ import java.util.ArrayList; import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.errorhandling.RoutingErrorsAttacher; +import org.opentripplanner.routing.algorithm.filterchain.framework.filterchain.DeleteResultHandler; +import org.opentripplanner.routing.algorithm.filterchain.framework.filterchain.RoutingErrorsAttacher; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.api.response.RoutingError; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 3ee85669381..1a7ff032e20 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -39,6 +39,7 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filterchain.DeleteResultHandler; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByAllSameStations; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByDistance; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupBySameRoutesAndStops; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java index 2bd26c6b7d4..089bf44ccd1 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandler.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain; +package org.opentripplanner.routing.algorithm.filterchain.framework.filterchain; import java.util.List; import java.util.function.Predicate; @@ -11,7 +11,7 @@ * This class will remove itineraries from the list which are flagged for deletion by the * filters. */ -class DeleteResultHandler { +public class DeleteResultHandler { private final ItineraryFilterDebugProfile debug; private final int numOfItineraries; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/errorhandling/RoutingErrorsAttacher.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/errorhandling/RoutingErrorsAttacher.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java index c95ad4e9ff1..0ae541e739a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/errorhandling/RoutingErrorsAttacher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.framework.errorhandling; +package org.opentripplanner.routing.algorithm.filterchain.framework.filterchain; import static org.opentripplanner.routing.api.response.InputField.DATE_TIME; import static org.opentripplanner.routing.api.response.RoutingErrorCode.NO_TRANSIT_CONNECTION_IN_SEARCH_WINDOW; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java similarity index 98% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java index 32bcae2b86f..bea81f773aa 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/DeleteResultHandlerTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain; +package org.opentripplanner.routing.algorithm.filterchain.framework.filterchain; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.PlanTestConstants.A; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java index 215d04aef67..0330aca3683 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/RoutingErrorsAttacherTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain; +package org.opentripplanner.routing.algorithm.filterchain.framework.filterchain; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; @@ -9,7 +9,6 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.errorhandling.RoutingErrorsAttacher; import org.opentripplanner.routing.api.response.RoutingErrorCode; class RoutingErrorsAttacherTest implements PlanTestConstants { From 0c9aef580cc13bd037094a994956518bc0abe4dc Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 15:05:15 +0100 Subject: [PATCH 055/356] refactor: Move images into images package --- .../{ => images}/ItineraryListFilterChain.excalidraw | 0 .../filterchain/{ => images}/ItineraryListFilterChain.svg | 0 .../opentripplanner/routing/algorithm/filterchain/package.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => images}/ItineraryListFilterChain.excalidraw (100%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{ => images}/ItineraryListFilterChain.svg (100%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.excalidraw b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.excalidraw rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.svg b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg similarity index 100% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChain.svg rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md index 7630f96b2df..7441e5f0849 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md @@ -7,7 +7,7 @@ chain is also responsible for creating routing errors, if no itineraries remain Itineraries are flagged for deletion, but not actually deleted when debugging is turned on. When debugging is off, the chain actually removes those itineraries that were flagged for deletion. -![Architecture diagram](ItineraryListFilterChain.svg) +![Architecture diagram](images/ItineraryListFilterChain.svg) There are four types of filters, which can be included in the filter chain. The same type of filter can appear multiple times. From d10e52c3c647181e6591b5193dda2de93f03c6e9 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 15:33:45 +0100 Subject: [PATCH 056/356] refactor: Fix dependency, set to: filterchain -> pagecursor --- .../routing/algorithm/RoutingWorker.java | 8 +++---- .../ItineraryListFilterChainBuilder.java | 23 ++++++++---------- .../filters/NumItinerariesFilter.java | 15 ++++++------ .../mapping/PagingServiceFactory.java | 6 ++--- .../RouteRequestToFilterChainMapper.java | 6 ++--- .../service/paging/PagingService.java | 24 ++++++++----------- .../filters/NumItinerariesFilterTest.java | 3 ++- .../service/paging/TestDriver.java | 10 ++++---- 8 files changed, 44 insertions(+), 51 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java b/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java index bb688f27be9..06ceaeebeb2 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java @@ -16,10 +16,10 @@ import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.api.request.SearchParams; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.algorithm.mapping.PagingServiceFactory; import org.opentripplanner.routing.algorithm.mapping.RouteRequestToFilterChainMapper; import org.opentripplanner.routing.algorithm.mapping.RoutingResponseMapper; @@ -65,7 +65,7 @@ public class RoutingWorker { private final ZonedDateTime transitSearchTimeZero; private final AdditionalSearchDays additionalSearchDays; private SearchParams raptorSearchParamsUsed = null; - private NumItinerariesFilterResults numItinerariesFilterResults = null; + private PageCursorInput pageCursorInput = null; public RoutingWorker(OtpServerRequestContext serverContext, RouteRequest request, ZoneId zoneId) { request.applyPageCursor(); @@ -137,7 +137,7 @@ public RoutingResponse route() { searchWindowUsed(), emptyDirectModeHandler.removeWalkAllTheWayResults() || removeWalkAllTheWayResultsFromDirectFlex, - it -> numItinerariesFilterResults = it + it -> pageCursorInput = it ); filteredItineraries = filterChain.filter(itineraries); @@ -283,7 +283,7 @@ private PagingService createPagingService(List itineraries) { serverContext.raptorTuningParameters(), request, raptorSearchParamsUsed, - numItinerariesFilterResults, + pageCursorInput, itineraries ); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 1a7ff032e20..305531c3f67 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -17,6 +17,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.algorithm.filterchain.filter.RemoveDeletionFlagForLeastTransfersItinerary; @@ -25,7 +26,6 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.NonTransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.algorithm.filterchain.filters.OtherThanSameLegsMaxGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; @@ -72,7 +72,7 @@ public class ItineraryListFilterChainBuilder { private double bikeRentalDistanceRatio; private double parkAndRideDurationRatio; private CostLinearFunction nonTransitGeneralizedCostLimit; - private Consumer numItinerariesFilterResultsConsumer; + private Consumer pageCursorInputSubscriber; private Instant earliestDepartureTime = null; private Duration searchWindow = null; private boolean accessibilityScore; @@ -264,18 +264,15 @@ public ItineraryListFilterChainBuilder withSearchWindow( } /** - * If the maximum number of itineraries is exceeded, then the excess itineraries are removed. To - * get notified about this a consumer can be added. The 'maxLimit' check is the last thing - * happening in the filter-chain after the final sort. So, if another filter removes an itinerary, - * the itinerary is not considered with respect to the {@link #withMaxNumberOfItineraries(int)} - * limit. - * - * @param numItinerariesFilterResultsConsumer the consumer to notify when elements are removed. + * If the maximum number of itineraries is exceeded, then the excess itineraries are removed. + * The paging service needs this information to adjust the paging cursor. The 'maxLimit' check is + * the last thing* happening in the filter-chain after the final sort. So, if another filter + * removes an itinerary, the itinerary is not considered with respect to this limit. */ - public ItineraryListFilterChainBuilder withNumItinerariesFilterResultsConsumer( - Consumer numItinerariesFilterResultsConsumer + public ItineraryListFilterChainBuilder withPageCursorInputSubscriber( + Consumer pageCursorInputSubscriber ) { - this.numItinerariesFilterResultsConsumer = numItinerariesFilterResultsConsumer; + this.pageCursorInputSubscriber = pageCursorInputSubscriber; return this; } @@ -469,7 +466,7 @@ public ItineraryListFilterChain build() { new NumItinerariesFilter( maxNumberOfItineraries, maxNumberOfItinerariesCropSection, - numItinerariesFilterResultsConsumer + pageCursorInputSubscriber ) ); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java index 1aa942afa19..570071308cd 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java @@ -4,6 +4,7 @@ import java.util.function.Consumer; import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** @@ -16,23 +17,21 @@ public class NumItinerariesFilter implements RemoveItineraryFlagger { public static final String TAG = "number-of-itineraries-filter"; - private static final Consumer IGNORE_SUBSCRIBER = i -> {}; + private static final Consumer IGNORE_SUBSCRIBER = i -> {}; private final int maxLimit; private final ListSection cropSection; - private final Consumer numItinerariesFilterResultsConsumer; + private final Consumer pageCursorInputSubscriber; public NumItinerariesFilter( int maxLimit, ListSection cropSection, - Consumer numItinerariesFilterResultsConsumer + Consumer pageCursorInputSubscriber ) { this.maxLimit = maxLimit; this.cropSection = cropSection; - this.numItinerariesFilterResultsConsumer = - numItinerariesFilterResultsConsumer == null - ? IGNORE_SUBSCRIBER - : numItinerariesFilterResultsConsumer; + this.pageCursorInputSubscriber = + pageCursorInputSubscriber == null ? IGNORE_SUBSCRIBER : pageCursorInputSubscriber; } @Override @@ -59,7 +58,7 @@ public List flagForRemoval(List itineraries) { itinerariesToKeep = itineraries.subList(0, maxLimit); } - numItinerariesFilterResultsConsumer.accept( + pageCursorInputSubscriber.accept( new NumItinerariesFilterResults(itinerariesToKeep, itinerariesToRemove, cropSection) ); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java index 3e3ebc2967c..ec58d444914 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/PagingServiceFactory.java @@ -4,9 +4,9 @@ import java.time.Instant; import java.util.List; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.api.request.SearchParams; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitTuningParameters; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.service.paging.PagingService; @@ -19,7 +19,7 @@ public static PagingService createPagingService( RaptorTuningParameters raptorTuningParameters, RouteRequest request, SearchParams raptorSearchParamsUsed, - NumItinerariesFilterResults numItinerariesFilterResults, + PageCursorInput pageCursorInput, List itineraries ) { return new PagingService( @@ -33,7 +33,7 @@ public static PagingService createPagingService( request.arriveBy(), request.numItineraries(), request.pageCursor(), - numItinerariesFilterResults, + pageCursorInput, itineraries ); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java index 1a2469de595..2f1c531e102 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java @@ -9,10 +9,10 @@ import org.opentripplanner.ext.ridehailing.RideHailingFilter; import org.opentripplanner.ext.stopconsolidation.ConsolidatedStopNameFilter; import org.opentripplanner.framework.application.OTPFeature; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChainBuilder; import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; @@ -32,7 +32,7 @@ public static ItineraryListFilterChain createFilterChain( Instant earliestDepartureTimeUsed, Duration searchWindowUsed, boolean removeWalkAllTheWayResults, - Consumer maxLimitFilterResultsSubscriber + Consumer pageCursorInputSubscriber ) { var builder = new ItineraryListFilterChainBuilder(request.itinerariesSortOrder()); @@ -89,7 +89,7 @@ public static ItineraryListFilterChain createFilterChain( context.transitService()::getMultiModalStationForStation ) .withSearchWindow(earliestDepartureTimeUsed, searchWindowUsed) - .withNumItinerariesFilterResultsConsumer(maxLimitFilterResultsSubscriber) + .withPageCursorInputSubscriber(pageCursorInputSubscriber) .withRemoveWalkAllTheWayResults(removeWalkAllTheWayResults) .withRemoveTransitIfWalkingIsBetter(true) .withDebugEnabled(params.debug()); diff --git a/src/main/java/org/opentripplanner/service/paging/PagingService.java b/src/main/java/org/opentripplanner/service/paging/PagingService.java index 2734049e940..3aa8033105a 100644 --- a/src/main/java/org/opentripplanner/service/paging/PagingService.java +++ b/src/main/java/org/opentripplanner/service/paging/PagingService.java @@ -11,8 +11,8 @@ import org.opentripplanner.model.plan.paging.PagingSearchWindowAdjuster; import org.opentripplanner.model.plan.paging.cursor.PageCursor; import org.opentripplanner.model.plan.paging.cursor.PageCursorFactory; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.model.plan.paging.cursor.PageType; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.api.response.TripSearchMetadata; public class PagingService { @@ -24,7 +24,7 @@ public class PagingService { private final boolean arriveBy; private final int numberOfItineraries; private final PageCursor pageCursor; - private final NumItinerariesFilterResults numItinerariesFilterResults; + private final PageCursorInput pageCursorInput; private final PagingSearchWindowAdjuster searchWindowAdjuster; private final List itineraries; @@ -42,7 +42,7 @@ public PagingService( boolean arriveBy, int numberOfItineraries, @Nullable PageCursor pageCursor, - NumItinerariesFilterResults numItinerariesFilterResults, + PageCursorInput pageCursorInput, List itineraries ) { this.searchWindowUsed = searchWindowUsed; @@ -53,7 +53,7 @@ public PagingService( this.numberOfItineraries = numberOfItineraries; this.pageCursor = pageCursor; - this.numItinerariesFilterResults = numItinerariesFilterResults; + this.pageCursorInput = pageCursorInput; this.itineraries = Objects.requireNonNull(itineraries); this.searchWindowAdjuster = createSearchWindowAdjuster( @@ -98,9 +98,9 @@ private Duration calculateSearchWindowNextSearch() { } // SearchWindow cropped -> decrease search-window - if (numItinerariesFilterResults != null) { + if (pageCursorInput != null) { boolean cropSWHead = doCropSearchWindowAtTail(); - Instant rmItineraryStartTime = numItinerariesFilterResults.pageCut().startTimeAsInstant(); + Instant rmItineraryStartTime = pageCursorInput.pageCut().startTimeAsInstant(); return searchWindowAdjuster.decreaseSearchWindow( searchWindowUsed, @@ -125,15 +125,11 @@ private Duration calculateSearchWindowNextSearch() { } private Instant lastKeptDepartureTime() { - return numItinerariesFilterResults == null - ? null - : numItinerariesFilterResults.pageCut().startTimeAsInstant(); + return pageCursorInput == null ? null : pageCursorInput.pageCut().startTimeAsInstant(); } private Instant firstKeptDepartureTime() { - return numItinerariesFilterResults == null - ? null - : numItinerariesFilterResults.pageCut().startTimeAsInstant(); + return pageCursorInput == null ? null : pageCursorInput.pageCut().startTimeAsInstant(); } private PagingSearchWindowAdjuster createSearchWindowAdjuster( @@ -189,8 +185,8 @@ private PageCursorFactory mapIntoPageCursorFactory(@Nullable PageType currentPag searchWindowUsed ); - if (numItinerariesFilterResults != null) { - factory = factory.withRemovedItineraries(numItinerariesFilterResults); + if (pageCursorInput != null) { + factory = factory.withRemovedItineraries(pageCursorInput); } return factory; } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java index 9ef7da991ff..2a48b08c22f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; public class NumItinerariesFilterTest { @@ -17,7 +18,7 @@ public class NumItinerariesFilterTest { private static final Itinerary i2 = newItinerary(A).bicycle(6, 8, B).build(); private static final Itinerary i3 = newItinerary(A).bus(21, 7, 9, B).build(); - private NumItinerariesFilterResults subscribeResult = null; + private PageCursorInput subscribeResult = null; @Test public void name() { diff --git a/src/test/java/org/opentripplanner/service/paging/TestDriver.java b/src/test/java/org/opentripplanner/service/paging/TestDriver.java index 70e47f31a75..8b1e634f186 100644 --- a/src/test/java/org/opentripplanner/service/paging/TestDriver.java +++ b/src/test/java/org/opentripplanner/service/paging/TestDriver.java @@ -11,8 +11,8 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.paging.cursor.PageCursor; +import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilterResults; import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; @@ -29,7 +29,7 @@ final class TestDriver { private final Instant lat; private final SortOrder sortOrder; private final ListSection cropSection; - private final NumItinerariesFilterResults results; + private final PageCursorInput results; public TestDriver( int nResults, @@ -40,7 +40,7 @@ public TestDriver( Instant lat, SortOrder sortOrder, ListSection cropSection, - NumItinerariesFilterResults results + PageCursorInput results ) { this.nResults = nResults; this.searchWindow = searchWindow; @@ -106,7 +106,7 @@ boolean arrivedBy() { return !sortOrder.isSortedByAscendingArrivalTime(); } - NumItinerariesFilterResults filterResults() { + PageCursorInput filterResults() { return results; } @@ -163,7 +163,7 @@ private static TestDriver createNewDriver( } // Filter nResults - var filterResultBox = new Box(); + var filterResultBox = new Box(); var maxNumFilter = new NumItinerariesFilter(nResults, cropItineraries, filterResultBox::set); kept = maxNumFilter.removeMatchesForTest(kept); From 547a8c191e4b66ddf65aea93a9ed6bb74b28fee0 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 16:07:44 +0100 Subject: [PATCH 057/356] refactor: Move tests same package as subject (framework.filter) --- .../{ => framework}/filter/GroupByFilterTest.java | 5 +---- .../{ => framework}/filter/SortingFilterTest.java | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/filter/GroupByFilterTest.java (93%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{ => framework}/filter/SortingFilterTest.java (86%) diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java index 8b6fea0e029..1db143739e3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -10,9 +10,6 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java similarity index 86% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java index 550b85d92a8..9e03b5a2ace 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SortingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/SortingFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; @@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; public class SortingFilterTest implements PlanTestConstants { From 3ba31ce6e7efbfec2d2e317fabda4a0462f81f71 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 16:08:14 +0100 Subject: [PATCH 058/356] refactor: Move from filter to filters --- .../filterchain/ItineraryListFilterChainBuilder.java | 6 +++--- .../RemoveDeletionFlagForLeastTransfersItinerary.java | 2 +- .../{filter => filters}/SameFirstOrLastTripFilter.java | 2 +- .../filterchain/{filter => filters}/TransitAlertFilter.java | 2 +- .../{filter => filters}/SameFirstOrLastTripFilterTest.java | 4 ++-- .../{filter => filters}/TransitAlertFilterTest.java | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{filter => filters}/RemoveDeletionFlagForLeastTransfersItinerary.java (99%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{filter => filters}/SameFirstOrLastTripFilter.java (99%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{filter => filters}/TransitAlertFilter.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{filter => filters}/SameFirstOrLastTripFilterTest.java (96%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{filter => filters}/TransitAlertFilterTest.java (99%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 305531c3f67..6d7089df24b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -20,9 +20,6 @@ import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; -import org.opentripplanner.routing.algorithm.filterchain.filter.RemoveDeletionFlagForLeastTransfersItinerary; -import org.opentripplanner.routing.algorithm.filterchain.filter.SameFirstOrLastTripFilter; -import org.opentripplanner.routing.algorithm.filterchain.filter.TransitAlertFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.NonTransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; @@ -30,11 +27,14 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveBikerentalWithMostlyWalkingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveDeletionFlagForLeastTransfersItinerary; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveItinerariesWithShortStreetLeg; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveParkAndRideWithMostlyWalkingFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveWalkOnlyFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.SameFirstOrLastTripFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.TransitAlertFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveDeletionFlagForLeastTransfersItinerary.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveDeletionFlagForLeastTransfersItinerary.java index 8ffd9986708..a4626aa467b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/RemoveDeletionFlagForLeastTransfersItinerary.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveDeletionFlagForLeastTransfersItinerary.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.numberOfTransfersComparator; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilter.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilter.java index 3d0f550eb0b..233edb0d11f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilter.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilter.java index c50f7c17957..4f9648bca74 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.filters; import java.util.List; import java.util.function.Function; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilterTest.java similarity index 96% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilterTest.java index 3161d23a065..88ea9b12277 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/SameFirstOrLastTripFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilterTest.java @@ -1,7 +1,7 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.filters; +import static org.ejml.UtilEjml.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import java.util.List; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilterTest.java index aae59e8e4b6..83eb532a7eb 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filter/TransitAlertFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filter; +package org.opentripplanner.routing.algorithm.filterchain.filters; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.BUS_ROUTE; From ae6740f211894df492f55eababc5ca81166a45fd Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 16:19:57 +0100 Subject: [PATCH 059/356] refactor: Use absolute references in doc - avoid import dependencies --- .../org/opentripplanner/model/plan/ItinerarySortKey.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java index 9c4879b0184..0ad62927d9a 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java @@ -2,13 +2,13 @@ import java.time.Instant; import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; /** * This interface is used to sort itineraries and other instances that we might want to sort among - * itineraries. It is used in the {@link SortingFilter} as defined by the - * {@link SortOrderComparator}. + * itineraries. It is used in the + * {@link org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter} + * as defined by the + * {@link org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator}. *

    * The methods in this interface are NOT documented here, but in the Itinerary class. To keep it simple, this * interface should be kept in sync with method names in the itinerary. From a4c55067cb6a404283d4277b2e016576608ca9b5 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 16:23:04 +0100 Subject: [PATCH 060/356] refactor: The MaxLimitFilter is a reusable generic filter, move to framework --- .../algorithm/filterchain/ItineraryListFilterChainBuilder.java | 2 +- .../{filters => framework/filter}/MaxLimitFilter.java | 2 +- .../filterchain/framework/spi/ItineraryListFilter.java | 3 ++- .../filterchain/framework/filter/GroupByFilterTest.java | 1 - .../{filters => framework/filter}/MaxLimitFilterTest.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/{filters => framework/filter}/MaxLimitFilter.java (91%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/{filters => framework/filter}/MaxLimitFilterTest.java (95%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 6d7089df24b..d541d86e73d 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -20,7 +20,6 @@ import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; -import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.NonTransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.OtherThanSameLegsMaxGeneralizedCostFilter; @@ -37,6 +36,7 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.TransitAlertFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filterchain.DeleteResultHandler; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilter.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilter.java index b8c7991f30f..4c786455dba 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import java.util.List; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java index 7821779fabf..c56b4fe42c9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java @@ -2,6 +2,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; /** * Filter, sort or decorate itineraries. A filter can modify the elements in the list, but not the @@ -13,7 +14,7 @@ * chain. *

    * This allows decoration of each filter and makes it easier to reuse logic. Like the {@link - * org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter} is reused in + * MaxLimitFilter} is reused in * several places. */ public interface ItineraryListFilter { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java index 1db143739e3..8bf29be62fa 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java @@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.filters.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.GroupId; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilterTest.java similarity index 95% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilterTest.java index 86814b4fc27..2fa10761c36 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/MaxLimitFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; From 07407c2dbea858202181f06a1b92d03a7e60dbe8 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 16:46:04 +0100 Subject: [PATCH 061/356] refactor: group filters -> system --- .../ItineraryListFilterChainBuilder.java | 6 +++--- .../{ => system}/NumItinerariesFilter.java | 2 +- .../NumItinerariesFilterResults.java | 21 ++++++++----------- .../OutsideSearchWindowFilter.java | 2 +- .../filters/{ => system}/PagingFilter.java | 2 +- .../filterchain/DeleteResultHandler.java | 2 +- .../filterchain/RoutingErrorsAttacher.java | 2 +- .../NumItinerariesFilterTest.java | 2 +- .../OutsideSearchWindowFilterTest.java | 2 +- .../{ => system}/PagingFilterTest.java | 2 +- .../filterchain/DeleteResultHandlerTest.java | 4 ++-- .../service/paging/TestDriver.java | 6 +++--- 12 files changed, 25 insertions(+), 28 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/NumItinerariesFilter.java (99%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/NumItinerariesFilterResults.java (74%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/OutsideSearchWindowFilter.java (99%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/PagingFilter.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/NumItinerariesFilterTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/OutsideSearchWindowFilterTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => system}/PagingFilterTest.java (99%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index d541d86e73d..3f621eab908 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -21,10 +21,7 @@ import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.algorithm.filterchain.filters.NonTransitGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.OtherThanSameLegsMaxGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveBikerentalWithMostlyWalkingFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveDeletionFlagForLeastTransfersItinerary; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveItinerariesWithShortStreetLeg; @@ -35,6 +32,9 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.SameFirstOrLastTripFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.TransitAlertFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.PagingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java index 570071308cd..aed5eeb4f95 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import java.util.List; import java.util.function.Consumer; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterResults.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java similarity index 74% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterResults.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java index 04c8fcc039c..8b11be099f7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterResults.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterResults.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import java.time.Instant; import java.util.List; @@ -9,20 +9,19 @@ import org.opentripplanner.model.plan.ItinerarySortKey; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; -public class NumItinerariesFilterResults implements PageCursorInput { +/** + * The NumItinerariesFilter removes itineraries from a list of itineraries based on the number to + * keep and whether it should crop at the head or the tail of the list. The results class keeps + * the extreme endpoints of the sets of itineraries that were kept and removed, as well as more + * details about the first itinerary removed (bottom of the head, or top of the tail) and whether + * itineraries were cropped at the head or the tail. + */ +class NumItinerariesFilterResults implements PageCursorInput { private final Instant earliestRemovedDeparture; private final Instant latestRemovedDeparture; private final ItinerarySortKey pageCut; - private final ListSection cropSection; - /** - * The NumItinerariesFilter removes itineraries from a list of itineraries based on the number to - * keep and whether it should crop at the head or the tail of the list. The results class keeps - * the extreme endpoints of the sets of itineraries that were kept and removed, as well as more - * details about the first itinerary removed (bottom of the head, or top of the tail) and whether - * itineraries were cropped at the head or the tail. - */ public NumItinerariesFilterResults( List keptItineraries, List removedItineraries, @@ -40,7 +39,6 @@ public NumItinerariesFilterResults( } else { pageCut = ListUtils.last(keptItineraries); } - this.cropSection = cropSection; } @Override @@ -65,7 +63,6 @@ public String toString() { .addDateTime("earliestRemovedDeparture", earliestRemovedDeparture) .addDateTime("latestRemovedDeparture", latestRemovedDeparture) .addObjOp("pageCut", pageCut, ItinerarySortKey::keyAsString) - .addEnum("cropSection", cropSection) .toString(); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java index bbaba7be22e..ba3ef4b04f3 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import java.time.Duration; import java.time.Instant; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java similarity index 99% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java index 1e9813735ef..1ef109525f6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import java.util.Comparator; import java.util.List; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java index 089bf44ccd1..c713ed7ac46 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandler.java @@ -4,7 +4,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java index 0ae541e739a..a4bd423884c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java @@ -9,9 +9,9 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; import org.opentripplanner.routing.api.response.RoutingError; /** diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java index 2a48b08c22f..622482fe4b3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/NumItinerariesFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/NumItinerariesFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java index 2ce7bbccf8c..9752004560e 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OutsideSearchWindowFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/OutsideSearchWindowFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java index 82df57ee7a6..751dcc7ad3c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/PagingFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/PagingFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.system; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.framework.collection.ListUtils.first; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java index bea81f773aa..b7d91f734d2 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/DeleteResultHandlerTest.java @@ -21,8 +21,8 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; class DeleteResultHandlerTest { diff --git a/src/test/java/org/opentripplanner/service/paging/TestDriver.java b/src/test/java/org/opentripplanner/service/paging/TestDriver.java index 8b1e634f186..928fbaaf01d 100644 --- a/src/test/java/org/opentripplanner/service/paging/TestDriver.java +++ b/src/test/java/org/opentripplanner/service/paging/TestDriver.java @@ -12,9 +12,9 @@ import org.opentripplanner.model.plan.SortOrder; import org.opentripplanner.model.plan.paging.cursor.PageCursor; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; -import org.opentripplanner.routing.algorithm.filterchain.filters.NumItinerariesFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.OutsideSearchWindowFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.PagingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.PagingFilter; /** * This class simulate/mock the context the paging is operating in. From 201978ceede7952c91eb5bc02bfb706e06b45ce2 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 17:03:42 +0100 Subject: [PATCH 062/356] refactor: Simplify RemoveBikerentalWithMostlyWalkingFilter --- .../RemoveBikerentalWithMostlyWalkingFilter.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java index 370d9d57984..af77d181c30 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java @@ -28,10 +28,9 @@ public String name() { @Override public Predicate shouldBeFlaggedForRemoval() { return itinerary -> { - var containsTransit = itinerary - .getLegs() - .stream() - .anyMatch(l -> l != null && l.isTransitLeg()); + if(itinerary.hasTransit()) { + return false; + } double bikeRentalDistance = itinerary .getLegs() @@ -39,11 +38,10 @@ public Predicate shouldBeFlaggedForRemoval() { .filter(l -> l.getRentedVehicle() != null && l.getRentedVehicle()) .mapToDouble(Leg::getDistanceMeters) .sum(); - double totalDistance = itinerary.distanceMeters(); + double totalDistance = itinerary.distanceMeters(); return ( bikeRentalDistance != 0 && - !containsTransit && (bikeRentalDistance / totalDistance) <= bikeRentalDistanceRatio ); }; From 3f8abf080b3e492a44ee9e2d17fcd0c765aeb469 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 18:15:46 +0100 Subject: [PATCH 063/356] refactor: Go through the filters and update doc and package location --- .../ItineraryListFilterChainBuilder.java | 45 ++++++++++--------- .../TransitGeneralizedCostFilterParams.java | 2 +- .../RemoveBikeRentalWithMostlyWalking.java} | 11 +++-- ...sitItinerariesBasedOnGeneralizedCost.java} | 15 ++++--- ...oveParkAndRideWithMostlyWalkingFilter.java | 15 +++---- .../{ => street}/RemoveWalkOnlyFilter.java | 2 +- .../DecorateTransitAlert.java} | 6 +-- .../KeepItinerariesWithFewestTransfers.java} | 14 +++--- .../RemoveItinerariesWithShortStreetLeg.java | 7 ++- .../RemoveTransitIfStreetOnlyIsBetter.java} | 12 ++--- .../RemoveTransitIfWalkingIsBetter.java} | 6 +-- .../TransitGeneralizedCostFilter.java | 8 ++-- .../RemoveIfFirstOrLastTripIsTheSame.java} | 7 ++- ...eOtherThanSameLegsMaxGeneralizedCost.java} | 13 +++--- .../filterchain/RoutingErrorsAttacher.java | 8 ++-- ...RemoveBikeRentalWithMostlyWalkingTest.java | 4 +- ...emoveParkAndRideWithMostlyWalkingTest.java | 2 +- .../RemoveWalkOnlyFilterTest.java | 2 +- ...moveItinerariesWithShortStreetLegTest.java | 2 +- ...emoveTransitIfStreetOnlyIsBetterTest.java} | 8 ++-- .../RemoveTransitIfWalkingIsBetterTest.java | 6 +-- .../{ => transit}/TransitAlertFilterTest.java | 4 +- .../TransitGeneralizedCostFilterTest.java | 2 +- ...RemoveIfFirstOrLastTripIsTheSameTest.java} | 9 ++-- ...erThanSameLegsMaxGeneralizedCostTest.java} | 6 +-- .../RoutingErrorsAttacherTest.java | 4 +- 26 files changed, 113 insertions(+), 107 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{RemoveBikerentalWithMostlyWalkingFilter.java => street/RemoveBikeRentalWithMostlyWalking.java} (79%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{NonTransitGeneralizedCostFilter.java => street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java} (73%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => street}/RemoveParkAndRideWithMostlyWalkingFilter.java (86%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => street}/RemoveWalkOnlyFilter.java (98%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{TransitAlertFilter.java => transit/DecorateTransitAlert.java} (91%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{RemoveDeletionFlagForLeastTransfersItinerary.java => transit/KeepItinerariesWithFewestTransfers.java} (63%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => transit}/RemoveItinerariesWithShortStreetLeg.java (81%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{RemoveTransitIfStreetOnlyIsBetterFilter.java => transit/RemoveTransitIfStreetOnlyIsBetter.java} (79%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{RemoveTransitIfWalkingIsBetterFilter.java => transit/RemoveTransitIfWalkingIsBetter.java} (90%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => transit}/TransitGeneralizedCostFilter.java (88%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{SameFirstOrLastTripFilter.java => transit/group/RemoveIfFirstOrLastTripIsTheSame.java} (90%) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/{OtherThanSameLegsMaxGeneralizedCostFilter.java => transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java} (85%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => street}/RemoveBikeRentalWithMostlyWalkingTest.java (93%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => street}/RemoveParkAndRideWithMostlyWalkingTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => street}/RemoveWalkOnlyFilterTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => transit}/RemoveItinerariesWithShortStreetLegTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{RemoveTransitIfStreetOnlyIsBetterFilterTest.java => transit/RemoveTransitIfStreetOnlyIsBetterTest.java} (94%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => transit}/RemoveTransitIfWalkingIsBetterTest.java (91%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => transit}/TransitAlertFilterTest.java (94%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{ => transit}/TransitGeneralizedCostFilterTest.java (99%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{SameFirstOrLastTripFilterTest.java => transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java} (83%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/{OtherThanSameLegsMaxGeneralizedCostFilterTest.java => transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java} (83%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 3f621eab908..03065cc9f22 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -20,21 +20,21 @@ import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.api.GroupBySimilarity; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; -import org.opentripplanner.routing.algorithm.filterchain.filters.NonTransitGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.OtherThanSameLegsMaxGeneralizedCostFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveBikerentalWithMostlyWalkingFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveDeletionFlagForLeastTransfersItinerary; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveItinerariesWithShortStreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveParkAndRideWithMostlyWalkingFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveWalkOnlyFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.SameFirstOrLastTripFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.TransitAlertFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveBikeRentalWithMostlyWalking; +import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveNonTransitItinerariesBasedOnGeneralizedCost; +import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveParkAndRideWithMostlyWalkingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveWalkOnlyFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.PagingFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.DecorateTransitAlert; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.KeepItinerariesWithFewestTransfers; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveItinerariesWithShortStreetLeg; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfStreetOnlyIsBetter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfWalkingIsBetter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.group.RemoveIfFirstOrLastTripIsTheSame; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.group.RemoveOtherThanSameLegsMaxGeneralizedCost; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; @@ -362,7 +362,7 @@ public ItineraryListFilterChain build() { if (sameFirstOrLastTripFilter) { filters.add(new SortingFilter(generalizedCostComparator())); - addRmFilter(filters, new SameFirstOrLastTripFilter()); + addRmFilter(filters, new RemoveIfFirstOrLastTripIsTheSame()); } if (minBikeParkingDistance > 0) { @@ -384,7 +384,7 @@ public ItineraryListFilterChain build() { } if (transitAlertService != null) { - filters.add(new TransitAlertFilter(transitAlertService, getMultiModalStation)); + filters.add(new DecorateTransitAlert(transitAlertService, getMultiModalStation)); } // Filter transit itineraries on generalized-cost @@ -400,7 +400,10 @@ public ItineraryListFilterChain build() { // Filter non-transit itineraries on generalized-cost if (nonTransitGeneralizedCostLimit != null) { - addRmFilter(filters, new NonTransitGeneralizedCostFilter(nonTransitGeneralizedCostLimit)); + addRmFilter( + filters, + new RemoveNonTransitItinerariesBasedOnGeneralizedCost(nonTransitGeneralizedCostLimit) + ); } // Apply all absolute filters AFTER the groupBy filters. Absolute filters are filters that @@ -417,14 +420,12 @@ public ItineraryListFilterChain build() { if (removeTransitWithHigherCostThanBestOnStreetOnly != null) { addRmFilter( filters, - new RemoveTransitIfStreetOnlyIsBetterFilter( - removeTransitWithHigherCostThanBestOnStreetOnly - ) + new RemoveTransitIfStreetOnlyIsBetter(removeTransitWithHigherCostThanBestOnStreetOnly) ); } if (removeTransitIfWalkingIsBetter) { - addRmFilter(filters, new RemoveTransitIfWalkingIsBetterFilter()); + addRmFilter(filters, new RemoveTransitIfWalkingIsBetter()); } if (removeWalkAllTheWayResults) { @@ -432,7 +433,7 @@ public ItineraryListFilterChain build() { } if (bikeRentalDistanceRatio > 0) { - addRmFilter(filters, new RemoveBikerentalWithMostlyWalkingFilter(bikeRentalDistanceRatio)); + addRmFilter(filters, new RemoveBikeRentalWithMostlyWalking(bikeRentalDistanceRatio)); } if (parkAndRideDurationRatio > 0) { @@ -566,7 +567,7 @@ private List buildGroupByTripIdAndDistanceFilters() { } if (group.maxCostOtherLegsFactor > 1.0) { - var flagger = new OtherThanSameLegsMaxGeneralizedCostFilter(group.maxCostOtherLegsFactor); + var flagger = new RemoveOtherThanSameLegsMaxGeneralizedCost(group.maxCostOtherLegsFactor); sysTags.add(flagger.name()); addRmFilter(nested, flagger); } @@ -575,7 +576,7 @@ private List buildGroupByTripIdAndDistanceFilters() { addRmFilter(nested, new MaxLimitFilter(tag, group.maxNumOfItinerariesPerGroup)); - nested.add(new RemoveDeletionFlagForLeastTransfersItinerary(sysTags)); + nested.add(new KeepItinerariesWithFewestTransfers(sysTags)); groupByFilters.add( new GroupByFilter<>(it -> new GroupByDistance(it, group.groupByP), nested) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java index eb4085c5c0c..c909ff00db0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java @@ -1,7 +1,7 @@ package org.opentripplanner.routing.algorithm.filterchain.api; import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.routing.algorithm.filterchain.filters.TransitGeneralizedCostFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java similarity index 79% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java index af77d181c30..21cadf413ae 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikerentalWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalking.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; @@ -12,11 +12,11 @@ *

    * This filter is turned off by default (bikeRentalDistanceRatio == 0) */ -public class RemoveBikerentalWithMostlyWalkingFilter implements RemoveItineraryFlagger { +public class RemoveBikeRentalWithMostlyWalking implements RemoveItineraryFlagger { private final double bikeRentalDistanceRatio; - public RemoveBikerentalWithMostlyWalkingFilter(double bikeRentalDistanceRatio) { + public RemoveBikeRentalWithMostlyWalking(double bikeRentalDistanceRatio) { this.bikeRentalDistanceRatio = bikeRentalDistanceRatio; } @@ -28,7 +28,7 @@ public String name() { @Override public Predicate shouldBeFlaggedForRemoval() { return itinerary -> { - if(itinerary.hasTransit()) { + if (itinerary.hasTransit()) { return false; } @@ -41,8 +41,7 @@ public Predicate shouldBeFlaggedForRemoval() { double totalDistance = itinerary.distanceMeters(); return ( - bikeRentalDistance != 0 && - (bikeRentalDistance / totalDistance) <= bikeRentalDistanceRatio + bikeRentalDistance != 0 && (bikeRentalDistance / totalDistance) <= bikeRentalDistanceRatio ); }; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java similarity index 73% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java index f7aad5f2b59..427084a55f6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/NonTransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java @@ -1,30 +1,35 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import java.util.List; import java.util.OptionalInt; import java.util.stream.Collectors; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.routing.api.request.preference.ItineraryFilterPreferences; /** + * This filter remove none-transit itineraries with generalized-cost higher than the max-limit. + * The max-limit is computed based on the overall min-generalized-cost using the provided cost + * function. + *

    * This filter is similar to {@link TransitGeneralizedCostFilter}. There are some important * differences, however. It will only remove non-transit results, but ALL results can be used as a * basis for computing the cost limit. *

    - * This is needed so that we do not for example get walk legs that last several hours, when transit - * can take you to the destination much quicker. + * This will, for example, remove walk legs which last several hours, when transit can take you to + * the destination much quicker. *

    * * @see ItineraryFilterPreferences#nonTransitGeneralizedCostLimit() */ -public class NonTransitGeneralizedCostFilter implements RemoveItineraryFlagger { +public class RemoveNonTransitItinerariesBasedOnGeneralizedCost implements RemoveItineraryFlagger { private final CostLinearFunction costLimitFunction; - public NonTransitGeneralizedCostFilter(CostLinearFunction costLimitFunction) { + public RemoveNonTransitItinerariesBasedOnGeneralizedCost(CostLinearFunction costLimitFunction) { this.costLimitFunction = costLimitFunction; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java similarity index 86% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java index 1c14de7686b..2a9cefd0657 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import java.util.List; import java.util.function.Predicate; @@ -31,10 +31,9 @@ public String name() { @Override public Predicate shouldBeFlaggedForRemoval() { return itinerary -> { - var containsTransit = itinerary - .getLegs() - .stream() - .anyMatch(l -> l != null && l.isTransitLeg()); + if (itinerary.hasTransit()) { + return false; + } double carDuration = itinerary .getLegs() @@ -46,11 +45,7 @@ public Predicate shouldBeFlaggedForRemoval() { .sum(); double totalDuration = itinerary.getDuration().toSeconds(); - return ( - !containsTransit && - carDuration != 0 && - (carDuration / totalDuration) <= parkAndRideDurationRatio - ); + return (carDuration != 0 && (carDuration / totalDuration) <= parkAndRideDurationRatio); }; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java similarity index 98% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java index 3ec64f4b731..1a53b898931 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java similarity index 91% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java index 4f9648bca74..f70c68587ec 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import java.util.List; import java.util.function.Function; @@ -10,11 +10,11 @@ import org.opentripplanner.transit.model.site.MultiModalStation; import org.opentripplanner.transit.model.site.Station; -public class TransitAlertFilter implements ItineraryListFilter { +public class DecorateTransitAlert implements ItineraryListFilter { private final AlertToLegMapper alertToLegMapper; - public TransitAlertFilter( + public DecorateTransitAlert( TransitAlertService transitAlertService, Function getMultiModalStation ) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveDeletionFlagForLeastTransfersItinerary.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java similarity index 63% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveDeletionFlagForLeastTransfersItinerary.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java index a4626aa467b..3d1e6301786 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveDeletionFlagForLeastTransfersItinerary.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/KeepItinerariesWithFewestTransfers.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator.numberOfTransfersComparator; @@ -10,16 +10,16 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; /** - * This filter makes sure that the itinerary with the least amount of transfers is not marked for - * deletion. It iterates over the itineraries and removes the SystemNotice if it contains - * the provided set of {@code filterKeys}. The itinerary must match all {@code filterKeys}, and - * if so the given keys are removed. Other system-notices are ignored. + * This filter makes sure that the itinerary with the fewest transfers is not removed. + * It iterates over the itineraries and removes the SystemNotice if it contains the provided set + * of {@code filterKeys}. The itinerary must match all {@code filterKeys}, and if so the given + * keys are removed. Itineraries with other system notices are ignored. */ -public class RemoveDeletionFlagForLeastTransfersItinerary implements ItineraryListFilter { +public class KeepItinerariesWithFewestTransfers implements ItineraryListFilter { private final Set filterKeys; - public RemoveDeletionFlagForLeastTransfersItinerary(List filterKeys) { + public KeepItinerariesWithFewestTransfers(List filterKeys) { this.filterKeys = new HashSet<>(filterKeys); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java similarity index 81% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLeg.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java index 5223704bbea..c9254b246e7 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import java.util.List; import org.opentripplanner.model.plan.Itinerary; @@ -10,6 +10,11 @@ * This filter is useful if you want to remove those results where there is a short bicycle * leg followed by parking the bike and taking transit. In such a case you would not need a bike * could just walk to the stop instead. + *

    + * TODO: This filter build on assumptions that is more or less an implementation detail. The + * filter should compare itineraries and remove them if a condition is meet, not just + * assume that a better option exist. Perhaps the access and egress should be filtered + * instead of filtering the transit itineraries? */ public class RemoveItinerariesWithShortStreetLeg implements ItineraryListFilter { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java similarity index 79% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java index 84a6f4e75b3..bddf5238f23 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import java.util.List; import java.util.OptionalInt; @@ -9,15 +9,15 @@ import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** - * Filter itineraries based on generalizedCost, compared with a on-street-all-the-way itinerary(if - * it exist). If an itinerary cost exceeds the limit computed from the best all-the-way-on-street itinerary, then the - * transit itinerary is removed. + * Filter itineraries based on generalizedCost, compared with an on-street-all-the-way itinerary + * (if it exists). If an itinerary cost exceeds the limit computed from the best + * all-the-way-on-street itinerary, then the transit itinerary is removed. */ -public class RemoveTransitIfStreetOnlyIsBetterFilter implements RemoveItineraryFlagger { +public class RemoveTransitIfStreetOnlyIsBetter implements RemoveItineraryFlagger { private final CostLinearFunction costLimitFunction; - public RemoveTransitIfStreetOnlyIsBetterFilter(CostLinearFunction costLimitFunction) { + public RemoveTransitIfStreetOnlyIsBetter(CostLinearFunction costLimitFunction) { this.costLimitFunction = costLimitFunction; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java index f57d065e35a..cf4d102c11a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import java.util.List; import java.util.OptionalInt; @@ -7,9 +7,9 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** - * Filter itineraries which have a higher generalized-cost than a pure walk itinerary. + * Filter itineraries which have a higher generalized-cost than the walk-only itinerary (if exist). */ -public class RemoveTransitIfWalkingIsBetterFilter implements RemoveItineraryFlagger { +public class RemoveTransitIfWalkingIsBetter implements RemoveItineraryFlagger { /** * Required for {@link org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain}, diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java similarity index 88% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java index b3e6fb1c01d..4d7ffffa13a 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import java.time.temporal.ChronoUnit; import java.util.Comparator; @@ -11,7 +11,7 @@ import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** - * This filter remove all transit results which have a generalized-cost higher than the max-limit + * This filter removes all transit results that have a generalized-cost higher than the max-limit * computed by the {@link #costLimitFunction} plus the wait cost given by * {@link TransitGeneralizedCostFilter#getWaitTimeCost}. */ @@ -41,11 +41,11 @@ public List flagForRemoval(List itineraries) { return transitItineraries .stream() - .filter(it -> transitItineraries.stream().anyMatch(t -> acceptGeneralizedCost(it, t))) + .filter(it -> transitItineraries.stream().anyMatch(t -> generalizedCostExceedsLimit(it, t))) .collect(Collectors.toList()); } - private boolean acceptGeneralizedCost(Itinerary subject, Itinerary transitItinerary) { + private boolean generalizedCostExceedsLimit(Itinerary subject, Itinerary transitItinerary) { return subject.getGeneralizedCost() > calculateLimit(subject, transitItinerary); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java similarity index 90% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java index 233edb0d11f..f076586f487 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit.group; import java.util.ArrayList; import java.util.List; @@ -7,13 +7,12 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; /** - * This filter ensures that no more than one itinerary begins or ends with same trip. + * This filter ensures that no more than one itinerary begins or ends with the same trip. * It loops through itineraries from top to bottom. If itinerary matches with any other itinerary * from above, it is removed from list. * Uses {@link GroupBySameFirstOrLastTrip}. - * for matching itineraries. */ -public class SameFirstOrLastTripFilter implements RemoveItineraryFlagger { +public class RemoveIfFirstOrLastTripIsTheSame implements RemoveItineraryFlagger { @Override public String name() { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java similarity index 85% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java index 74a395379c8..becac712445 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit.group; import java.util.List; import java.util.OptionalInt; @@ -7,24 +7,25 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.transit.model.timetable.Trip; /** - * This filter marks itineraries, which use same trips for most of their legs, but where some - * itineraries have a much higher cost for the other legs, for deletion. This is similar to {@link + * This filter remove itineraries, which use the same trips for most of their legs, but where some + * itineraries have a much higher cost for the other legs. This is similar to {@link * TransitGeneralizedCostFilter}, but is used together with {@link GroupByFilter} to filter within * the groups. */ -public class OtherThanSameLegsMaxGeneralizedCostFilter implements RemoveItineraryFlagger { +public class RemoveOtherThanSameLegsMaxGeneralizedCost implements RemoveItineraryFlagger { /** - * How much higher cost do we allow for the non-shared legs before we filter out the itinerary. + * How much higher cost do we allow for the non-shared legs before we filter out the itinerary? */ private final double maxCostOtherLegsFactor; - public OtherThanSameLegsMaxGeneralizedCostFilter(double maxCostOtherLegsFactor) { + public RemoveOtherThanSameLegsMaxGeneralizedCost(double maxCostOtherLegsFactor) { this.maxCostOtherLegsFactor = maxCostOtherLegsFactor; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java index a4bd423884c..6af4f240a10 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacher.java @@ -9,9 +9,9 @@ import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StreetLeg; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfWalkingIsBetterFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfStreetOnlyIsBetter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfWalkingIsBetter; import org.opentripplanner.routing.api.response.RoutingError; /** @@ -50,12 +50,12 @@ public static List computeErrors( it .getSystemNotices() .stream() - .anyMatch(notice -> notice.tag().equals(RemoveTransitIfStreetOnlyIsBetterFilter.TAG)); + .anyMatch(notice -> notice.tag().equals(RemoveTransitIfStreetOnlyIsBetter.TAG)); Predicate isWorseThanWalking = it -> it .getSystemNotices() .stream() - .anyMatch(notice -> notice.tag().equals(RemoveTransitIfWalkingIsBetterFilter.TAG)); + .anyMatch(notice -> notice.tag().equals(RemoveTransitIfWalkingIsBetter.TAG)); if ( filteredItineraries .stream() diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikeRentalWithMostlyWalkingTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java similarity index 93% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikeRentalWithMostlyWalkingTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java index 58cecb82810..4e47306601c 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveBikeRentalWithMostlyWalkingTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveBikeRentalWithMostlyWalkingTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import static org.opentripplanner.model.plan.TestItineraryBuilder.A; import static org.opentripplanner.model.plan.TestItineraryBuilder.B; @@ -20,7 +20,7 @@ public class RemoveBikeRentalWithMostlyWalkingTest { private static final int T10_10 = TimeUtils.hm2time(10, 10); private static final int T10_20 = TimeUtils.hm2time(10, 20); - private final RemoveBikerentalWithMostlyWalkingFilter subject = new RemoveBikerentalWithMostlyWalkingFilter( + private final RemoveBikeRentalWithMostlyWalking subject = new RemoveBikeRentalWithMostlyWalking( 0.3 ); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java index 8fdfb3c6de6..a4c90d1346f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveParkAndRideWithMostlyWalkingTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveParkAndRideWithMostlyWalkingTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import static org.opentripplanner.model.plan.TestItineraryBuilder.A; import static org.opentripplanner.model.plan.TestItineraryBuilder.B; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java index 2ede3ccac10..359423a842b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveWalkOnlyFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveWalkOnlyFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.street; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.A; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLegTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLegTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java index 72d88ec2469..7949b6ab086 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveItinerariesWithShortStreetLegTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java index 1541afc623b..df45bcf4538 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfStreetOnlyIsBetterFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; @@ -12,7 +12,7 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; -public class RemoveTransitIfStreetOnlyIsBetterFilterTest implements PlanTestConstants { +public class RemoveTransitIfStreetOnlyIsBetterTest implements PlanTestConstants { @Test public void filterAwayNothingIfNoWalking() { @@ -21,7 +21,7 @@ public void filterAwayNothingIfNoWalking() { Itinerary i2 = newItinerary(A).rail(110, 6, 9, E).build(); // When: - RemoveItineraryFlagger flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( + RemoveItineraryFlagger flagger = new RemoveTransitIfStreetOnlyIsBetter( CostLinearFunction.of(Duration.ofSeconds(200), 1.2) ); List result = flagger.removeMatchesForTest(List.of(i1, i2)); @@ -49,7 +49,7 @@ public void filterAwayLongTravelTimeWithoutWaitTime() { i2.setGeneralizedCost(360); // When: - RemoveItineraryFlagger flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( + RemoveItineraryFlagger flagger = new RemoveTransitIfStreetOnlyIsBetter( CostLinearFunction.of(Duration.ofSeconds(60), 1.2) ); List result = flagger.removeMatchesForTest(List.of(i2, bicycle, walk, i1)); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java similarity index 91% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java index af2e5a68965..55efcf68856 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/RemoveTransitIfWalkingIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; @@ -18,7 +18,7 @@ public void filterAwayNothingIfNoWalking() { Itinerary i2 = newItinerary(A).rail(110, 6, 9, E).build(); // When: - List result = new RemoveTransitIfWalkingIsBetterFilter() + List result = new RemoveTransitIfWalkingIsBetter() .removeMatchesForTest(List.of(i1, i2)); // Then: @@ -39,7 +39,7 @@ public void filterAwayTransitWithLongerWalk() { // transit which has less walking than plain walk should be kept Itinerary i2 = newItinerary(A, 6).walk(D1m, B).bus(2, 7, 10, E).build(); - List result = new RemoveTransitIfWalkingIsBetterFilter() + List result = new RemoveTransitIfWalkingIsBetter() .removeMatchesForTest(List.of(i1, i2, bicycle, walk)); assertEquals(toStr(List.of(i2, bicycle, walk)), toStr(result)); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java similarity index 94% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java index 83eb532a7eb..1ba7dde39fe 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitAlertFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.BUS_ROUTE; @@ -32,7 +32,7 @@ void testFilter() { ) ); - TransitAlertFilter filter = new TransitAlertFilter(transitAlertService, ignore -> null); + DecorateTransitAlert filter = new DecorateTransitAlert(transitAlertService, ignore -> null); // Expect filter to no fail on an empty list assertEquals(List.of(), filter.filter(List.of())); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java similarity index 99% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java index f55b0c8d0b3..6f5f01a9728 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/TransitGeneralizedCostFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilterTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.Itinerary.toStr; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java similarity index 83% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java index 88ea9b12277..0e125207935 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/SameFirstOrLastTripFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSameTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit.group; import static org.ejml.UtilEjml.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -9,10 +9,11 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -public class SameFirstOrLastTripFilterTest implements PlanTestConstants { +public class RemoveIfFirstOrLastTripIsTheSameTest implements PlanTestConstants { /** - * This test ensures that filter work as intended regarding comparison order and exclusion logic + * This test ensures that the filter works as intended regarding comparison order and exclusion + * logic. */ @Test public void testMatchOrderOnFirstStation() { @@ -34,7 +35,7 @@ public void testMatchOrderOnFirstStation() { List input = List.of(i1, i2, i3, i4, i5); - final SameFirstOrLastTripFilter filter = new SameFirstOrLastTripFilter(); + final RemoveIfFirstOrLastTripIsTheSame filter = new RemoveIfFirstOrLastTripIsTheSame(); var flagged = filter.flagForRemoval(input); // First journey should always be included diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java similarity index 83% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java index 0bb2265c8a5..c5017c55ae3 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/OtherThanSameLegsMaxGeneralizedCostFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCostTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.routing.algorithm.filterchain.filters; +package org.opentripplanner.routing.algorithm.filterchain.filters.transit.group; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; @@ -8,7 +8,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -class OtherThanSameLegsMaxGeneralizedCostFilterTest implements PlanTestConstants { +class RemoveOtherThanSameLegsMaxGeneralizedCostTest implements PlanTestConstants { @Test public void testFilter() { @@ -19,7 +19,7 @@ public void testFilter() { Itinerary second = newItinerary(A).rail(20, T11_05, T11_14, B).walk(D10m, C).build(); - var subject = new OtherThanSameLegsMaxGeneralizedCostFilter(2.0); + var subject = new RemoveOtherThanSameLegsMaxGeneralizedCost(2.0); assertEquals(List.of(second), subject.flagForRemoval(List.of(first, second))); } } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java index 0330aca3683..98ea33cea88 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filterchain/RoutingErrorsAttacherTest.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.algorithm.filterchain.filters.RemoveTransitIfStreetOnlyIsBetterFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfStreetOnlyIsBetter; import org.opentripplanner.routing.api.response.RoutingErrorCode; class RoutingErrorsAttacherTest implements PlanTestConstants { @@ -38,7 +38,7 @@ public static List flagAll(List itineraries) { itineraries.forEach(i -> i.flagForDeletion( new SystemNotice( - RemoveTransitIfStreetOnlyIsBetterFilter.TAG, + RemoveTransitIfStreetOnlyIsBetter.TAG, "This itinerary is marked as deleted." ) ) From b01c5d5ac94774e4b47a09b52b794612f662f176 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 5 Jan 2024 18:47:44 +0100 Subject: [PATCH 064/356] refactor: Rename decorators --- ...> DecorateWithAccessibilityScoreTest.java} | 4 +- .../ext/emissions/EmissionsTest.java | 19 ++-- .../ext/fares/FaresFilterTest.java | 2 +- .../flex/trip/ScheduledDeviatedTripTest.java | 4 +- ....java => DecorateWithRideHailingTest.java} | 8 +- ...=> DecorateConsolidatedStopNamesTest.java} | 4 +- ...va => DecorateWithAccessibilityScore.java} | 5 +- ...sFilter.java => DecorateWithEmission.java} | 3 +- ...FaresFilter.java => DecorateWithFare.java} | 4 +- ...lter.java => DecorateWithRideHailing.java} | 6 +- ...ava => DecorateConsolidatedStopNames.java} | 4 +- .../ItineraryListFilterChainBuilder.java | 105 +++++++++--------- .../RemoveItinerariesWithShortStreetLeg.java | 3 + .../RouteRequestToFilterChainMapper.java | 20 ++-- .../ItineraryListFilterChainTest.java | 6 +- 15 files changed, 104 insertions(+), 93 deletions(-) rename src/ext-test/java/org/opentripplanner/ext/accessibilityscore/{AccessibilityScoreFilterTest.java => DecorateWithAccessibilityScoreTest.java} (89%) rename src/ext-test/java/org/opentripplanner/ext/ridehailing/{RideHailingFilterTest.java => DecorateWithRideHailingTest.java} (87%) rename src/ext-test/java/org/opentripplanner/ext/stopconsolidation/{ConsolidatedStopNameFilterTest.java => DecorateConsolidatedStopNamesTest.java} (94%) rename src/ext/java/org/opentripplanner/ext/accessibilityscore/{AccessibilityScoreFilter.java => DecorateWithAccessibilityScore.java} (96%) rename src/ext/java/org/opentripplanner/ext/emissions/{EmissionsFilter.java => DecorateWithEmission.java} (97%) rename src/ext/java/org/opentripplanner/ext/fares/{FaresFilter.java => DecorateWithFare.java} (80%) rename src/ext/java/org/opentripplanner/ext/ridehailing/{RideHailingFilter.java => DecorateWithRideHailing.java} (93%) rename src/ext/java/org/opentripplanner/ext/stopconsolidation/{ConsolidatedStopNameFilter.java => DecorateConsolidatedStopNames.java} (92%) diff --git a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilterTest.java b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java similarity index 89% rename from src/ext-test/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilterTest.java rename to src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java index 3239a7a73df..4ffc59a1781 100644 --- a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java @@ -11,7 +11,7 @@ import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.api.request.preference.WheelchairPreferences; -public class AccessibilityScoreFilterTest implements PlanTestConstants { +public class DecorateWithAccessibilityScoreTest implements PlanTestConstants { @Test public void shouldAddAccessibilityScore() { @@ -37,7 +37,7 @@ public void shouldAddAccessibilityScore() { input.forEach(i -> assertNull(i.getAccessibilityScore())); - var filter = new AccessibilityScoreFilter(WheelchairPreferences.DEFAULT.maxSlope()); + var filter = new DecorateWithAccessibilityScore(WheelchairPreferences.DEFAULT.maxSlope()); var filtered = filter.filter(input); filtered.forEach(i -> { diff --git a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java b/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java index 82058567c38..ef33b6e3ba9 100644 --- a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java @@ -31,7 +31,7 @@ class EmissionsTest { private static DefaultEmissionsService eService; - private static EmissionsFilter emissionsFilter; + private static DecorateWithEmission decorateWithEmission; static final ZonedDateTime TIME = OffsetDateTime .parse("2023-07-20T17:49:06+03:00") @@ -58,7 +58,7 @@ static void SetUp() { emissions.put(new FeedScopedId("F", "2"), 0.0); EmissionsDataModel emissionsDataModel = new EmissionsDataModel(emissions, 0.131); eService = new DefaultEmissionsService(emissionsDataModel); - emissionsFilter = new EmissionsFilter(eService); + decorateWithEmission = new DecorateWithEmission(eService); } @Test @@ -66,7 +66,7 @@ void testGetEmissionsForItinerary() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS))); assertEquals( new Grams(2223.902), - emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() + decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() ); } @@ -75,14 +75,14 @@ void testGetEmissionsForCarRoute() { Itinerary i = new Itinerary(List.of(STREET_LEG)); assertEquals( new Grams(28.0864), - emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() + decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() ); } @Test void testNoEmissionsForFeedWithoutEmissionsConfigured() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED))); - assertNull(emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson()); + assertNull(decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson()); } @Test @@ -90,7 +90,7 @@ void testZeroEmissionsForItineraryWithZeroEmissions() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_ZERO_EMISSIONS))); assertEquals( new Grams(0.0), - emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() + decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() ); } @@ -99,7 +99,7 @@ void testGetEmissionsForCombinedRoute() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS), STREET_LEG)); assertEquals( new Grams(2251.9884), - emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() + decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() ); } @@ -108,8 +108,9 @@ void testNoEmissionsForCombinedRouteWithoutTransitEmissions() { Itinerary i = new Itinerary( List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED), STREET_LEG) ); - var emissionsResult = emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson() != null - ? emissionsFilter.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() + var emissionsResult = decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson() != + null + ? decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() : null; assertNull(emissionsResult); } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java index 7fe315cb97b..134dd942d4e 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java @@ -42,7 +42,7 @@ void shouldAddFare() { var fp = new FareProduct(id("fp"), "fare product", Money.euros(10.00f), null, null, null); fares.addFareProduct(leg, fp); - var filter = new FaresFilter((FareService) itinerary -> fares); + var filter = new DecorateWithFare((FareService) itinerary -> fares); var filtered = filter.filter(input); filtered.forEach(i -> assertEquals(fares, i.getFares())); diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index 3fb77a29adf..4150dd5b489 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -18,7 +18,7 @@ import org.opentripplanner.TestOtpModel; import org.opentripplanner.TestServerContext; import org.opentripplanner._support.time.ZoneIds; -import org.opentripplanner.ext.fares.FaresFilter; +import org.opentripplanner.ext.fares.DecorateWithFare; import org.opentripplanner.ext.flex.FlexRouter; import org.opentripplanner.ext.flex.FlexTest; import org.opentripplanner.framework.application.OTPFeature; @@ -144,7 +144,7 @@ void calculateDirectFare() { List.of(to) ); - var filter = new FaresFilter(graph.getFareService()); + var filter = new DecorateWithFare(graph.getFareService()); var itineraries = filter.filter(router.createFlexOnlyItineraries().stream().toList()); diff --git a/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingFilterTest.java b/src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java similarity index 87% rename from src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingFilterTest.java rename to src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java index ec7932b1d3d..58eb6315dd9 100644 --- a/src/ext-test/java/org/opentripplanner/ext/ridehailing/RideHailingFilterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailingTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.model.plan.TestItineraryBuilder; import org.opentripplanner.transit.model.basic.Money; -class RideHailingFilterTest implements PlanTestConstants { +class DecorateWithRideHailingTest implements PlanTestConstants { public static final RideEstimate RIDE_ESTIMATE = new RideEstimate( UBER, @@ -39,7 +39,7 @@ class RideHailingFilterTest implements PlanTestConstants { @Test void noServices() { - var filter = new RideHailingFilter(List.of(), false); + var filter = new DecorateWithRideHailing(List.of(), false); var filtered = filter.filter(List.of(i)); @@ -48,7 +48,7 @@ void noServices() { @Test void addRideHailingInformation() { - var filter = new RideHailingFilter(List.of(mockService), false); + var filter = new DecorateWithRideHailing(List.of(mockService), false); var filtered = filter.filter(List.of(i)); @@ -63,7 +63,7 @@ void addRideHailingInformation() { @Test void failingService() { - var filter = new RideHailingFilter(List.of(failingService), false); + var filter = new DecorateWithRideHailing(List.of(failingService), false); var filtered = filter.filter(List.of(i)); diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilterTest.java b/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java similarity index 94% rename from src/ext-test/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilterTest.java rename to src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java index d88e8a5879e..6f0671da04c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.model.plan.TestItineraryBuilder; -class ConsolidatedStopNameFilterTest { +class DecorateConsolidatedStopNamesTest { @Test void changeNames() { @@ -27,7 +27,7 @@ void changeNames() { repo.addGroups(groups); var service = new DefaultStopConsolidationService(repo, transitModel); - var filter = new ConsolidatedStopNameFilter(service); + var filter = new DecorateConsolidatedStopNames(service); var itinerary = TestItineraryBuilder .newItinerary(Place.forStop(STOP_C)) diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java b/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java similarity index 96% rename from src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java rename to src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java index b0ced6e00c5..4c36964af19 100644 --- a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java +++ b/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java @@ -25,7 +25,8 @@ * calculating them on the backend makes life a little easier and changes are automatically applied * to all frontends. */ -public record AccessibilityScoreFilter(double wheelchairMaxSlope) implements ItineraryListFilter { +public record DecorateWithAccessibilityScore(double wheelchairMaxSlope) + implements ItineraryListFilter { public static Float compute(List legs) { return legs .stream() @@ -43,7 +44,7 @@ public static float compute(ScheduledTransitLeg leg) { var values = List.of(trip, fromStop, toStop); var sum = (float) values .stream() - .mapToDouble(AccessibilityScoreFilter::accessibilityScore) + .mapToDouble(DecorateWithAccessibilityScore::accessibilityScore) .sum(); return sum / values.size(); } diff --git a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java b/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java rename to src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java index 2186339a4e6..50a5dd2c3ee 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/EmissionsFilter.java +++ b/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java @@ -19,7 +19,8 @@ * @param emissionsService */ @Sandbox -public record EmissionsFilter(EmissionsService emissionsService) implements ItineraryListFilter { +public record DecorateWithEmission(EmissionsService emissionsService) + implements ItineraryListFilter { @Override public List filter(List itineraries) { for (Itinerary itinerary : itineraries) { diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java b/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java similarity index 80% rename from src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java rename to src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java index cc3a956ef16..786885452e7 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/FaresFilter.java +++ b/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java @@ -8,8 +8,10 @@ /** * Computes the fares of an itinerary and adds them. + *

    + * TODO: Convert to a class - exposing a service in a DTO is a risk. */ -public record FaresFilter(FareService fareService) implements ItineraryListFilter { +public record DecorateWithFare(FareService fareService) implements ItineraryListFilter { @Override public List filter(List itineraries) { return itineraries diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java b/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java similarity index 93% rename from src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java rename to src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java index bbaa707a00b..cbe4e174334 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/RideHailingFilter.java +++ b/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java @@ -15,15 +15,15 @@ * This filter decorates car dropoff/pickup legs with information from ride hailing services and * adds information about price and arrival time of the vehicle. */ -public class RideHailingFilter implements ItineraryListFilter { +public class DecorateWithRideHailing implements ItineraryListFilter { - private static final Logger LOG = LoggerFactory.getLogger(RideHailingFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(DecorateWithRideHailing.class); public static final String NO_RIDE_HAILING_AVAILABLE = "no-ride-hailing-available"; private final List rideHailingServices; private final boolean wheelchairAccessible; - public RideHailingFilter( + public DecorateWithRideHailing( List rideHailingServices, boolean wheelchairAccessible ) { diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java similarity index 92% rename from src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java rename to src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 6165732e122..b9f3012b425 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/ConsolidatedStopNameFilter.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -12,11 +12,11 @@ * then replaces it with the secondary, agency-specific stop name. This is so that the in-vehicle * display matches what OTP returns as a board/alight stop name. */ -public class ConsolidatedStopNameFilter implements ItineraryListFilter { +public class DecorateConsolidatedStopNames implements ItineraryListFilter { private final StopConsolidationService service; - public ConsolidatedStopNameFilter(StopConsolidationService service) { + public DecorateConsolidatedStopNames(StopConsolidationService service) { this.service = Objects.requireNonNull(service); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 03065cc9f22..bcce86d7185 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -11,7 +11,7 @@ import java.util.function.Consumer; import java.util.function.Function; import javax.annotation.Nullable; -import org.opentripplanner.ext.accessibilityscore.AccessibilityScoreFilter; +import org.opentripplanner.ext.accessibilityscore.DecorateWithAccessibilityScore; import org.opentripplanner.framework.collection.ListSection; import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.model.plan.Itinerary; @@ -89,16 +89,16 @@ public class ItineraryListFilterChainBuilder { */ @Sandbox - private ItineraryListFilter emissionsFilter; + private ItineraryListFilter emissionDecorator; @Sandbox - private ItineraryListFilter faresFilter; + private ItineraryListFilter fareDecorator; @Sandbox - private ItineraryListFilter rideHailingFilter; + private ItineraryListFilter rideHailingDecorator; @Sandbox - private ItineraryListFilter stopConsolidationFilter; + private ItineraryListFilter stopConsolidationDecorator; public ItineraryListFilterChainBuilder(SortOrder sortOrder) { this.sortOrder = sortOrder; @@ -317,13 +317,13 @@ public ItineraryListFilterChainBuilder withAccessibilityScore( return this; } - public ItineraryListFilterChainBuilder withFaresFilter(ItineraryListFilter filter) { - this.faresFilter = filter; + public ItineraryListFilterChainBuilder withFareDecorator(ItineraryListFilter decorator) { + this.fareDecorator = decorator; return this; } - public ItineraryListFilterChainBuilder withEmissions(ItineraryListFilter emissionsFilter) { - this.emissionsFilter = emissionsFilter; + public ItineraryListFilterChainBuilder withEmissions(ItineraryListFilter emissionDecorator) { + this.emissionDecorator = emissionDecorator; return this; } @@ -339,15 +339,25 @@ public ItineraryListFilterChainBuilder withRemoveTimeshiftedItinerariesWithSameR return this; } - public ItineraryListFilterChainBuilder withRideHailingFilter(ItineraryListFilter filter) { - this.rideHailingFilter = filter; + public ItineraryListFilterChainBuilder withRideHailingDecorator(ItineraryListFilter decorator) { + this.rideHailingDecorator = decorator; return this; } - public ItineraryListFilterChainBuilder withStopConsolidationFilter( - @Nullable ItineraryListFilter filter + public ItineraryListFilterChainBuilder withConsolidatedStopNamesDecorator( + @Nullable ItineraryListFilter decorator ) { - this.stopConsolidationFilter = filter; + this.stopConsolidationDecorator = decorator; + return this; + } + + public ItineraryListFilterChainBuilder withTransitAlerts( + TransitAlertService transitAlertService, + Function getMultiModalStation + ) { + this.transitAlertService = transitAlertService; + this.getMultiModalStation = getMultiModalStation; + return this; } @@ -366,27 +376,12 @@ public ItineraryListFilterChain build() { } if (minBikeParkingDistance > 0) { + // TODO: use addRmFilter() here filters.add( new RemoveItinerariesWithShortStreetLeg(minBikeParkingDistance, TraverseMode.BICYCLE) ); } - if (accessibilityScore) { - filters.add(new AccessibilityScoreFilter(wheelchairMaxSlope)); - } - - if (faresFilter != null) { - filters.add(faresFilter); - } - - if (emissionsFilter != null) { - filters.add(emissionsFilter); - } - - if (transitAlertService != null) { - filters.add(new DecorateTransitAlert(transitAlertService, getMultiModalStation)); - } - // Filter transit itineraries on generalized-cost if (transitGeneralizedCostFilterParams != null) { addRmFilter( @@ -445,9 +440,9 @@ public ItineraryListFilterChain build() { } // Paging related filters - these filters are run after group-by filters to allow a result - // outside the page to also take effect inside the window. This is debatable but lead to less - // noise, however it is not deterministic because the result depends on the size of the search-window and - // where the "cut" between each page is located. + // outside the page to also take effect inside the window. This is debatable, but leads to less + // noise; However, it is not deterministic because the result depends on the size of the + // search-window and where the "cut" between each page is located. { // Limit to search-window if (earliestDepartureTime != null) { @@ -476,18 +471,34 @@ public ItineraryListFilterChain build() { // Do the final itineraries sort filters.add(new SortingFilter(SortOrderComparator.comparator(sortOrder))); - // Sandbox filters to decorate itineraries + // Decorate itineraries + { + if (transitAlertService != null) { + filters.add(new DecorateTransitAlert(transitAlertService, getMultiModalStation)); + } + + // Sandbox filters to decorate itineraries - if (faresFilter != null) { - filters.add(faresFilter); - } + if (accessibilityScore) { + // TODO: This should be injected to avoid circular dependencies (dep. on sandbox here) + filters.add(new DecorateWithAccessibilityScore(wheelchairMaxSlope)); + } - if (rideHailingFilter != null) { - filters.add(rideHailingFilter); - } + if (emissionDecorator != null) { + filters.add(emissionDecorator); + } - if (stopConsolidationFilter != null) { - filters.add(stopConsolidationFilter); + if (fareDecorator != null) { + filters.add(fareDecorator); + } + + if (rideHailingDecorator != null) { + filters.add(rideHailingDecorator); + } + + if (stopConsolidationDecorator != null) { + filters.add(stopConsolidationDecorator); + } } var debugHandler = new DeleteResultHandler(debug, maxNumberOfItineraries); @@ -495,16 +506,6 @@ public ItineraryListFilterChain build() { return new ItineraryListFilterChain(filters, debugHandler); } - public ItineraryListFilterChainBuilder withTransitAlerts( - TransitAlertService transitAlertService, - Function getMultiModalStation - ) { - this.transitAlertService = transitAlertService; - this.getMultiModalStation = getMultiModalStation; - - return this; - } - /** * If enabled, this adds the filter to remove itineraries which have the same stops and routes. * These are sometimes called "time-shifted duplicates" but since those terms have so many diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java index c9254b246e7..010828c4cff 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java @@ -11,6 +11,9 @@ * leg followed by parking the bike and taking transit. In such a case you would not need a bike * could just walk to the stop instead. *

    + * TODO: THIS FILTER DOES NOT FOLLOW THE ITINERARY FILTER FRAMEWORK. This filter should implement the + * {@link org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger}. + * * TODO: This filter build on assumptions that is more or less an implementation detail. The * filter should compare itineraries and remove them if a condition is meet, not just * assume that a better option exist. Perhaps the access and egress should be filtered diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java index 2f1c531e102..ab839f14798 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java @@ -4,10 +4,10 @@ import java.time.Instant; import java.util.List; import java.util.function.Consumer; -import org.opentripplanner.ext.emissions.EmissionsFilter; -import org.opentripplanner.ext.fares.FaresFilter; -import org.opentripplanner.ext.ridehailing.RideHailingFilter; -import org.opentripplanner.ext.stopconsolidation.ConsolidatedStopNameFilter; +import org.opentripplanner.ext.emissions.DecorateWithEmission; +import org.opentripplanner.ext.fares.DecorateWithFare; +import org.opentripplanner.ext.ridehailing.DecorateWithRideHailing; +import org.opentripplanner.ext.stopconsolidation.DecorateConsolidatedStopNames; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.model.plan.paging.cursor.PageCursorInput; import org.opentripplanner.routing.algorithm.filterchain.ItineraryListFilterChain; @@ -96,22 +96,22 @@ public static ItineraryListFilterChain createFilterChain( var fareService = context.graph().getFareService(); if (fareService != null) { - builder.withFaresFilter(new FaresFilter(fareService)); + builder.withFareDecorator(new DecorateWithFare(fareService)); } if (!context.rideHailingServices().isEmpty()) { - builder.withRideHailingFilter( - new RideHailingFilter(context.rideHailingServices(), request.wheelchair()) + builder.withRideHailingDecorator( + new DecorateWithRideHailing(context.rideHailingServices(), request.wheelchair()) ); } if (OTPFeature.Co2Emissions.isOn() && context.emissionsService() != null) { - builder.withEmissions(new EmissionsFilter(context.emissionsService())); + builder.withEmissions(new DecorateWithEmission(context.emissionsService())); } if (context.stopConsolidationService() != null) { - builder.withStopConsolidationFilter( - new ConsolidatedStopNameFilter(context.stopConsolidationService()) + builder.withConsolidatedStopNamesDecorator( + new DecorateConsolidatedStopNames(context.stopConsolidationService()) ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java index 0591ae7ce4e..d897c948e6d 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java @@ -20,9 +20,9 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.opentripplanner.ext.emissions.DecorateWithEmission; import org.opentripplanner.ext.emissions.DefaultEmissionsService; import org.opentripplanner.ext.emissions.EmissionsDataModel; -import org.opentripplanner.ext.emissions.EmissionsFilter; import org.opentripplanner.ext.emissions.EmissionsService; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.model.plan.Itinerary; @@ -365,7 +365,9 @@ public void setUpItineraries() { @Test public void emissionsTest() { - ItineraryListFilterChain chain = builder.withEmissions(new EmissionsFilter(eService)).build(); + ItineraryListFilterChain chain = builder + .withEmissions(new DecorateWithEmission(eService)) + .build(); List itineraries = chain.filter(List.of(bus, car)); assertFalse(itineraries.stream().anyMatch(i -> i.getEmissionsPerPerson().getCo2() == null)); } From d4e28f746ae7f9f93e24554a4fe2326cccfb8500 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 20:46:19 +0100 Subject: [PATCH 065/356] Add tests --- pom.xml | 1 - .../opentripplanner/astar/model/BinHeap.java | 14 --------- .../strategy/MaxCountSkipEdgeStrategy.java | 2 +- .../module/NearbyStopFinder.java | 16 ++++------ .../MaxCountSkipEdgeStrategyTest.java | 12 ++++++-- .../model/_data/StreetModelForTest.java | 1 + .../street/search/state/TestStateBuilder.java | 29 +++++++++++++++++-- 7 files changed, 44 insertions(+), 31 deletions(-) diff --git a/pom.xml b/pom.xml index de8baecefd9..29b1f14dc09 100644 --- a/pom.xml +++ b/pom.xml @@ -282,7 +282,6 @@ --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/jdk.internal.util=ALL-UNNAMED - --add-opens java.base/jdk.internal.util.jar=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.http=ALL-UNNAMED --add-opens java.base/sun.net.www.protocol.jar=ALL-UNNAMED diff --git a/src/main/java/org/opentripplanner/astar/model/BinHeap.java b/src/main/java/org/opentripplanner/astar/model/BinHeap.java index f1c39f12b61..1e9b540a77a 100644 --- a/src/main/java/org/opentripplanner/astar/model/BinHeap.java +++ b/src/main/java/org/opentripplanner/astar/model/BinHeap.java @@ -1,7 +1,6 @@ package org.opentripplanner.astar.model; import java.util.Arrays; -import org.opentripplanner.framework.tostring.ToStringBuilder; public class BinHeap { @@ -80,14 +79,6 @@ public void rekey(T e, double p) { prio[i] = p; } - public void dump() { - for (int i = 0; i <= capacity; i++) { - String topMarker = (i > size) ? "(UNUSED)" : ""; - System.out.printf("%d\t%f\t%s\t%s\n", i, prio[i], elem[i], topMarker); - } - System.out.printf("-----------------------\n"); - } - public void reset() { // empties the queue in one operation size = 0; @@ -136,9 +127,4 @@ public void resize(int capacity) { prio = Arrays.copyOf(prio, capacity + 1); elem = Arrays.copyOf(elem, capacity + 1); } - - @Override - public String toString() { - return ToStringBuilder.of().addNum("size", size).toString(); - } } diff --git a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java index f719ed371ac..0369e3e29db 100644 --- a/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java +++ b/src/main/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategy.java @@ -26,7 +26,7 @@ public MaxCountSkipEdgeStrategy(int count, Predicate shouldIncreaseCount) @Override public boolean shouldSkipEdge(State current, Edge edge) { - if (current.isFinal() && shouldIncreaseCount.test(current)) { + if (shouldIncreaseCount.test(current)) { visited++; } return visited > maxCount; diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index 4caa04d7892..13fbfec2b17 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -228,14 +228,11 @@ public List findNearbyStopsViaStreets( Vertex targetVertex = state.getVertex(); if (originVertices.contains(targetVertex)) continue; if (targetVertex instanceof TransitStopVertex tsv && state.isFinal()) { - stopsFound.add( - NearbyStop.nearbyStopForState(state, tsv.getStop()) - ); + stopsFound.add(NearbyStop.nearbyStopForState(state, tsv.getStop())); } if ( OTPFeature.FlexRouting.isOn() && - targetVertex instanceof StreetVertex streetVertex && - !streetVertex.areaStops().isEmpty() + targetVertex instanceof StreetVertex streetVertex && !streetVertex.areaStops().isEmpty() ) { for (AreaStop areaStop : ((StreetVertex) targetVertex).areaStops()) { // This is for a simplification, so that we only return one vertex from each @@ -312,10 +309,7 @@ private SkipEdgeStrategy getSkipEdgeStrategy( return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } else { if (maxStopCount > 0) { - var strategy = new MaxCountSkipEdgeStrategy<>( - maxStopCount, - NearbyStopFinder::isTransitVertex - ); + var strategy = new MaxCountSkipEdgeStrategy<>(maxStopCount, NearbyStopFinder::hasFoundStop); return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } return durationSkipEdgeStrategy; @@ -368,7 +362,7 @@ private boolean canBoardFlex(State state, boolean reverse) { /** * Checks if the {@code state} as at a transit vertex. */ - public static boolean isTransitVertex(State state) { - return state.getVertex() instanceof TransitStopVertex; + public static boolean hasFoundStop(State state) { + return state.getVertex() instanceof TransitStopVertex && state.isFinal(); } } diff --git a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java index 04844d65da2..85d9fe72ec3 100644 --- a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java +++ b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java @@ -12,7 +12,7 @@ class MaxCountSkipEdgeStrategyTest { @Test void countStops() { var state = TestStateBuilder.ofWalking().stop().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::isTransitVertex); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasFoundStop); assertFalse(strategy.shouldSkipEdge(state, null)); assertTrue(strategy.shouldSkipEdge(state, null)); } @@ -20,9 +20,17 @@ void countStops() { @Test void doNotCountStop() { var state = TestStateBuilder.ofWalking().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::isTransitVertex); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasFoundStop); assertFalse(strategy.shouldSkipEdge(state, null)); assertFalse(strategy.shouldSkipEdge(state, null)); assertFalse(strategy.shouldSkipEdge(state, null)); } + + @Test + void nonFinalState() { + var state = TestStateBuilder.ofScooterRentalArriveBy().stop().build(); + assertFalse(state.isFinal()); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasFoundStop); + assertFalse(strategy.shouldSkipEdge(state, null)); + } } diff --git a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java index 1f3dbf8c4c9..0ac1762ae6f 100644 --- a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java +++ b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java @@ -93,4 +93,5 @@ public static StreetEdge streetEdge( ) { return streetEdge(from, to, 1, permissions); } + } diff --git a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java b/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java index 042ff5ba553..752985de51e 100644 --- a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java +++ b/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java @@ -1,6 +1,7 @@ package org.opentripplanner.street.search.state; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType.EGRESS; import static org.opentripplanner.transit.model.site.PathwayMode.WALKWAY; import java.time.Instant; @@ -10,6 +11,7 @@ import javax.annotation.Nonnull; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; +import org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressType; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.service.vehiclerental.model.TestFreeFloatingRentalVehicleBuilder; import org.opentripplanner.service.vehiclerental.model.TestVehicleRentalStationBuilder; @@ -20,6 +22,7 @@ import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model._data.StreetModelForTest; +import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.ElevatorAlightEdge; import org.opentripplanner.street.model.edge.ElevatorBoardEdge; import org.opentripplanner.street.model.edge.ElevatorHopEdge; @@ -51,10 +54,19 @@ public class TestStateBuilder { private State currentState; private TestStateBuilder(StreetMode mode) { + this(mode, AccessEgressType.ACCESS); + } + + private TestStateBuilder(StreetMode mode, AccessEgressType type) { currentState = new State( StreetModelForTest.intersectionVertex(count, count), - StreetSearchRequest.of().withMode(mode).withStartTime(DEFAULT_START_TIME).build() + StreetSearchRequest + .of() + .withArriveBy(type.isEgress()) + .withMode(mode) + .withStartTime(DEFAULT_START_TIME) + .build() ); } @@ -80,6 +92,14 @@ public static TestStateBuilder ofScooterRental() { return new TestStateBuilder(StreetMode.SCOOTER_RENTAL); } + /** + * Creates a state starts the scooter rental but in arriveBy mode, so therefore starting with + * a rental scooter and going backwards until it finds a rental vertex where to drop it. + */ + public static TestStateBuilder ofScooterRentalArriveBy() { + return new TestStateBuilder(StreetMode.SCOOTER_RENTAL, EGRESS); + } + public static TestStateBuilder ofBikeRental() { return new TestStateBuilder(StreetMode.BIKE_RENTAL); } @@ -248,7 +268,12 @@ private TestStateBuilder arriveAtStop(RegularStop stop) { var from = (StreetVertex) currentState.vertex; var to = new TransitStopVertexBuilder().withStop(stop).build(); - var edge = StreetTransitStopLink.createStreetTransitStopLink(from, to); + Edge edge; + if (currentState.getRequest().arriveBy()) { + edge = StreetTransitStopLink.createStreetTransitStopLink(to, from); + } else { + edge = StreetTransitStopLink.createStreetTransitStopLink(from, to); + } var states = edge.traverse(currentState); if (states.length != 1) { throw new IllegalStateException("Only single state transitions are supported."); From 67d6443655c449dcbd99f973f1dfda2f12a6d3bf Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 22:32:28 +0100 Subject: [PATCH 066/356] Improve documentation --- .../module/NearbyStopFinder.java | 30 +++++++++++-------- .../MaxCountSkipEdgeStrategyTest.java | 6 ++-- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index 13fbfec2b17..09d8024eca0 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -47,14 +47,8 @@ import org.opentripplanner.transit.service.TransitService; /** - * These library functions are used by the streetless and streetful stop linkers, and in profile - * transfer generation. - * TODO OTP2 Fold these into org.opentripplanner.routing.graphfinder.StreetGraphFinder - * These are not library functions, this is instantiated as an object. Define lifecycle of the object (reuse?). - * Because AStar instances should only be used once, NearbyStopFinder should only be used once. - * Ideally they could also be used in long distance mode and profile routing for the street segments. - * For each stop, it finds the closest stops on all other patterns. This reduces the number of transfer edges - * significantly compared to simple radius-constrained all-to-all stop linkage. + * This class contains code for finding nearby stops from a given vertex. It is being used by access + * and egress searches as well as transfer generation. */ public class NearbyStopFinder { @@ -100,6 +94,8 @@ public NearbyStopFinder( * that the result will include the origin vertex if it is an instance of StopVertex. This is * intentional: we don't want to return the next stop down the line for trip patterns that pass * through the origin vertex. + * Taking the patterns into account reduces the number of transfers significantly compared to + * simple traverse-duration-constrained all-to-all stop linkage. */ public Set findNearbyStopsConsideringPatterns( Vertex vertex, @@ -309,7 +305,7 @@ private SkipEdgeStrategy getSkipEdgeStrategy( return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } else { if (maxStopCount > 0) { - var strategy = new MaxCountSkipEdgeStrategy<>(maxStopCount, NearbyStopFinder::hasFoundStop); + var strategy = new MaxCountSkipEdgeStrategy<>(maxStopCount, NearbyStopFinder::hasReachedStop); return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } return durationSkipEdgeStrategy; @@ -355,14 +351,24 @@ private boolean canBoardFlex(State state, boolean reverse) { return edges .stream() .anyMatch(e -> - e instanceof StreetEdge && ((StreetEdge) e).getPermission().allows(TraverseMode.CAR) + e instanceof StreetEdge se && se.getPermission().allows(TraverseMode.CAR) ); } /** - * Checks if the {@code state} as at a transit vertex. + * Checks if the {@code state} is at a transit vertex and if it's final, which means that the state + * can actually board a vehicle. + *

    + * This is important because there can be cases where states that cannot actually board the vehicle + * can dominate those that can thereby leading to zero found stops when this predicate is used with + * the {@link MaxCountSkipEdgeStrategy}. + *

    + * An example of this would be an egress/reverse search with a very high walk reluctance where + * the states that speculatively rent a vehicle move the walk states down the A* priority queue + * until the required number of stops are reached to abort the search, leading to zero egress + * results. */ - public static boolean hasFoundStop(State state) { + public static boolean hasReachedStop(State state) { return state.getVertex() instanceof TransitStopVertex && state.isFinal(); } } diff --git a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java index 85d9fe72ec3..17dc26a4c5e 100644 --- a/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java +++ b/src/test/java/org/opentripplanner/astar/strategy/MaxCountSkipEdgeStrategyTest.java @@ -12,7 +12,7 @@ class MaxCountSkipEdgeStrategyTest { @Test void countStops() { var state = TestStateBuilder.ofWalking().stop().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasFoundStop); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasReachedStop); assertFalse(strategy.shouldSkipEdge(state, null)); assertTrue(strategy.shouldSkipEdge(state, null)); } @@ -20,7 +20,7 @@ void countStops() { @Test void doNotCountStop() { var state = TestStateBuilder.ofWalking().build(); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasFoundStop); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasReachedStop); assertFalse(strategy.shouldSkipEdge(state, null)); assertFalse(strategy.shouldSkipEdge(state, null)); assertFalse(strategy.shouldSkipEdge(state, null)); @@ -30,7 +30,7 @@ void doNotCountStop() { void nonFinalState() { var state = TestStateBuilder.ofScooterRentalArriveBy().stop().build(); assertFalse(state.isFinal()); - var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasFoundStop); + var strategy = new MaxCountSkipEdgeStrategy<>(1, NearbyStopFinder::hasReachedStop); assertFalse(strategy.shouldSkipEdge(state, null)); } } From 623b626a5b22d75f7bf8079ae2eee369b75ce52a Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 22:51:16 +0100 Subject: [PATCH 067/356] Run speed test on branch --- .github/workflows/performance-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/performance-test.yml b/.github/workflows/performance-test.yml index c2168a79a06..d764fdbeff0 100644 --- a/.github/workflows/performance-test.yml +++ b/.github/workflows/performance-test.yml @@ -4,6 +4,7 @@ on: push: branches: - dev-2.x + - max-count-rental jobs: perf-test: From f2bc21fcf5b8d5d6b69370c239def28adee8f0bb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 22:53:25 +0100 Subject: [PATCH 068/356] Fix formatting --- .../graph_builder/module/NearbyStopFinder.java | 9 +++++---- .../street/model/_data/StreetModelForTest.java | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index 09d8024eca0..360cdaee363 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -305,7 +305,10 @@ private SkipEdgeStrategy getSkipEdgeStrategy( return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } else { if (maxStopCount > 0) { - var strategy = new MaxCountSkipEdgeStrategy<>(maxStopCount, NearbyStopFinder::hasReachedStop); + var strategy = new MaxCountSkipEdgeStrategy<>( + maxStopCount, + NearbyStopFinder::hasReachedStop + ); return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } return durationSkipEdgeStrategy; @@ -350,9 +353,7 @@ private boolean canBoardFlex(State state, boolean reverse) { return edges .stream() - .anyMatch(e -> - e instanceof StreetEdge se && se.getPermission().allows(TraverseMode.CAR) - ); + .anyMatch(e -> e instanceof StreetEdge se && se.getPermission().allows(TraverseMode.CAR)); } /** diff --git a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java index 0ac1762ae6f..1f3dbf8c4c9 100644 --- a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java +++ b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java @@ -93,5 +93,4 @@ public static StreetEdge streetEdge( ) { return streetEdge(from, to, 1, permissions); } - } From 63327b72b243052806602a5fbd8d3b7c9ec4b70e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 23:04:43 +0100 Subject: [PATCH 069/356] Move classes according to review feedback --- .../ext/restapi}/mapping/EnumMapperTest.java | 5 +---- .../ext/restapi}/mapping/FareMapperTest.java | 3 +-- .../ext/restapi/model/ApiTravelOptionsMakerTest.java} | 6 ++---- .../opentripplanner/ext/restapi}/model/ApiWalkStepTest.java | 3 +-- .../ext/restapi}/parameter/ApiRequestModeTest.java | 4 +++- .../ext/restapi}/parameter/QualifiedModeSetTest.java | 4 +++- .../ext/restapi}/parameter/QualifiedModeTest.java | 5 ++++- .../org/opentripplanner/ext/restapi/resources/IndexAPI.java | 2 +- .../ext/restapi/resources/PlannerResource.java | 2 +- .../ext/vectortiles/VectorTilesResource.java | 2 +- .../layers/stations/DigitransitStationPropertyMapper.java | 2 +- .../vectortiles/layers/stations/StationsLayerBuilder.java | 2 +- .../layers/stops/DigitransitStopPropertyMapper.java | 2 +- .../ext/vectortiles/layers/stops/StopsLayerBuilder.java | 2 +- .../DigitransitVehicleParkingGroupPropertyMapper.java | 2 +- .../DigitransitVehicleParkingPropertyMapper.java | 2 +- .../StadtnaviVehicleParkingPropertyMapper.java | 2 +- .../vehicleparkings/VehicleParkingGroupsLayerBuilder.java | 2 +- .../layers/vehicleparkings/VehicleParkingsLayerBuilder.java | 2 +- .../layers/vehiclerental/VehicleRentalLayerBuilder.java | 2 +- ...gitransitRealtimeVehicleRentalStationPropertyMapper.java | 2 +- .../mapper/DigitransitRentalVehiclePropertyMapper.java | 2 +- .../mapper/DigitransitVehicleRentalPropertyMapper.java | 2 +- .../DigitransitVehicleRentalStationPropertyMapper.java | 2 +- .../api/resource/GraphInspectorVectorTileResource.java | 2 +- .../opentripplanner/apis/gtfs/datafetchers/PatternImpl.java | 2 +- .../opentripplanner/apis/gtfs/datafetchers/PlanImpl.java | 2 +- .../apis/gtfs/datafetchers/RoutingErrorImpl.java | 2 +- .../opentripplanner/apis/gtfs/datafetchers/TripImpl.java | 2 +- .../apis/{common => support}/SemanticHash.java | 2 +- .../opentripplanner/apis/{common => support}/TileJson.java | 2 +- .../{common => support}/mapping/PlannerErrorMapper.java | 2 +- .../apis/{common => support}/mapping/PropertyMapper.java | 2 +- .../apis/transmodel/model/plan/RoutingErrorType.java | 2 +- .../apis/transmodel/model/plan/TripType.java | 2 +- .../opentripplanner/framework/i18n/I18NStringMapper.java | 0 .../inspector/vector/AreaStopsLayerBuilder.java | 2 +- .../inspector/vector/DebugClientAreaStopPropertyMapper.java | 2 +- .../org/opentripplanner/inspector/vector/LayerBuilder.java | 2 +- .../opentripplanner/inspector/vector/LayerParameters.java | 2 +- .../vector/geofencing/GeofencingZonesLayerBuilder.java | 2 +- .../vector/geofencing/GeofencingZonesPropertyMapper.java | 2 +- 42 files changed, 49 insertions(+), 49 deletions(-) rename src/{test/java/org/opentripplanner/api => ext-test/java/org/opentripplanner/ext/restapi}/mapping/EnumMapperTest.java (91%) rename src/{test/java/org/opentripplanner/api => ext-test/java/org/opentripplanner/ext/restapi}/mapping/FareMapperTest.java (91%) rename src/{test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java => ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java} (96%) rename src/{test/java/org/opentripplanner/api => ext-test/java/org/opentripplanner/ext/restapi}/model/ApiWalkStepTest.java (91%) rename src/{test/java/org/opentripplanner/api => ext-test/java/org/opentripplanner/ext/restapi}/parameter/ApiRequestModeTest.java (69%) rename src/{test/java/org/opentripplanner/api => ext-test/java/org/opentripplanner/ext/restapi}/parameter/QualifiedModeSetTest.java (97%) rename src/{test/java/org/opentripplanner/api => ext-test/java/org/opentripplanner/ext/restapi}/parameter/QualifiedModeTest.java (82%) rename src/main/java/org/opentripplanner/apis/{common => support}/SemanticHash.java (99%) rename src/main/java/org/opentripplanner/apis/{common => support}/TileJson.java (97%) rename src/main/java/org/opentripplanner/apis/{common => support}/mapping/PlannerErrorMapper.java (97%) rename src/main/java/org/opentripplanner/apis/{common => support}/mapping/PropertyMapper.java (96%) rename src/{ext => main}/java/org/opentripplanner/framework/i18n/I18NStringMapper.java (100%) diff --git a/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java similarity index 91% rename from src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java index 956b2aa065e..35cc368fec4 100644 --- a/src/test/java/org/opentripplanner/api/mapping/EnumMapperTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -8,9 +8,6 @@ import java.util.Map; import java.util.function.Function; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.restapi.mapping.AbsoluteDirectionMapper; -import org.opentripplanner.ext.restapi.mapping.RelativeDirectionMapper; -import org.opentripplanner.ext.restapi.mapping.VertexTypeMapper; import org.opentripplanner.ext.restapi.model.ApiAbsoluteDirection; import org.opentripplanner.ext.restapi.model.ApiRelativeDirection; import org.opentripplanner.ext.restapi.model.ApiVertexType; diff --git a/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java similarity index 91% rename from src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java index 0d13a77e7c9..bd1bd07aa43 100644 --- a/src/test/java/org/opentripplanner/api/mapping/FareMapperTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; @@ -6,7 +6,6 @@ import java.util.List; import java.util.Locale; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.restapi.mapping.FareMapper; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; diff --git a/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java similarity index 96% rename from src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java index 16e0ae1547e..fdcd0a7fe20 100644 --- a/src/test/java/org/opentripplanner/api/model/ApiApiTravelOptionsMakerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiTravelOptionsMakerTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -6,14 +6,12 @@ import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.restapi.model.ApiTravelOption; -import org.opentripplanner.ext.restapi.model.ApiTravelOptionsMaker; import org.opentripplanner.transit.model.basic.TransitMode; /** * Created by mabu on 28.7.2015. */ -public class ApiApiTravelOptionsMakerTest { +public class ApiTravelOptionsMakerTest { @Test public void testMakeOptions() throws Exception { diff --git a/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java similarity index 91% rename from src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java index fe265b05081..7f6909bfc2c 100644 --- a/src/test/java/org/opentripplanner/api/model/ApiWalkStepTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/model/ApiWalkStepTest.java @@ -1,10 +1,9 @@ -package org.opentripplanner.api.model; +package org.opentripplanner.ext.restapi.model; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.restapi.model.ApiWalkStep; public class ApiWalkStepTest { diff --git a/src/test/java/org/opentripplanner/api/parameter/ApiRequestModeTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java similarity index 69% rename from src/test/java/org/opentripplanner/api/parameter/ApiRequestModeTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java index caf26510b2a..13cfc43c59c 100644 --- a/src/test/java/org/opentripplanner/api/parameter/ApiRequestModeTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/ApiRequestModeTest.java @@ -1,10 +1,12 @@ -package org.opentripplanner.api.parameter; +package org.opentripplanner.ext.restapi.parameter; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.transit.model.basic.TransitMode.CARPOOL; import java.util.List; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.opentripplanner.api.parameter.ApiRequestMode; class ApiRequestModeTest { diff --git a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java similarity index 97% rename from src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java index ba5a39abe89..ad344713a74 100644 --- a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeSetTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeSetTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.parameter; +package org.opentripplanner.ext.restapi.parameter; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -26,6 +26,8 @@ import jakarta.ws.rs.BadRequestException; import java.util.Set; import org.junit.jupiter.api.Test; +import org.opentripplanner.api.parameter.QualifiedMode; +import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.transit.model.basic.TransitMode; diff --git a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java similarity index 82% rename from src/test/java/org/opentripplanner/api/parameter/QualifiedModeTest.java rename to src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java index e4c4c9448fc..3a682ba40c9 100644 --- a/src/test/java/org/opentripplanner/api/parameter/QualifiedModeTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/parameter/QualifiedModeTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.parameter; +package org.opentripplanner.ext.restapi.parameter; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -6,6 +6,9 @@ import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; +import org.opentripplanner.api.parameter.ApiRequestMode; +import org.opentripplanner.api.parameter.QualifiedMode; +import org.opentripplanner.api.parameter.Qualifier; public class QualifiedModeTest { diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java index 90fd12a1c7c..5bdda8a57a2 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java @@ -25,7 +25,7 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; -import org.opentripplanner.apis.common.SemanticHash; +import org.opentripplanner.apis.support.SemanticHash; import org.opentripplanner.ext.restapi.mapping.AgencyMapper; import org.opentripplanner.ext.restapi.mapping.AlertMapper; import org.opentripplanner.ext.restapi.mapping.FeedInfoMapper; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java index ac1ee80df95..0b6a06f0b5d 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java @@ -11,7 +11,7 @@ import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.common.Message; import org.opentripplanner.api.model.error.PlannerError; -import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.ext.restapi.mapping.TripPlanMapper; import org.opentripplanner.ext.restapi.mapping.TripSearchMetadataMapper; import org.opentripplanner.ext.restapi.model.ElevationMetadata; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index 96093884a25..af2715d6928 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -17,7 +17,7 @@ import java.util.Objects; import java.util.function.Predicate; import org.glassfish.grizzly.http.server.Request; -import org.opentripplanner.apis.common.TileJson; +import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.ext.vectortiles.layers.stations.StationsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.stops.StopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingGroupsLayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java index b7b21e01c38..a828cd37a7c 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/DigitransitStationPropertyMapper.java @@ -6,7 +6,7 @@ import java.util.Map; import java.util.stream.Collectors; import org.json.simple.JSONArray; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.framework.FeedScopedId; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java index 1b09d2e8c5d..449a1489d89 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stations/StationsLayerBuilder.java @@ -9,7 +9,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java index d2b72e36cd3..2c5a4519e96 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/DigitransitStopPropertyMapper.java @@ -8,7 +8,7 @@ import java.util.stream.Collectors; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.network.TripPattern; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index e57e3e48cb0..6d15816669e 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java index 66cb6060ca9..33f415c157a 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingGroupPropertyMapper.java @@ -5,7 +5,7 @@ import java.util.Locale; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java index 27d2b78776b..892d4907395 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/DigitransitVehicleParkingPropertyMapper.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.routing.vehicle_parking.VehicleParking; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java index 7ff573864a2..c938f9736fd 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/StadtnaviVehicleParkingPropertyMapper.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Locale; import org.json.simple.JSONObject; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.model.calendar.openinghours.OsmOpeningHoursSupport; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java index 59440b78ab7..0cd1d84868b 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerBuilder.java @@ -8,7 +8,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java index 7a43044d40c..95326172415 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerBuilder.java @@ -11,7 +11,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java index 06fecf26e57..0869aeb2ba8 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/VehicleRentalLayerBuilder.java @@ -7,7 +7,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java index 87b5cf9e126..4ceb7124d52 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRealtimeVehicleRentalStationPropertyMapper.java @@ -7,7 +7,7 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java index 1450b7855bd..33e661866bc 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitRentalVehiclePropertyMapper.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collection; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java index 90e553e6320..3114b072934 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalPropertyMapper.java @@ -3,7 +3,7 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java index 6d82f592b38..67fb00efa85 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/vehiclerental/mapper/DigitransitVehicleRentalStationPropertyMapper.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; diff --git a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java index 89905298e66..8c50b2e3bdc 100644 --- a/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/api/resource/GraphInspectorVectorTileResource.java @@ -17,7 +17,7 @@ import java.util.Objects; import java.util.function.Predicate; import org.glassfish.grizzly.http.server.Request; -import org.opentripplanner.apis.common.TileJson; +import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.inspector.vector.AreaStopsLayerBuilder; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java index 5c121a6dd07..88db00c3c4e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PatternImpl.java @@ -13,10 +13,10 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.apis.common.SemanticHash; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.SemanticHash; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.routing.alertpatch.EntitySelector; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java index 36dc4a987d8..b9bdfde9cbc 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/PlanImpl.java @@ -4,8 +4,8 @@ import graphql.schema.DataFetchingEnvironment; import java.util.stream.Collectors; import org.opentripplanner.api.resource.DebugOutput; -import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.StopArrival; import org.opentripplanner.model.plan.paging.cursor.PageCursor; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java index d80db923df6..5c4bd7099c6 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RoutingErrorImpl.java @@ -4,9 +4,9 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.routing.api.response.RoutingError; public class RoutingErrorImpl implements GraphQLDataFetchers.GraphQLRoutingError { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java index c9b1abdaa64..21bff637976 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/TripImpl.java @@ -15,7 +15,6 @@ import java.util.stream.Collectors; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; -import org.opentripplanner.apis.common.SemanticHash; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; @@ -23,6 +22,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; import org.opentripplanner.apis.gtfs.mapping.BikesAllowedMapper; import org.opentripplanner.apis.gtfs.model.TripOccupancy; +import org.opentripplanner.apis.support.SemanticHash; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.Timetable; import org.opentripplanner.model.TripTimeOnDate; diff --git a/src/main/java/org/opentripplanner/apis/common/SemanticHash.java b/src/main/java/org/opentripplanner/apis/support/SemanticHash.java similarity index 99% rename from src/main/java/org/opentripplanner/apis/common/SemanticHash.java rename to src/main/java/org/opentripplanner/apis/support/SemanticHash.java index 73ef2da906c..2d1f35977fa 100644 --- a/src/main/java/org/opentripplanner/apis/common/SemanticHash.java +++ b/src/main/java/org/opentripplanner/apis/support/SemanticHash.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common; +package org.opentripplanner.apis.support; import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; diff --git a/src/main/java/org/opentripplanner/apis/common/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/common/TileJson.java rename to src/main/java/org/opentripplanner/apis/support/TileJson.java index c9b3856e932..2259d72d828 100644 --- a/src/main/java/org/opentripplanner/apis/common/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common; +package org.opentripplanner.apis.support; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.UriInfo; diff --git a/src/main/java/org/opentripplanner/apis/common/mapping/PlannerErrorMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java similarity index 97% rename from src/main/java/org/opentripplanner/apis/common/mapping/PlannerErrorMapper.java rename to src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java index b85986c930b..a606cb75a52 100644 --- a/src/main/java/org/opentripplanner/apis/common/mapping/PlannerErrorMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.mapping; +package org.opentripplanner.apis.support.mapping; import java.util.List; import org.opentripplanner.api.common.Message; diff --git a/src/main/java/org/opentripplanner/apis/common/mapping/PropertyMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java similarity index 96% rename from src/main/java/org/opentripplanner/apis/common/mapping/PropertyMapper.java rename to src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java index ad2868239a8..dfb7def85c7 100644 --- a/src/main/java/org/opentripplanner/apis/common/mapping/PropertyMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/PropertyMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.apis.common.mapping; +package org.opentripplanner.apis.support.mapping; import edu.colorado.cires.cmg.mvt.VectorTile; import edu.colorado.cires.cmg.mvt.adapt.jts.IUserDataConverter; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java index a8ae74dede2..215e1983ca0 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/RoutingErrorType.java @@ -7,7 +7,7 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; -import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; public class RoutingErrorType { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java index fcf794a7ca8..053b261c08e 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripType.java @@ -8,7 +8,7 @@ import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import java.util.stream.Collectors; -import org.opentripplanner.apis.common.mapping.PlannerErrorMapper; +import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.apis.transmodel.model.PlanResponse; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.framework.graphql.GraphQLUtils; diff --git a/src/ext/java/org/opentripplanner/framework/i18n/I18NStringMapper.java b/src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java similarity index 100% rename from src/ext/java/org/opentripplanner/framework/i18n/I18NStringMapper.java rename to src/main/java/org/opentripplanner/framework/i18n/I18NStringMapper.java diff --git a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java index 5f268d9f9bf..5e4539e1f5c 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/AreaStopsLayerBuilder.java @@ -7,7 +7,7 @@ import java.util.function.Function; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; diff --git a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java index fb50a25fd33..63c58dd9b05 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/DebugClientAreaStopPropertyMapper.java @@ -3,7 +3,7 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.TransitService; diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java index cec59ef136f..949bbef0a94 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerBuilder.java @@ -10,7 +10,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; /** diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index a36fdfad840..ca4a6a64c76 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,6 +1,6 @@ package org.opentripplanner.inspector.vector; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; /** * Configuration options for a single vector tile layer. diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java index 3948f95e8ee..1764451cc89 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesLayerBuilder.java @@ -4,7 +4,7 @@ import java.util.Map; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java index 7321727076c..98c9cf23eca 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/geofencing/GeofencingZonesPropertyMapper.java @@ -6,7 +6,7 @@ import java.util.Collection; import java.util.List; -import org.opentripplanner.apis.common.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.street.model.vertex.Vertex; From 154cfe970b17c5b3bcb08bf47335e4592aec7819 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 23:06:15 +0100 Subject: [PATCH 070/356] Move PlannerError back --- .../opentripplanner/ext/restapi/model/TripPlannerResponse.java | 2 +- .../opentripplanner/ext/restapi/resources/PlannerResource.java | 2 +- .../java/org/opentripplanner/api}/error/PlannerError.java | 2 +- .../apis/support/mapping/PlannerErrorMapper.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/{ext/java/org/opentripplanner/ext/restapi/model => main/java/org/opentripplanner/api}/error/PlannerError.java (94%) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java b/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java index 337301cddfd..28cce2dd669 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/TripPlannerResponse.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map.Entry; -import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.error.PlannerError; import org.opentripplanner.api.resource.DebugOutput; /** Represents a trip planner response, will be serialized into XML or JSON by Jersey */ diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java index 0b6a06f0b5d..38c70851b76 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/PlannerResource.java @@ -10,7 +10,7 @@ import jakarta.ws.rs.core.UriInfo; import org.glassfish.grizzly.http.server.Request; import org.opentripplanner.api.common.Message; -import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.error.PlannerError; import org.opentripplanner.apis.support.mapping.PlannerErrorMapper; import org.opentripplanner.ext.restapi.mapping.TripPlanMapper; import org.opentripplanner.ext.restapi.mapping.TripSearchMetadataMapper; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/error/PlannerError.java b/src/main/java/org/opentripplanner/api/error/PlannerError.java similarity index 94% rename from src/ext/java/org/opentripplanner/ext/restapi/model/error/PlannerError.java rename to src/main/java/org/opentripplanner/api/error/PlannerError.java index a41a3f6148a..1a35275a7cd 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/error/PlannerError.java +++ b/src/main/java/org/opentripplanner/api/error/PlannerError.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.model.error; +package org.opentripplanner.api.error; import java.util.List; import org.opentripplanner.api.common.Message; diff --git a/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java index a606cb75a52..9ec662f51e0 100644 --- a/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/PlannerErrorMapper.java @@ -2,7 +2,7 @@ import java.util.List; import org.opentripplanner.api.common.Message; -import org.opentripplanner.api.model.error.PlannerError; +import org.opentripplanner.api.error.PlannerError; import org.opentripplanner.routing.api.response.InputField; import org.opentripplanner.routing.api.response.RoutingError; From 8a8856b5b130e478b8d1ad89daa9ed24ed24c44c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 23:09:02 +0100 Subject: [PATCH 071/356] Update src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java Co-authored-by: Thomas Gran --- .../org/opentripplanner/routing/error/PathNotFoundException.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java index f0a2c854015..8776cb81c00 100644 --- a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java +++ b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java @@ -6,6 +6,5 @@ * Indicates that the call to org.opentripplanner.routing.services.PathService returned either null * or ZERO paths. * - * @see PlannerResource for where this is (locally) thrown. */ public class PathNotFoundException extends RuntimeException {} From 360b16594bc06ffce12adc7e61179a8a659a4bf5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 23:09:12 +0100 Subject: [PATCH 072/356] Update src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java Co-authored-by: Thomas Gran --- .../opentripplanner/routing/error/PathNotFoundException.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java index 8776cb81c00..a4071f9911e 100644 --- a/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java +++ b/src/main/java/org/opentripplanner/routing/error/PathNotFoundException.java @@ -1,7 +1,5 @@ package org.opentripplanner.routing.error; -import org.opentripplanner.ext.restapi.resources.PlannerResource; - /** * Indicates that the call to org.opentripplanner.routing.services.PathService returned either null * or ZERO paths. From 7fdb6958bc8acdd95a91b59ea5bf6f9517d2ccdb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 23:12:21 +0100 Subject: [PATCH 073/356] Move StreetNoteMapper into apis.support --- .../org/opentripplanner/ext/restapi/mapping/LegMapper.java | 5 +++-- .../opentripplanner/ext/restapi/mapping/WalkStepMapper.java | 5 +++-- .../opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java | 3 +-- .../apis/support/mapping/StreetNoteMapper.java} | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) rename src/{ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java => main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java} (89%) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java index f16a9e8fbf5..766262bca89 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegMapper.java @@ -7,6 +7,7 @@ import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; +import org.opentripplanner.apis.support.mapping.StreetNoteMapper; import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.ext.restapi.model.ApiLeg; import org.opentripplanner.framework.geometry.EncodedPolyline; @@ -19,7 +20,7 @@ public class LegMapper { private final WalkStepMapper walkStepMapper; - private final StreetNoteMaperMapper streetNoteMaperMapper; + private final StreetNoteMapper streetNoteMaperMapper; private final AlertMapper alertMapper; private final PlaceMapper placeMapper; private final boolean addIntermediateStops; @@ -28,7 +29,7 @@ public class LegMapper { public LegMapper(Locale locale, boolean addIntermediateStops) { this.walkStepMapper = new WalkStepMapper(locale); - this.streetNoteMaperMapper = new StreetNoteMaperMapper(locale); + this.streetNoteMaperMapper = new StreetNoteMapper(locale); this.alertMapper = new AlertMapper(locale); this.placeMapper = new PlaceMapper(locale); this.addIntermediateStops = addIntermediateStops; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java index fba316d32ba..c5c59e4dc37 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java @@ -7,17 +7,18 @@ import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import org.opentripplanner.apis.support.mapping.StreetNoteMapper; import org.opentripplanner.ext.restapi.model.ApiWalkStep; import org.opentripplanner.model.plan.WalkStep; public class WalkStepMapper { - private final StreetNoteMaperMapper alertsMapper; + private final StreetNoteMapper alertsMapper; private final Locale locale; public WalkStepMapper(Locale locale) { this.locale = locale; - this.alertsMapper = new StreetNoteMaperMapper(locale); + this.alertsMapper = new StreetNoteMapper(locale); } public List mapWalkSteps(Collection domain) { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java index 572535a540d..563200dbba0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/StreetNoteMapper.java @@ -1,6 +1,5 @@ package org.opentripplanner.apis.gtfs.mapping; -import org.opentripplanner.ext.restapi.mapping.StreetNoteMaperMapper; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.routing.alertpatch.TimePeriod; import org.opentripplanner.routing.alertpatch.TransitAlert; @@ -11,7 +10,7 @@ public class StreetNoteMapper { /** - * Similar to {@link StreetNoteMaperMapper ::mapToApi}. + * Similar to {@link org.opentripplanner.apis.support.mapping.StreetNoteMapper ::mapToApi}. */ public static TransitAlert mapStreetNoteToAlert(StreetNote note) { // TODO: The ID is used only in the mapping, we should instead have two mappers for the fields diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java b/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java similarity index 89% rename from src/ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java rename to src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java index 62926eb6e18..9cde403c2ed 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/StreetNoteMaperMapper.java +++ b/src/main/java/org/opentripplanner/apis/support/mapping/StreetNoteMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.restapi.mapping; +package org.opentripplanner.apis.support.mapping; import java.util.List; import java.util.Locale; @@ -7,11 +7,11 @@ import org.opentripplanner.ext.restapi.model.ApiAlert; import org.opentripplanner.street.model.note.StreetNote; -public class StreetNoteMaperMapper { +public class StreetNoteMapper { private final Locale locale; - public StreetNoteMaperMapper(Locale locale) { + public StreetNoteMapper(Locale locale) { this.locale = locale; } From 57fc58844a49a252ca85d10b0e662a014d0a5cd3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 5 Jan 2024 23:14:25 +0100 Subject: [PATCH 074/356] Move resources into sandbox section --- .../java/org/opentripplanner/apis/APIEndpoints.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java index 04a0e3a145a..fc49c02431f 100644 --- a/src/main/java/org/opentripplanner/apis/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -46,11 +46,6 @@ public class APIEndpoints { private APIEndpoints() { // Add feature enabled APIs, these can be enabled by default, some is not. // See the OTPFeature enum for details. - addIfEnabled(LegacyRestApi, Routers.class); - addIfEnabled(LegacyRestApi, PlannerResource.class); - addIfEnabled(LegacyRestApi, IndexAPI.class); - - addIfEnabled(APIBikeRental, BikeRental.class); addIfEnabled(APIGraphInspectorTile, GraphInspectorTileResource.class); addIfEnabled(APIGraphInspectorTile, GraphInspectorVectorTileResource.class); addIfEnabled(APIServerInfo, ServerInfo.class); @@ -65,6 +60,12 @@ private APIEndpoints() { addIfEnabled(SandboxAPIParkAndRideApi, ParkAndRideResource.class); addIfEnabled(SandboxAPIGeocoder, GeocoderResource.class); addIfEnabled(SandboxAPITravelTime, TravelTimeResource.class); + + // scheduled to be removed + addIfEnabled(APIBikeRental, BikeRental.class); + addIfEnabled(LegacyRestApi, Routers.class); + addIfEnabled(LegacyRestApi, PlannerResource.class); + addIfEnabled(LegacyRestApi, IndexAPI.class); } /** From 3e71e1cf9e13ecf66a229de91105c9c9d55867f5 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Sat, 6 Jan 2024 01:32:34 +0100 Subject: [PATCH 075/356] refactor: Introduce a ItineraryDecorator interface --- .../DecorateWithAccessibilityScoreTest.java | 82 +++++++++++-------- .../ext/emissions/EmissionsTest.java | 33 +++----- .../ext/fares/FaresFilterTest.java | 11 ++- .../flex/trip/ScheduledDeviatedTripTest.java | 2 +- .../DecorateConsolidatedStopNamesTest.java | 6 +- .../DecorateWithAccessibilityScore.java | 8 +- .../ext/emissions/DecorateWithEmission.java | 57 ++++++------- .../ext/fares/DecorateWithFare.java | 23 ++---- .../ridehailing/DecorateWithRideHailing.java | 2 +- .../DecorateConsolidatedStopNames.java | 13 ++- .../opentripplanner/model/plan/Itinerary.java | 3 +- .../ItineraryListFilterChainBuilder.java | 39 ++++++--- .../filters/transit/DecorateTransitAlert.java | 21 ++--- .../framework/filter/DecorateFilter.java | 23 ++++++ .../framework/spi/ItineraryDecorator.java | 13 +++ .../RouteRequestToFilterChainMapper.java | 2 +- .../transit/TransitAlertFilterTest.java | 25 +++--- 17 files changed, 196 insertions(+), 167 deletions(-) create mode 100644 src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java create mode 100644 src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java diff --git a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java index 4ffc59a1781..d70b9f32f62 100644 --- a/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScoreTest.java @@ -1,11 +1,13 @@ package org.opentripplanner.ext.accessibilityscore; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import java.util.List; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; @@ -13,40 +15,50 @@ public class DecorateWithAccessibilityScoreTest implements PlanTestConstants { - @Test - public void shouldAddAccessibilityScore() { - final int ID = 1; - - Itinerary i1 = newItinerary(A, 0) - .walk(20, Place.forStop(TEST_MODEL.stop("1:stop", 1d, 1d).build())) - .bus(ID, 0, 50, B) - .bus(ID, 52, 100, C) - .build(); - Itinerary i2 = newItinerary(A, 0) - .walk(20, Place.forStop(TEST_MODEL.stop("1:stop", 1d, 1d).build())) - .bus(ID, 0, 50, B) - .bus(ID, 52, 100, C) - .build(); - Itinerary i3 = newItinerary(A, 0) - .walk(20, Place.forStop(TEST_MODEL.stop("1:stop", 1d, 1d).build())) - .bus(ID, 0, 50, B) - .bus(ID, 52, 100, C) - .build(); - - List input = List.of(i1, i2, i3); - - input.forEach(i -> assertNull(i.getAccessibilityScore())); + private static final int ID = 1; + static List accessibilityScoreTestCase() { + return List.of( + Arguments.of( + newItinerary(A, 0) + .walk(20, Place.forStop(TEST_MODEL.stop("1:stop", 1d, 1d).build())) + .bus(ID, 0, 50, B) + .bus(ID, 52, 100, C) + .build(), + 0.5f + ), + Arguments.of( + newItinerary(A, 0) + .walk(20, Place.forStop(TEST_MODEL.stop("1:stop", 1d, 1d).build())) + .bus(ID, 0, 50, B) + .bus(ID, 52, 100, C) + .build(), + 0.5f + ), + Arguments.of( + newItinerary(A, 0) + .walk(20, Place.forStop(TEST_MODEL.stop("1:stop", 1d, 1d).build())) + .bus(ID, 0, 50, B) + .bus(ID, 52, 100, C) + .build(), + 0.5f + ) + ); + } + + @ParameterizedTest + @MethodSource("accessibilityScoreTestCase") + public void accessibilityScoreTest(Itinerary itinerary, float expectedAccessibilityScore) { var filter = new DecorateWithAccessibilityScore(WheelchairPreferences.DEFAULT.maxSlope()); - var filtered = filter.filter(input); - - filtered.forEach(i -> { - assertNotNull(i.getAccessibilityScore()); - i - .getLegs() - .forEach(l -> { - assertNotNull(l.accessibilityScore()); - }); - }); + + filter.decorate(itinerary); + + assertEquals(expectedAccessibilityScore, itinerary.getAccessibilityScore()); + + itinerary + .getLegs() + .forEach(l -> { + assertNotNull(l.accessibilityScore()); + }); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java b/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java index ef33b6e3ba9..ff8a65ab494 100644 --- a/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/emissions/EmissionsTest.java @@ -64,43 +64,36 @@ static void SetUp() { @Test void testGetEmissionsForItinerary() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS))); - assertEquals( - new Grams(2223.902), - decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() - ); + decorateWithEmission.decorate(i); + assertEquals(new Grams(2223.902), i.getEmissionsPerPerson().getCo2()); } @Test void testGetEmissionsForCarRoute() { Itinerary i = new Itinerary(List.of(STREET_LEG)); - assertEquals( - new Grams(28.0864), - decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() - ); + decorateWithEmission.decorate(i); + assertEquals(new Grams(28.0864), i.getEmissionsPerPerson().getCo2()); } @Test void testNoEmissionsForFeedWithoutEmissionsConfigured() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED))); - assertNull(decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson()); + decorateWithEmission.decorate(i); + assertNull(i.getEmissionsPerPerson()); } @Test void testZeroEmissionsForItineraryWithZeroEmissions() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_ZERO_EMISSIONS))); - assertEquals( - new Grams(0.0), - decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() - ); + decorateWithEmission.decorate(i); + assertEquals(new Grams(0.0), i.getEmissionsPerPerson().getCo2()); } @Test void testGetEmissionsForCombinedRoute() { Itinerary i = new Itinerary(List.of(createTransitLeg(ROUTE_WITH_EMISSIONS), STREET_LEG)); - assertEquals( - new Grams(2251.9884), - decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() - ); + decorateWithEmission.decorate(i); + assertEquals(new Grams(2251.9884), i.getEmissionsPerPerson().getCo2()); } @Test @@ -108,9 +101,9 @@ void testNoEmissionsForCombinedRouteWithoutTransitEmissions() { Itinerary i = new Itinerary( List.of(createTransitLeg(ROUTE_WITHOUT_EMISSIONS_CONFIGURED), STREET_LEG) ); - var emissionsResult = decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson() != - null - ? decorateWithEmission.filter(List.of(i)).get(0).getEmissionsPerPerson().getCo2() + decorateWithEmission.decorate(i); + var emissionsResult = i.getEmissionsPerPerson() != null + ? i.getEmissionsPerPerson().getCo2() : null; assertNull(emissionsResult); } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java index 134dd942d4e..90468b091f9 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java @@ -31,9 +31,7 @@ void shouldAddFare() { .bus(ID, 52, 100, C) .build(); - List input = List.of(i1, i1, i1); - - input.forEach(i -> assertEquals(ItineraryFares.empty(), i.getFares())); + assertEquals(ItineraryFares.empty(), i1.getFares()); var fares = new ItineraryFares(); fares.addFare(FareType.regular, Money.euros(2.80f)); @@ -43,11 +41,12 @@ void shouldAddFare() { fares.addFareProduct(leg, fp); var filter = new DecorateWithFare((FareService) itinerary -> fares); - var filtered = filter.filter(input); - filtered.forEach(i -> assertEquals(fares, i.getFares())); + filter.decorate(i1); + + assertEquals(fares, i1.getFares()); - var busLeg = filtered.get(0).getTransitLeg(1); + var busLeg = i1.getTransitLeg(1); assertEquals( List.of(new FareProductUse("c1a04702-1fb6-32d4-ba02-483bf68111ed", fp)), diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index 4150dd5b489..3523a6e5c5e 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -146,7 +146,7 @@ void calculateDirectFare() { var filter = new DecorateWithFare(graph.getFareService()); - var itineraries = filter.filter(router.createFlexOnlyItineraries().stream().toList()); + var itineraries = router.createFlexOnlyItineraries().stream().peek(filter::decorate).toList(); var itinerary = itineraries.iterator().next(); assertFalse(itinerary.getFares().getFareTypes().isEmpty()); diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java b/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java index 6f0671da04c..38af8ea7187 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.ext.stopconsolidation; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.opentripplanner.ext.stopconsolidation.TestStopConsolidationModel.STOP_C; import static org.opentripplanner.ext.stopconsolidation.TestStopConsolidationModel.STOP_D; import static org.opentripplanner.model.plan.PlanTestConstants.T11_05; @@ -36,10 +35,9 @@ void changeNames() { .bus(1, T11_05, T11_12, PlanTestConstants.F) .build(); - var filtered = filter.filter(List.of(itinerary)); - assertFalse(filtered.isEmpty()); + filter.decorate(itinerary); - var updatedLeg = filtered.get(0).getLegs().get(0); + var updatedLeg = itinerary.getLegs().get(0); assertEquals(STOP_D.getName(), updatedLeg.getFrom().name); assertEquals(STOP_D.getName(), updatedLeg.getTo().name); } diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java b/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java index 4c36964af19..a0430719382 100644 --- a/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java +++ b/src/ext/java/org/opentripplanner/ext/accessibilityscore/DecorateWithAccessibilityScore.java @@ -8,7 +8,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.WalkStep; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.WheelchairTraversalInformation; import org.opentripplanner.transit.model.basic.Accessibility; @@ -26,7 +26,7 @@ * to all frontends. */ public record DecorateWithAccessibilityScore(double wheelchairMaxSlope) - implements ItineraryListFilter { + implements ItineraryDecorator { public static Float compute(List legs) { return legs .stream() @@ -50,8 +50,8 @@ public static float compute(ScheduledTransitLeg leg) { } @Override - public List filter(List itineraries) { - return itineraries.stream().map(this::addAccessibilityScore).toList(); + public void decorate(Itinerary itinerary) { + addAccessibilityScore(itinerary); } private static double accessibilityScore(Accessibility wheelchair) { diff --git a/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java b/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java index 50a5dd2c3ee..1f6e79fc4df 100644 --- a/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java +++ b/src/ext/java/org/opentripplanner/ext/emissions/DecorateWithEmission.java @@ -10,7 +10,7 @@ import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.TransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -20,42 +20,39 @@ */ @Sandbox public record DecorateWithEmission(EmissionsService emissionsService) - implements ItineraryListFilter { + implements ItineraryDecorator { @Override - public List filter(List itineraries) { - for (Itinerary itinerary : itineraries) { - List transitLegs = itinerary - .getLegs() - .stream() - .filter(l -> l instanceof ScheduledTransitLeg || l instanceof FlexibleTransitLeg) - .map(TransitLeg.class::cast) - .toList(); + public void decorate(Itinerary itinerary) { + List transitLegs = itinerary + .getLegs() + .stream() + .filter(l -> l instanceof ScheduledTransitLeg || l instanceof FlexibleTransitLeg) + .map(TransitLeg.class::cast) + .toList(); - Optional co2ForTransit = calculateCo2EmissionsForTransit(transitLegs); + Optional co2ForTransit = calculateCo2EmissionsForTransit(transitLegs); - if (!transitLegs.isEmpty() && co2ForTransit.isEmpty()) { - continue; - } + if (!transitLegs.isEmpty() && co2ForTransit.isEmpty()) { + return; + } - List carLegs = itinerary - .getLegs() - .stream() - .filter(l -> l instanceof StreetLeg) - .map(StreetLeg.class::cast) - .filter(leg -> leg.getMode() == TraverseMode.CAR) - .toList(); + List carLegs = itinerary + .getLegs() + .stream() + .filter(l -> l instanceof StreetLeg) + .map(StreetLeg.class::cast) + .filter(leg -> leg.getMode() == TraverseMode.CAR) + .toList(); - Optional co2ForCar = calculateCo2EmissionsForCar(carLegs); + Optional co2ForCar = calculateCo2EmissionsForCar(carLegs); - if (co2ForTransit.isPresent() && co2ForCar.isPresent()) { - itinerary.setEmissionsPerPerson(new Emissions(co2ForTransit.get().plus(co2ForCar.get()))); - } else if (co2ForTransit.isPresent()) { - itinerary.setEmissionsPerPerson(new Emissions(co2ForTransit.get())); - } else if (co2ForCar.isPresent()) { - itinerary.setEmissionsPerPerson(new Emissions(co2ForCar.get())); - } + if (co2ForTransit.isPresent() && co2ForCar.isPresent()) { + itinerary.setEmissionsPerPerson(new Emissions(co2ForTransit.get().plus(co2ForCar.get()))); + } else if (co2ForTransit.isPresent()) { + itinerary.setEmissionsPerPerson(new Emissions(co2ForTransit.get())); + } else if (co2ForCar.isPresent()) { + itinerary.setEmissionsPerPerson(new Emissions(co2ForCar.get())); } - return itineraries; } private Optional calculateCo2EmissionsForTransit(List transitLegs) { diff --git a/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java b/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java index 786885452e7..a47392a3fbf 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java +++ b/src/ext/java/org/opentripplanner/ext/fares/DecorateWithFare.java @@ -1,9 +1,7 @@ package org.opentripplanner.ext.fares; -import java.util.List; -import java.util.Objects; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.routing.fares.FareService; /** @@ -11,18 +9,13 @@ *

    * TODO: Convert to a class - exposing a service in a DTO is a risk. */ -public record DecorateWithFare(FareService fareService) implements ItineraryListFilter { +public record DecorateWithFare(FareService fareService) implements ItineraryDecorator { @Override - public List filter(List itineraries) { - return itineraries - .stream() - .peek(i -> { - var fare = fareService.calculateFares(i); - if (Objects.nonNull(fare)) { - i.setFare(fare); - FaresToItineraryMapper.addFaresToLegs(fare, i); - } - }) - .toList(); + public void decorate(Itinerary itinerary) { + var fare = fareService.calculateFares(itinerary); + if (fare != null) { + itinerary.setFare(fare); + FaresToItineraryMapper.addFaresToLegs(fare, itinerary); + } } } diff --git a/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java b/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java index cbe4e174334..cd076b7e2a5 100644 --- a/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java +++ b/src/ext/java/org/opentripplanner/ext/ridehailing/DecorateWithRideHailing.java @@ -13,7 +13,7 @@ /** * This filter decorates car dropoff/pickup legs with information from ride hailing services and - * adds information about price and arrival time of the vehicle. + * adds information about the price and arrival time of the vehicle. */ public class DecorateWithRideHailing implements ItineraryListFilter { diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index b9f3012b425..8fcba82a357 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -1,18 +1,17 @@ package org.opentripplanner.ext.stopconsolidation; -import java.util.List; import java.util.Objects; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopLeg; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ScheduledTransitLeg; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; /** * A decorating filter that checks if a transit leg contains any primary stops and if it does, * then replaces it with the secondary, agency-specific stop name. This is so that the in-vehicle * display matches what OTP returns as a board/alight stop name. */ -public class DecorateConsolidatedStopNames implements ItineraryListFilter { +public class DecorateConsolidatedStopNames implements ItineraryDecorator { private final StopConsolidationService service; @@ -21,8 +20,8 @@ public DecorateConsolidatedStopNames(StopConsolidationService service) { } @Override - public List filter(List itineraries) { - return itineraries.stream().map(this::replacePrimaryNamesWithSecondary).toList(); + public void decorate(Itinerary itinerary) { + replacePrimaryNamesWithSecondary(itinerary); } /** @@ -31,8 +30,8 @@ public List filter(List itineraries) { * operating the route, so that the name in the result matches the name in the in-vehicle * display. */ - private Itinerary replacePrimaryNamesWithSecondary(Itinerary i) { - return i.transformTransitLegs(leg -> { + private void replacePrimaryNamesWithSecondary(Itinerary i) { + i.transformTransitLegs(leg -> { if (leg instanceof ScheduledTransitLeg stl && needsToRenameStops(stl)) { var agency = leg.getAgency(); return new ConsolidatedStopLeg( diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index d1252c45f2d..903e04c8b0c 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -388,7 +388,7 @@ public List getLegs() { *

    * NOTE: The itinerary is mutable so the transformation is done in-place! */ - public Itinerary transformTransitLegs(Function mapper) { + public void transformTransitLegs(Function mapper) { legs = legs .stream() @@ -400,7 +400,6 @@ public Itinerary transformTransitLegs(Function mapper) { } }) .toList(); - return this; } public Stream getStreetLegs() { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index bcce86d7185..c95005acd32 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -35,6 +35,7 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.transit.group.RemoveIfFirstOrLastTripIsTheSame; import org.opentripplanner.routing.algorithm.filterchain.filters.transit.group.RemoveOtherThanSameLegsMaxGeneralizedCost; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DecorateFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; @@ -44,6 +45,7 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupByDistance; import org.opentripplanner.routing.algorithm.filterchain.framework.groupids.GroupBySameRoutesAndStops; import org.opentripplanner.routing.algorithm.filterchain.framework.sort.SortOrderComparator; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; @@ -56,6 +58,7 @@ /** * Create a filter chain based on the given config. */ +@SuppressWarnings("UnusedReturnValue") public class ItineraryListFilterChainBuilder { private static final int NOT_SET = -1; @@ -89,16 +92,16 @@ public class ItineraryListFilterChainBuilder { */ @Sandbox - private ItineraryListFilter emissionDecorator; + private ItineraryDecorator emissionDecorator; @Sandbox - private ItineraryListFilter fareDecorator; + private ItineraryDecorator fareDecorator; @Sandbox private ItineraryListFilter rideHailingDecorator; @Sandbox - private ItineraryListFilter stopConsolidationDecorator; + private ItineraryDecorator stopConsolidationDecorator; public ItineraryListFilterChainBuilder(SortOrder sortOrder) { this.sortOrder = sortOrder; @@ -317,12 +320,12 @@ public ItineraryListFilterChainBuilder withAccessibilityScore( return this; } - public ItineraryListFilterChainBuilder withFareDecorator(ItineraryListFilter decorator) { + public ItineraryListFilterChainBuilder withFareDecorator(ItineraryDecorator decorator) { this.fareDecorator = decorator; return this; } - public ItineraryListFilterChainBuilder withEmissions(ItineraryListFilter emissionDecorator) { + public ItineraryListFilterChainBuilder withEmissions(ItineraryDecorator emissionDecorator) { this.emissionDecorator = emissionDecorator; return this; } @@ -339,13 +342,15 @@ public ItineraryListFilterChainBuilder withRemoveTimeshiftedItinerariesWithSameR return this; } - public ItineraryListFilterChainBuilder withRideHailingDecorator(ItineraryListFilter decorator) { - this.rideHailingDecorator = decorator; + public ItineraryListFilterChainBuilder withRideHailingDecoratingFilter( + ItineraryListFilter decoratorFilter + ) { + this.rideHailingDecorator = decoratorFilter; return this; } public ItineraryListFilterChainBuilder withConsolidatedStopNamesDecorator( - @Nullable ItineraryListFilter decorator + @Nullable ItineraryDecorator decorator ) { this.stopConsolidationDecorator = decorator; return this; @@ -361,6 +366,7 @@ public ItineraryListFilterChainBuilder withTransitAlerts( return this; } + @SuppressWarnings("CollectionAddAllCanBeReplacedWithConstructor") public ItineraryListFilterChain build() { List filters = new ArrayList<>(); @@ -474,22 +480,22 @@ public ItineraryListFilterChain build() { // Decorate itineraries { if (transitAlertService != null) { - filters.add(new DecorateTransitAlert(transitAlertService, getMultiModalStation)); + addDecorator(filters, new DecorateTransitAlert(transitAlertService, getMultiModalStation)); } // Sandbox filters to decorate itineraries if (accessibilityScore) { // TODO: This should be injected to avoid circular dependencies (dep. on sandbox here) - filters.add(new DecorateWithAccessibilityScore(wheelchairMaxSlope)); + addDecorator(filters, new DecorateWithAccessibilityScore(wheelchairMaxSlope)); } if (emissionDecorator != null) { - filters.add(emissionDecorator); + addDecorator(filters, emissionDecorator); } if (fareDecorator != null) { - filters.add(fareDecorator); + addDecorator(filters, fareDecorator); } if (rideHailingDecorator != null) { @@ -497,7 +503,7 @@ public ItineraryListFilterChain build() { } if (stopConsolidationDecorator != null) { - filters.add(stopConsolidationDecorator); + addDecorator(filters, stopConsolidationDecorator); } } @@ -597,4 +603,11 @@ private static void addRmFilter( ) { filters.add(new RemoveFilter(removeFilter)); } + + private static void addDecorator( + List filters, + ItineraryDecorator decorator + ) { + filters.add(new DecorateFilter(decorator)); + } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java index f70c68587ec..ccc2c9b26f0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/DecorateTransitAlert.java @@ -1,16 +1,15 @@ package org.opentripplanner.routing.algorithm.filterchain.filters.transit; -import java.util.List; import java.util.function.Function; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.routing.algorithm.mapping.AlertToLegMapper; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.site.MultiModalStation; import org.opentripplanner.transit.model.site.Station; -public class DecorateTransitAlert implements ItineraryListFilter { +public class DecorateTransitAlert implements ItineraryDecorator { private final AlertToLegMapper alertToLegMapper; @@ -22,17 +21,13 @@ public DecorateTransitAlert( } @Override - public List filter(List itineraries) { - for (Itinerary itinerary : itineraries) { - boolean firstLeg = true; - for (Leg leg : itinerary.getLegs()) { - if (leg.isTransitLeg()) { - alertToLegMapper.addTransitAlertsToLeg(leg, firstLeg); - firstLeg = false; - } + public void decorate(Itinerary itinerary) { + boolean firstLeg = true; + for (Leg leg : itinerary.getLegs()) { + if (leg.isTransitLeg()) { + alertToLegMapper.addTransitAlertsToLeg(leg, firstLeg); + firstLeg = false; } } - - return itineraries; } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java new file mode 100644 index 00000000000..b2101c0ebfc --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java @@ -0,0 +1,23 @@ +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; + +import java.util.List; +import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; + +public class DecorateFilter implements ItineraryListFilter { + + private final ItineraryDecorator decorator; + + public DecorateFilter(ItineraryDecorator decorator) { + this.decorator = decorator; + } + + @Override + public List filter(List itineraries) { + for (var it : itineraries) { + decorator.decorate(it); + } + return itineraries; + } +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java new file mode 100644 index 00000000000..f1df247f296 --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java @@ -0,0 +1,13 @@ +package org.opentripplanner.routing.algorithm.filterchain.framework.spi; + +import org.opentripplanner.model.plan.Itinerary; + +/** + * Use this interface to decorate itineraries with more information. + */ +public interface ItineraryDecorator { + /** + * Implement this do decorate each itinerary in the result. + */ + void decorate(Itinerary itinerary); +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java index ab839f14798..651d94b4eac 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java @@ -100,7 +100,7 @@ public static ItineraryListFilterChain createFilterChain( } if (!context.rideHailingServices().isEmpty()) { - builder.withRideHailingDecorator( + builder.withRideHailingDecoratingFilter( new DecorateWithRideHailing(context.rideHailingServices(), request.wheelchair()) ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java index 1ba7dde39fe..379eb207155 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitAlertFilterTest.java @@ -6,7 +6,6 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TimePeriod; @@ -32,23 +31,19 @@ void testFilter() { ) ); - DecorateTransitAlert filter = new DecorateTransitAlert(transitAlertService, ignore -> null); - - // Expect filter to no fail on an empty list - assertEquals(List.of(), filter.filter(List.of())); + var decorator = new DecorateTransitAlert(transitAlertService, ignore -> null); // Given a list with one itinerary - List list = List.of( - newItinerary(A).bus(31, 0, 30, E).build(), - newItinerary(B).rail(21, 0, 30, E).build() - ); - - list = filter.filter(list); + var i1 = newItinerary(A).bus(31, 0, 30, E).build(); + decorator.decorate(i1); // Then: expect correct alerts to be added - Itinerary first = list.get(0); - assertEquals(1, first.getLegs().get(0).getTransitAlerts().size()); - assertEquals(ID, first.getLegs().get(0).getTransitAlerts().iterator().next().getId()); - assertEquals(0, list.get(1).getLegs().get(0).getTransitAlerts().size()); + assertEquals(1, i1.getLegs().get(0).getTransitAlerts().size()); + assertEquals(ID, i1.getLegs().get(0).getTransitAlerts().iterator().next().getId()); + + var i2 = newItinerary(B).rail(21, 0, 30, E).build(); + decorator.decorate(i2); + + assertEquals(0, i2.getLegs().get(0).getTransitAlerts().size()); } } From 1ba569ab7328f2621d00b3eaff28dad6b4da2b45 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:30:07 +0200 Subject: [PATCH 076/356] Introduce vehicle walking preferences --- .../common/RequestToPreferencesMapper.java | 10 +- .../apis/gtfs/mapping/RouteRequestMapper.java | 16 +- .../preferences/BikePreferencesMapper.java | 2 +- .../request/preference/BikePreferences.java | 128 ++---------- .../preference/RoutingPreferences.java | 2 +- .../preference/VehicleWalkingPreferences.java | 185 ++++++++++++++++++ .../street/model/edge/BikeWalkableEdge.java | 8 +- .../street/model/edge/StreetEdge.java | 6 +- .../edge/StreetEdgeReluctanceCalculator.java | 4 +- .../BikePreferencesMapperTest.java | 2 +- .../preference/BikePreferencesTest.java | 28 --- .../VehicleWalkingPreferencesTest.java | 77 ++++++++ .../integration/BarrierRoutingTest.java | 5 +- .../street/integration/BikeWalkingTest.java | 2 +- .../street/model/edge/StreetEdgeCostTest.java | 4 +- .../street/model/edge/StreetEdgeTest.java | 12 +- 16 files changed, 325 insertions(+), 166 deletions(-) create mode 100644 src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java create mode 100644 src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 6ccc8d3ca47..68e61d6fe4e 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -67,10 +67,6 @@ private void mapBike() { setIfNotNull(req.bikeSpeed, bike::withSpeed); setIfNotNull(req.bikeReluctance, bike::withReluctance); setIfNotNull(req.bikeBoardCost, bike::withBoardCost); - setIfNotNull(req.bikeWalkingSpeed, bike::withWalkingSpeed); - setIfNotNull(req.bikeWalkingReluctance, bike::withWalkingReluctance); - setIfNotNull(req.bikeSwitchTime, bike::withSwitchTime); - setIfNotNull(req.bikeSwitchCost, bike::withSwitchCost); setIfNotNull(req.bikeOptimizeType, bike::withOptimizeType); if (req.bikeOptimizeType == BicycleOptimizeType.TRIANGLE) { @@ -87,6 +83,12 @@ private void mapBike() { setIfNotNull(req.bikeParkTime, parking::withParkTime); }); bike.withRental(this::mapRental); + bike.withWalking(walk -> { + setIfNotNull(req.bikeWalkingSpeed, walk::withSpeed); + setIfNotNull(req.bikeWalkingReluctance, walk::withReluctance); + setIfNotNull(req.bikeSwitchTime, walk::withHopTime); + setIfNotNull(req.bikeSwitchCost, walk::withHopCost); + }); }); } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index 790064aba22..a12ef45f6fb 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -23,6 +23,7 @@ import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; +import org.opentripplanner.routing.api.request.preference.VehicleWalkingPreferences; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; import org.opentripplanner.routing.core.BicycleOptimizeType; @@ -66,11 +67,7 @@ public static RouteRequest toRouteRequest( request.withPreferences(preferences -> { preferences.withBike(bike -> { callWith.argument("bikeReluctance", bike::withReluctance); - callWith.argument("bikeWalkingReluctance", bike::withWalkingReluctance); - callWith.argument("bikeWalkingSpeed", bike::withWalkingSpeed); callWith.argument("bikeSpeed", bike::withSpeed); - callWith.argument("bikeSwitchTime", bike::withSwitchTime); - callWith.argument("bikeSwitchCost", bike::withSwitchCost); callWith.argument("bikeBoardCost", bike::withBoardCost); if (environment.getArgument("optimize") != null) { @@ -86,6 +83,7 @@ public static RouteRequest toRouteRequest( bike.withParking(parking -> setParkingPreferences(callWith, parking)); bike.withRental(rental -> setRentalPreferences(callWith, request, rental)); + bike.withWalking(walking -> setVehicleWalkingPreferences(callWith, walking)); }); preferences.withCar(car -> { @@ -330,6 +328,16 @@ private static void setRentalPreferences( ); } + private static void setVehicleWalkingPreferences( + CallerWithEnvironment callWith, + VehicleWalkingPreferences.Builder walking + ) { + callWith.argument("bikeWalkingReluctance", walking::withReluctance); + callWith.argument("bikeWalkingSpeed", walking::withSpeed); + callWith.argument("bikeSwitchTime", time -> walking.withHopTime((int) time)); + callWith.argument("bikeSwitchCost", cost -> walking.withHopCost((int) cost)); + } + private static class CallerWithEnvironment { private final DataFetchingEnvironment environment; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java index 3ccdd9007a4..1179c034e93 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java @@ -27,7 +27,7 @@ public static void mapBikePreferences( "walkReluctance", r -> { bike.withReluctance((double) r); - bike.withWalkingReluctance(WALK_BIKE_RELATIVE_RELUCTANCE * (double) r); + bike.withWalking(w -> w.withReluctance(WALK_BIKE_RELATIVE_RELUCTANCE * (double) r)); } ); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 5717876bbfc..f282e02340c 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -25,45 +25,32 @@ public final class BikePreferences implements Serializable { private final double speed; private final double reluctance; private final Cost boardCost; - private final double walkingSpeed; - private final double walkingReluctance; - private final int switchTime; - private final Cost switchCost; private final VehicleParkingPreferences parking; private final VehicleRentalPreferences rental; - private final double stairsReluctance; private final BicycleOptimizeType optimizeType; private final TimeSlopeSafetyTriangle optimizeTriangle; + private final VehicleWalkingPreferences walking; private BikePreferences() { this.speed = 5; this.reluctance = 2.0; this.boardCost = Cost.costOfMinutes(10); - this.walkingSpeed = 1.33; - this.walkingReluctance = 5.0; - this.switchTime = 0; - this.switchCost = Cost.ZERO; this.parking = VehicleParkingPreferences.DEFAULT; this.rental = VehicleRentalPreferences.DEFAULT; this.optimizeType = BicycleOptimizeType.SAFE; this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; - // very high reluctance to carry the bike up/down a flight of stairs - this.stairsReluctance = 10; + this.walking = VehicleWalkingPreferences.DEFAULT; } private BikePreferences(Builder builder) { this.speed = Units.speed(builder.speed); this.reluctance = Units.reluctance(builder.reluctance); this.boardCost = builder.boardCost; - this.walkingSpeed = Units.speed(builder.walkingSpeed); - this.walkingReluctance = Units.reluctance(builder.walkingReluctance); - this.switchTime = Units.duration(builder.switchTime); - this.switchCost = builder.switchCost; this.parking = builder.parking; this.rental = builder.rental; this.optimizeType = Objects.requireNonNull(builder.optimizeType); this.optimizeTriangle = Objects.requireNonNull(builder.optimizeTriangle); - this.stairsReluctance = Units.reluctance(builder.stairsReluctance); + this.walking = builder.walking; } public static BikePreferences.Builder of() { @@ -94,36 +81,6 @@ public int boardCost() { return boardCost.toSeconds(); } - /** - * The walking speed when walking a bike. Default: 1.33 m/s ~ Same as walkSpeed - */ - public double walkingSpeed() { - return walkingSpeed; - } - - /** - * A multiplier for how bad walking is, compared to being in transit for equal - * lengths of time. Empirically, values between 2 and 4 seem to correspond - * well to the concept of not wanting to walk too much without asking for - * totally ridiculous itineraries, but this observation should in no way be - * taken as scientific or definitive. Your mileage may vary. See - * https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on - * performance with high values. Default value: 2.0 - */ - public double walkingReluctance() { - return walkingReluctance; - } - - /** Time to get on and off your own bike */ - public int switchTime() { - return switchTime; - } - - /** Cost of getting on and off your own bike */ - public int switchCost() { - return switchCost.toSeconds(); - } - /** Parking preferences that can be different per request */ public VehicleParkingPreferences parking() { return parking; @@ -145,8 +102,9 @@ public TimeSlopeSafetyTriangle optimizeTriangle() { return optimizeTriangle; } - public double stairsReluctance() { - return stairsReluctance; + /** Bike walking preferences that can be different per request */ + public VehicleWalkingPreferences walking() { + return walking; } @Override @@ -158,15 +116,11 @@ public boolean equals(Object o) { doubleEquals(that.speed, speed) && doubleEquals(that.reluctance, reluctance) && boardCost.equals(that.boardCost) && - doubleEquals(that.walkingSpeed, walkingSpeed) && - doubleEquals(that.walkingReluctance, walkingReluctance) && - switchTime == that.switchTime && - switchCost.equals(that.switchCost) && - parking.equals(that.parking) && - rental.equals(that.rental) && + Objects.equals(parking, that.parking) && + Objects.equals(rental, that.rental) && optimizeType == that.optimizeType && optimizeTriangle.equals(that.optimizeTriangle) && - doubleEquals(stairsReluctance, that.stairsReluctance) + Objects.equals(walking, that.walking) ); } @@ -176,15 +130,11 @@ public int hashCode() { speed, reluctance, boardCost, - walkingSpeed, - walkingReluctance, - switchTime, - switchCost, parking, rental, optimizeType, optimizeTriangle, - stairsReluctance + walking ); } @@ -195,15 +145,11 @@ public String toString() { .addNum("speed", speed, DEFAULT.speed) .addNum("reluctance", reluctance, DEFAULT.reluctance) .addObj("boardCost", boardCost, DEFAULT.boardCost) - .addNum("walkingSpeed", walkingSpeed, DEFAULT.walkingSpeed) - .addNum("walkingReluctance", walkingReluctance, DEFAULT.walkingReluctance) - .addDurationSec("switchTime", switchTime, DEFAULT.switchTime) - .addObj("switchCost", switchCost, DEFAULT.switchCost) .addObj("parking", parking, DEFAULT.parking) .addObj("rental", rental, DEFAULT.rental) .addEnum("optimizeType", optimizeType, DEFAULT.optimizeType) .addObj("optimizeTriangle", optimizeTriangle, DEFAULT.optimizeTriangle) - .addNum("stairsReluctance", stairsReluctance, DEFAULT.stairsReluctance) + .addObj("walking", walking, DEFAULT.walking) .toString(); } @@ -214,31 +160,23 @@ public static class Builder { private double speed; private double reluctance; private Cost boardCost; - private double walkingSpeed; - private double walkingReluctance; - private int switchTime; - private Cost switchCost; private VehicleParkingPreferences parking; private VehicleRentalPreferences rental; private BicycleOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; - public double stairsReluctance; + public VehicleWalkingPreferences walking; public Builder(BikePreferences original) { this.original = original; this.speed = original.speed; this.reluctance = original.reluctance; this.boardCost = original.boardCost; - this.walkingSpeed = original.walkingSpeed; - this.walkingReluctance = original.walkingReluctance; - this.switchTime = original.switchTime; - this.switchCost = original.switchCost; this.parking = original.parking; this.rental = original.rental; this.optimizeType = original.optimizeType; this.optimizeTriangle = original.optimizeTriangle; - this.stairsReluctance = original.stairsReluctance; + this.walking = original.walking; } public BikePreferences original() { @@ -272,42 +210,6 @@ public Builder withBoardCost(int boardCost) { return this; } - public double walkingSpeed() { - return walkingSpeed; - } - - public Builder withWalkingSpeed(double walkingSpeed) { - this.walkingSpeed = walkingSpeed; - return this; - } - - public double walkingReluctance() { - return walkingReluctance; - } - - public Builder withWalkingReluctance(double walkingReluctance) { - this.walkingReluctance = walkingReluctance; - return this; - } - - public int switchTime() { - return switchTime; - } - - public Builder withSwitchTime(int switchTime) { - this.switchTime = switchTime; - return this; - } - - public Cost switchCost() { - return switchCost; - } - - public Builder withSwitchCost(int switchCost) { - this.switchCost = Cost.costOfSeconds(switchCost); - return this; - } - public Builder withParking(Consumer body) { this.parking = ifNotNull(this.parking, original.parking).copyOf().apply(body).build(); return this; @@ -338,8 +240,8 @@ public Builder withOptimizeTriangle(Consumer bo return this; } - public Builder withStairsReluctance(double value) { - this.stairsReluctance = value; + public Builder withWalking(Consumer body) { + this.walking = ifNotNull(this.walking, original.walking).copyOf().apply(body).build(); return this; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java index 3230bbf5968..d3d22160935 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java @@ -129,7 +129,7 @@ public SystemPreferences system() { */ public double getSpeed(TraverseMode mode, boolean walkingBike) { return switch (mode) { - case WALK -> walkingBike ? bike.walkingSpeed() : walk.speed(); + case WALK -> walkingBike ? bike.walking().speed() : walk.speed(); case BICYCLE -> bike.speed(); case CAR -> car.speed(); default -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + mode); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java new file mode 100644 index 00000000000..0abf2926f42 --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java @@ -0,0 +1,185 @@ +package org.opentripplanner.routing.api.request.preference; + +import java.io.Serializable; +import java.time.Duration; +import java.util.Objects; +import java.util.function.Consumer; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.model.Units; +import org.opentripplanner.framework.tostring.ToStringBuilder; + +/** + * Preferences for walking a vehicle. + *

    + * THIS CLASS IS IMMUTABLE AND THREAD-SAFE. + */ +public class VehicleWalkingPreferences implements Serializable { + + public static final VehicleWalkingPreferences DEFAULT = new VehicleWalkingPreferences(); + + private final double speed; + private final double reluctance; + private final Duration hopTime; + private final Cost hopCost; + private final double stairsReluctance; + + private VehicleWalkingPreferences() { + this.speed = 1.33; + this.reluctance = 5.0; + this.hopTime = Duration.ZERO; + this.hopCost = Cost.ZERO; + // very high reluctance to carry the bike up/down a flight of stairs + this.stairsReluctance = 10; + } + + /** + * Sets the vehicle walking preferences and does some input value validation and rounds + * reluctances and speed to not have too many decimals. + */ + private VehicleWalkingPreferences(Builder builder) { + this.speed = Units.speed(builder.speed); + this.reluctance = Units.reluctance(builder.reluctance); + this.hopTime = Duration.ofSeconds(Units.duration(builder.hopTime)); + this.hopCost = Cost.costOfSeconds(builder.hopCost); + this.stairsReluctance = Units.reluctance(builder.stairsReluctance); + } + + public static VehicleWalkingPreferences.Builder of() { + return new VehicleWalkingPreferences.Builder(DEFAULT); + } + + public VehicleWalkingPreferences.Builder copyOf() { + return new VehicleWalkingPreferences.Builder(this); + } + + /** + * The walking speed when walking a vehicle. Default: 1.33 m/s ~ Same as walkSpeed. + */ + public double speed() { + return speed; + } + + /** + * A multiplier for how bad walking is, compared to being in transit for equal + * lengths of time. Empirically, values between 2 and 4 seem to correspond + * well to the concept of not wanting to walk too much without asking for + * totally ridiculous itineraries, but this observation should in no way be + * taken as scientific or definitive. Your mileage may vary. See + * https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on + * performance with high values. Default value: 2.0 + */ + public double reluctance() { + return reluctance; + } + + /** Time to get on and off your own vehicle. */ + public Duration hopTime() { + return hopTime; + } + + /** Cost of getting on and off your own vehicle. */ + public Cost hopCost() { + return hopCost; + } + + /** Reluctance of walking carrying a vehicle up a flight of stairs. */ + public double stairsReluctance() { + return stairsReluctance; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + VehicleWalkingPreferences that = (VehicleWalkingPreferences) o; + return ( + speed == that.speed && + reluctance == that.reluctance && + Objects.equals(hopTime, that.hopTime) && + Objects.equals(hopCost, that.hopCost) && + stairsReluctance == that.stairsReluctance + ); + } + + @Override + public int hashCode() { + return Objects.hash(speed, reluctance, hopTime, hopCost, stairsReluctance); + } + + @Override + public String toString() { + return ToStringBuilder + .of(VehicleWalkingPreferences.class) + .addNum("speed", speed, DEFAULT.speed) + .addNum("reluctance", reluctance, DEFAULT.reluctance) + .addObj("hopTime", hopTime, DEFAULT.hopTime) + .addObj("hopCost", hopCost, DEFAULT.hopCost) + .addNum("stairsReluctance", stairsReluctance, DEFAULT.stairsReluctance) + .toString(); + } + + public static class Builder { + + private final VehicleWalkingPreferences original; + private double speed; + private double reluctance; + private int hopTime; + private int hopCost; + private double stairsReluctance; + + private Builder(VehicleWalkingPreferences original) { + this.original = original; + this.speed = original.speed; + this.reluctance = original.reluctance; + this.hopTime = (int) original.hopTime.toSeconds(); + this.hopCost = original.hopCost.toSeconds(); + this.stairsReluctance = original.stairsReluctance; + } + + public VehicleWalkingPreferences.Builder withSpeed(double speed) { + this.speed = speed; + return this; + } + + public VehicleWalkingPreferences.Builder withReluctance(double reluctance) { + this.reluctance = reluctance; + return this; + } + + public VehicleWalkingPreferences.Builder withHopTime(Duration hopTime) { + this.hopTime = (int) hopTime.toSeconds(); + return this; + } + + public VehicleWalkingPreferences.Builder withHopTime(int hopTime) { + this.hopTime = hopTime; + return this; + } + + public VehicleWalkingPreferences.Builder withHopCost(int hopCost) { + this.hopCost = hopCost; + return this; + } + + public VehicleWalkingPreferences.Builder withStairsReluctance(double stairsReluctance) { + this.stairsReluctance = stairsReluctance; + return this; + } + + public VehicleWalkingPreferences original() { + return original; + } + + public VehicleWalkingPreferences.Builder apply( + Consumer body + ) { + body.accept(this); + return this; + } + + public VehicleWalkingPreferences build() { + var newObj = new VehicleWalkingPreferences(this); + return original.equals(newObj) ? original : newObj; + } + } +} diff --git a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java b/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java index eb17c5d0900..799a5b006e6 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java @@ -17,8 +17,8 @@ default void switchToWalkingBike(RoutingPreferences preferences, StateEditor edi editor.setBackWalkingBike(true); if (shouldIncludeCost) { - editor.incrementWeight(preferences.bike().switchCost()); - editor.incrementTimeInSeconds(preferences.bike().switchTime()); + editor.incrementWeight(preferences.bike().walking().hopCost().toSeconds()); + editor.incrementTimeInSeconds((int) preferences.bike().walking().hopTime().toSeconds()); } } @@ -28,8 +28,8 @@ default void switchToBiking(RoutingPreferences preferences, StateEditor editor) editor.setBackWalkingBike(false); if (shouldIncludeCost) { - editor.incrementWeight(preferences.bike().switchCost()); - editor.incrementTimeInSeconds(preferences.bike().switchTime()); + editor.incrementWeight(preferences.bike().walking().hopCost().toSeconds()); + editor.incrementTimeInSeconds((int) preferences.bike().walking().hopTime().toSeconds()); } } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index d0b0018898a..3f17081b6cb 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -231,7 +231,9 @@ public double calculateSpeed( final double speed = switch (traverseMode) { - case WALK -> walkingBike ? preferences.bike().walkingSpeed() : preferences.walk().speed(); + case WALK -> walkingBike + ? preferences.bike().walking().speed() + : preferences.walk().speed(); case BICYCLE, SCOOTER -> preferences.bike().speed(); case CAR -> getCarSpeed(); case FLEX -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + traverseMode); @@ -1276,7 +1278,7 @@ private TraversalCosts walkingTraversalCosts( time = weight = (getEffectiveBikeDistance() / speed); if (isStairs()) { // we do allow walking the bike across a stairs but there is a very high default penalty - weight *= preferences.bike().stairsReluctance(); + weight *= preferences.bike().walking().stairsReluctance(); } } else { // take slopes into account when walking diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java index 669adc2489f..ee2f3d833ee 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java @@ -10,7 +10,7 @@ private StreetEdgeReluctanceCalculator() {} /** * Compute reluctance for a regular street section. Note! This does not apply if in a wheelchair, - * see {@link #computeWheelchairReluctance(RouteRequest, double, boolean, boolean)}. + * see {@link #computeWheelchairReluctance(RoutingPreferences, double, boolean, boolean)}. */ static double computeReluctance( RoutingPreferences pref, @@ -22,7 +22,7 @@ static double computeReluctance( return pref.walk().stairsReluctance(); } else { return switch (traverseMode) { - case WALK -> walkingBike ? pref.bike().walkingReluctance() : pref.walk().reluctance(); + case WALK -> walkingBike ? pref.bike().walking().reluctance() : pref.walk().reluctance(); case BICYCLE -> pref.bike().reluctance(); case CAR -> pref.car().reluctance(); default -> throw new IllegalArgumentException( diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java index 378571eeea9..a72fd25cbfa 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java @@ -18,7 +18,7 @@ static List mapBikePreferencesTestCases() { Arguments.of( "walkReluctance", 10.0, - "BikePreferences{reluctance: 10.0, walkingReluctance: 27.0}" + "BikePreferences{reluctance: 10.0, walking: VehicleWalkingPreferences{reluctance: 27.0}}" ), Arguments.of("bikeSpeed", 10.0, "BikePreferences{speed: 10.0}"), Arguments.of( diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 9da7852cc2c..9bf287737df 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -11,11 +11,7 @@ class BikePreferencesTest { public static final double SPEED = 2.0; public static final double RELUCTANCE = 1.2; - public static final double WALKING_SPEED = 1.15; public static final int BOARD_COST = 660; - public static final double WALKING_RELUCTANCE = 1.45; - public static final int SWITCH_TIME = 200; - public static final int SWITCH_COST = 450; public static final TimeSlopeSafetyTriangle TRIANGLE = TimeSlopeSafetyTriangle .of() .withSlope(1) @@ -29,10 +25,6 @@ class BikePreferencesTest { .withSpeed(SPEED) .withReluctance(RELUCTANCE) .withBoardCost(BOARD_COST) - .withWalkingSpeed(WALKING_SPEED) - .withWalkingReluctance(WALKING_RELUCTANCE) - .withSwitchTime(SWITCH_TIME) - .withSwitchCost(SWITCH_COST) .withOptimizeType(OPTIMIZE_TYPE) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) .withParking(parking -> parking.withParkCost(PARK_COST).build()) @@ -54,26 +46,6 @@ void boardCost() { assertEquals(BOARD_COST, subject.boardCost()); } - @Test - void walkingSpeed() { - assertEquals(WALKING_SPEED, subject.walkingSpeed()); - } - - @Test - void walkingReluctance() { - assertEquals(WALKING_RELUCTANCE, subject.walkingReluctance()); - } - - @Test - void switchTime() { - assertEquals(SWITCH_TIME, subject.switchTime()); - } - - @Test - void switchCost() { - assertEquals(SWITCH_COST, subject.switchCost()); - } - @Test void optimizeType() { assertEquals(OPTIMIZE_TYPE, subject.optimizeType()); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java new file mode 100644 index 00000000000..9571eee8cc5 --- /dev/null +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java @@ -0,0 +1,77 @@ +package org.opentripplanner.routing.api.request.preference; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; + +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; + +class VehicleWalkingPreferencesTest { + + private static final double SPEED = 1.45; + private static final double RELUCTANCE = 5.5; + private static final Duration HOP_TIME = Duration.ofSeconds(15); + private static final Cost HOP_COST = Cost.costOfSeconds(20); + private static final double STAIRS_RELUCTANCE = 11; + + private final VehicleWalkingPreferences subject = createPreferences(); + + @Test + void speed() { + assertEquals(SPEED, subject.speed()); + } + + @Test + void reluctance() { + assertEquals(RELUCTANCE, subject.reluctance()); + } + + @Test + void hopTime() { + assertEquals(HOP_TIME, subject.hopTime()); + } + + @Test + void hopCost() { + assertEquals(HOP_COST, subject.hopCost()); + } + + @Test + void stairsReluctance() { + assertEquals(STAIRS_RELUCTANCE, subject.stairsReluctance()); + } + + @Test + void testCopyOfEqualsAndHashCode() { + // Create a copy, make a change and set it back again to force creating a new object + var other = subject.copyOf().withSpeed(5.4).build(); + var same = other.copyOf().withSpeed(SPEED).build(); + assertEqualsAndHashCode(subject, other, same); + } + + @Test + void testToString() { + assertEquals("VehicleWalkingPreferences{}", VehicleWalkingPreferences.DEFAULT.toString()); + assertEquals( + "VehicleWalkingPreferences{" + + "speed: 1.45, " + + "reluctance: 5.5, " + + "hopTime: PT15S, " + + "hopCost: $20, " + + "stairsReluctance: 11.0}", + subject.toString() + ); + } + + private VehicleWalkingPreferences createPreferences() { + return VehicleWalkingPreferences + .of() + .withSpeed(SPEED) + .withReluctance(RELUCTANCE) + .withHopTime(HOP_TIME) + .withHopCost(HOP_COST.toSeconds()) + .withStairsReluctance(STAIRS_RELUCTANCE) + .build(); + } +} diff --git a/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java b/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java index e9b979e3b5b..d1ea3c8e59d 100644 --- a/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java @@ -66,7 +66,10 @@ public void shouldWalkForBarriers() { from, to, BIKE, - rr -> rr.withPreferences(p -> p.withBike(it -> it.withWalkingReluctance(1d))), + rr -> + rr.withPreferences(p -> + p.withBike(it -> it.withWalking(walking -> walking.withReluctance(1d))) + ), itineraries -> itineraries .stream() diff --git a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java b/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java index 66086c6d168..417f1b87347 100644 --- a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java @@ -375,7 +375,7 @@ private List runStreetSearchAndCreateDescriptor( preferences .withWalk(w -> w.withSpeed(10)) .withBike(it -> - it.withSpeed(20d).withWalkingSpeed(5d).withSwitchTime(100).withSwitchCost(1000) + it.withSpeed(20d).withWalking(w -> w.withSpeed(5d).withHopTime(100).withHopCost(1000)) ) ); request.setArriveBy(arriveBy); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java index 4712841a8d9..2ecfa51822a 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java @@ -159,7 +159,9 @@ public void bikeStairsReluctance(double stairsReluctance, long expectedCost) { .buildAndConnect(); var req = StreetSearchRequest.of(); - req.withPreferences(p -> p.withBike(b -> b.withStairsReluctance(stairsReluctance))); + req.withPreferences(p -> + p.withBike(b -> b.withWalking(w -> w.withStairsReluctance(stairsReluctance))) + ); req.withMode(StreetMode.BIKE); var result = traverse(stairsEdge, req.build()); assertEquals(expectedCost, (long) result.weight); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index e131bae1a7a..42d841b9fa3 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -55,7 +55,9 @@ public void before() { references .withStreet(s -> s.withTurnReluctance(1.0)) .withWalk(it -> it.withSpeed(1.0).withReluctance(1.0).withStairsReluctance(1.0)) - .withBike(it -> it.withSpeed(5.0f).withReluctance(1.0).withWalkingSpeed(0.8)) + .withBike(it -> + it.withSpeed(5.0f).withReluctance(1.0).withWalking(w -> w.withSpeed(0.8)) + ) .withCar(c -> c.withSpeed(15.0f).withReluctance(1.0)) ) .build(); @@ -218,7 +220,9 @@ public void testBikeSwitch() { StreetEdge e2 = streetEdge(v2, v0, 0.0, StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE); StreetSearchRequestBuilder noPenalty = StreetSearchRequest.copyOf(proto); - noPenalty.withPreferences(p -> p.withBike(it -> it.withSwitchTime(0).withSwitchCost(0))); + noPenalty.withPreferences(p -> + p.withBike(it -> it.withWalking(w -> w.withHopTime(0).withHopCost(0))) + ); State s0 = new State(v0, noPenalty.withMode(StreetMode.BIKE).build()); State s1 = e0.traverse(s0)[0]; @@ -226,7 +230,9 @@ public void testBikeSwitch() { State s3 = e2.traverse(s2)[0]; StreetSearchRequestBuilder withPenalty = StreetSearchRequest.copyOf(proto); - withPenalty.withPreferences(p -> p.withBike(it -> it.withSwitchTime(42).withSwitchCost(23))); + withPenalty.withPreferences(p -> + p.withBike(it -> it.withWalking(w -> w.withHopTime(42).withHopCost(23))) + ); State s4 = new State(v0, withPenalty.withMode(StreetMode.BIKE).build()); State s5 = e0.traverse(s4)[0]; From f96c42bd52b4f22a1778d6baea3e4bfb0faab03a Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:30:48 +0200 Subject: [PATCH 077/356] Restructure and name bike/car preferences in router-config --- docs/RouteRequest.md | 290 +++++++++++------- docs/RouterConfiguration.md | 45 ++- docs/examples/entur/router-config.json | 45 ++- docs/examples/ibi/atlanta/router-config.json | 24 +- .../routerequest/RouteRequestConfig.java | 272 +++------------- .../TriangleOptimizationConfig.java | 53 ++++ .../routerequest/VehicleParkingConfig.java | 93 ++++++ .../routerequest/VehicleRentalConfig.java | 8 +- .../routerequest/VehicleWalkingConfig.java | 82 +++++ .../standalone/config/router-config.json | 45 ++- .../performance/norway/speed-test-config.json | 6 +- .../switzerland/speed-test-config.json | 6 +- 12 files changed, 556 insertions(+), 413 deletions(-) create mode 100644 src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java create mode 100644 src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java create mode 100644 src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 9e891cf732d..755f5f73e28 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -17,29 +17,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |--------------------------------------------------------------------------------------------------------------|:----------------------:|------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|------------------|:-----:| | [alightSlack](#rd_alightSlack) | `duration` | The minimum extra time after exiting a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 | | arriveBy | `boolean` | Whether the trip should depart or arrive at the specified date and time. | *Optional* | `false` | 2.0 | -| [bikeBoardCost](#rd_bikeBoardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. | *Optional* | `600` | 2.0 | -| bikeParkCost | `integer` | Cost to park a bike. | *Optional* | `120` | 2.0 | -| bikeParkTime | `duration` | Time to park a bike. | *Optional* | `"PT1M"` | 2.0 | -| bikeReluctance | `double` | A multiplier for how bad biking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -| bikeSpeed | `double` | Max bike speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | -| bikeStairsReluctance | `double` | How bad is it to walk the bicycle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | -| bikeSwitchCost | `integer` | The cost of the user fetching their bike and parking it again. | *Optional* | `0` | 2.0 | -| bikeSwitchTime | `integer` | The time it takes the user to fetch their bike and park it again in seconds. | *Optional* | `0` | 2.0 | -| bikeTriangleSafetyFactor | `double` | For bike triangle routing, how much safety matters (range 0-1). | *Optional* | `0.0` | 2.0 | -| bikeTriangleSlopeFactor | `double` | For bike triangle routing, how much slope matters (range 0-1). | *Optional* | `0.0` | 2.0 | -| bikeTriangleTimeFactor | `double` | For bike triangle routing, how much time matters (range 0-1). | *Optional* | `0.0` | 2.0 | -| bikeWalkingReluctance | `double` | A multiplier for how bad walking with a bike is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | -| bikeWalkingSpeed | `double` | The user's bike walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | | [boardSlack](#rd_boardSlack) | `duration` | The boardSlack is the minimum extra time to board a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 | -| carAccelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -| carDecelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -| carDropoffTime | `integer` | Time to park a car in a park and ride, w/o taking into account driving and walking cost. | *Optional* | `120` | 2.0 | -| carParkCost | `integer` | Cost of parking a car. | *Optional* | `120` | 2.1 | -| carParkTime | `duration` | Time to park a car | *Optional* | `"PT1M"` | 2.1 | -| carPickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | -| carPickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | -| carReluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -| carSpeed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | | [drivingDirection](#rd_drivingDirection) | `enum` | The driving direction to use in the intersection traversal calculation | *Optional* | `"right"` | 2.2 | | elevatorBoardCost | `integer` | What is the cost of boarding a elevator? | *Optional* | `90` | 2.0 | | elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 | @@ -55,7 +33,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | modes | `string` | The set of access/egress/direct/transit modes to be used for the route search. | *Optional* | `"TRANSIT,WALK"` | 2.0 | | nonpreferredTransferPenalty | `integer` | Penalty (in seconds) for using a non-preferred transfer. | *Optional* | `180` | 2.0 | | numItineraries | `integer` | The maximum number of itineraries to return. | *Optional* | `50` | 2.0 | -| [optimize](#rd_optimize) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | | [otherThanPreferredRoutesPenalty](#rd_otherThanPreferredRoutesPenalty) | `integer` | Penalty added for using every route that is not preferred if user set any route as preferred. | *Optional* | `300` | 2.0 | | [relaxTransitPriorityGroup](#rd_relaxTransitPriorityGroup) | `string` | The relax function for transit-priority-groups | *Optional* | `"0s + 1.00 t"` | 2.5 | | [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | @@ -67,7 +44,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [transferSlack](#rd_transferSlack) | `integer` | The extra time needed to make a safe transfer in seconds. | *Optional* | `120` | 2.0 | | turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 | | [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 | -| [unpreferredVehicleParkingTagCost](#rd_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | | waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 | | walkBoardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | | [walkReluctance](#rd_walkReluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | @@ -82,8 +58,55 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |          costFactor | `double` | A factor multiplied with the time-penalty to get the cost-penalty. | *Optional* | `0.0` | 2.4 | |          timePenalty | `time-penalty` | Penalty added to the time of a path/leg. | *Optional* | `"0s + 0.00 t"` | 2.4 | | [alightSlackForMode](#rd_alightSlackForMode) | `enum map of duration` | How much extra time should be given when alighting a vehicle for each given mode. | *Optional* | | 2.0 | -| [bannedVehicleParkingTags](#rd_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +| bicycle | `object` | Bicycle preferences. | *Optional* | | 2.5 | +|    [boardCost](#rd_bicycle_boardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. | *Optional* | `600` | 2.0 | +|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | +|    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | +|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       [unpreferredVehicleParkingTagCost](#rd_bicycle_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | +|       [bannedVehicleParkingTags](#rd_bicycle_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +|       [preferredVehicleParkingTags](#rd_bicycle_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | +|       [requiredVehicleParkingTags](#rd_bicycle_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | +|    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|    walking | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | +|       [hopCost](#rd_bicycle_walking_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [hopTime](#rd_bicycle_walking_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | +|       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | +|       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | | [boardSlackForMode](#rd_boardSlackForMode) | `enum map of duration` | How much extra time should be given when boarding a vehicle for each given mode. | *Optional* | | 2.0 | +| car | `object` | Car preferences. | *Optional* | | 2.5 | +|    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | +|    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | +|    dropoffTime | `integer` | Time to park a car in a park and ride, w/o taking into account driving and walking cost. | *Optional* | `120` | 2.0 | +|    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | +|    pickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | +|    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | +|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_car_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_car_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | | [itineraryFilters](#rd_itineraryFilters) | `object` | Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results. | *Optional* | | 2.0 | |    [accessibilityScore](#rd_if_accessibilityScore) | `boolean` | An experimental feature contributed by IBI which adds a sandbox accessibility *score* between 0 and 1 for each leg and itinerary. | *Optional* | `false` | 2.2 | |    [bikeRentalDistanceRatio](#rd_if_bikeRentalDistanceRatio) | `double` | Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using _distance_. | *Optional* | `0.0` | 2.1 | @@ -101,8 +124,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [costLimitFunction](#rd_if_transitGeneralizedCostLimit_costLimitFunction) | `cost-linear-function` | The base function used by the filter. | *Optional* | `"15m + 1.50 t"` | 2.2 | |       [intervalRelaxFactor](#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor) | `double` | How much the filter should be relaxed for itineraries that do not overlap in time. | *Optional* | `0.4` | 2.2 | | [maxDirectStreetDurationForMode](#rd_maxDirectStreetDurationForMode) | `enum map of duration` | Limit direct route duration per street mode. | *Optional* | | 2.2 | -| [preferredVehicleParkingTags](#rd_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | -| [requiredVehicleParkingTags](#rd_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | | [transferOptimization](#rd_transferOptimization) | `object` | Optimize where a transfer between to trip happens. | *Optional* | | 2.1 | |    [backTravelWaitTimeFactor](#rd_to_backTravelWaitTimeFactor) | `double` | To reduce back-travel we favor waiting, this reduces the cost of waiting. | *Optional* | `1.0` | 2.1 | |    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | @@ -113,16 +134,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | |    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | |    [routes](#rd_unpreferred_routes) | `feed-scoped-id[]` | The ids of the routes that incur an extra cost when being used. Format: `FeedId:RouteId` | *Optional* | | 2.2 | -| vehicleRental | `object` | Vehicle rental options | *Optional* | | 2.3 | -|    allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | -|    dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|    dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|    keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | -|    pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|    pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | -|    useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | -|    [allowedNetworks](#rd_vehicleRental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | -|    [bannedNetworks](#rd_vehicleRental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | | wheelchairAccessibility | `object` | See [Wheelchair Accessibility](Accessibility.md) | *Optional* | | 2.2 | |    enabled | `boolean` | Enable wheelchair accessibility. | *Optional* | `false` | 2.0 | |    inaccessibleStreetReluctance | `double` | The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. | *Optional* | `25.0` | 2.2 | @@ -159,15 +170,6 @@ The minimum extra time after exiting a public transport vehicle. The slack is added to the time when going from the transit vehicle to the stop. -

    bikeBoardCost

    - -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `600` -**Path:** /routingDefaults - -Prevents unnecessary transfers by adding a cost for boarding a vehicle. - -This is the cost that is used when boarding while cycling.This is usually higher that walkBoardCost. -

    boardSlack

    **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` @@ -230,14 +232,6 @@ search, hence, making it a bit slower. Recommended values would be from 12 hours 1 day (region) to 2 days (country like Norway)." -

    optimize

    - -**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe"` -**Path:** /routingDefaults -**Enum values:** `quick` | `safe` | `flat` | `greenways` | `triangle` - -The set of characteristics that the user wants to optimize for. -

    otherThanPreferredRoutesPenalty

    **Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` @@ -364,15 +358,6 @@ Function should return number of seconds that we are willing to wait for preferr or for an unpreferred agency's departure. For example: `5m + 2.0 t` -

    unpreferredVehicleParkingTagCost

    - -**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` -**Path:** /routingDefaults - -What cost to add if a parking facility doesn't contain a preferred tag. - -See `preferredVehicleParkingTags`. -

    walkReluctance

    **Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `2.0` @@ -473,16 +458,98 @@ How much extra time should be given when alighting a vehicle for each given mode Sometimes there is a need to configure a longer alighting times for specific modes, such as airplanes or ferries. -

    bannedVehicleParkingTags

    +

    boardCost

    + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `600` +**Path:** /routingDefaults/bicycle + +Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. + +This is the cost that is used when boarding while cycling.This is usually higher that walkBoardCost. + +

    optimization

    + +**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe"` +**Path:** /routingDefaults/bicycle +**Enum values:** `quick` | `safe` | `flat` | `greenways` | `triangle` + +The set of characteristics that the user wants to optimize for. + +

    unpreferredVehicleParkingTagCost

    + +**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` +**Path:** /routingDefaults/bicycle/parking + +What cost to add if a parking facility doesn't contain a preferred tag. + +See `preferredVehicleParkingTags`. + +

    bannedVehicleParkingTags

    **Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults +**Path:** /routingDefaults/bicycle/parking Tags with which a vehicle parking will not be used. If empty, no tags are banned. Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). +

    preferredVehicleParkingTags

    + +**Since version:** `2.3` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/parking + +Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

    requiredVehicleParkingTags

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/parking + +Tags without which a vehicle parking will not be used. If empty, no tags are required. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

    allowedNetworks

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/rental + +The vehicle rental networks which may be used. If empty all networks may be used. + +

    bannedNetworks

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/rental + +The vehicle rental networks which may not be used. If empty, no networks are banned. + +

    hopCost

    + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` +**Path:** /routingDefaults/bicycle/walking + +The cost of hopping on or off a vehicle. + +There are different parameters for the cost of renting or parking a vehicle and this is +not meant for controlling the cost of those events. + + +

    hopTime

    + +**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` +**Path:** /routingDefaults/bicycle/walking + +The time it takes the user to hop on or off a vehicle in seconds. + +Time it takes to rent or park a vehicle have their own parameters and this is not meant +for controlling the duration of those events. + +

    boardSlackForMode

    **Since version:** `2.0` ∙ **Type:** `enum map of duration` ∙ **Cardinality:** `Optional` @@ -495,6 +562,20 @@ Sometimes there is a need to configure a board times for specific modes, such as ferries, where the check-in process needs to be done in good time before ride. +

    allowedNetworks

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/rental + +The vehicle rental networks which may be used. If empty all networks may be used. + +

    bannedNetworks

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/rental + +The vehicle rental networks which may not be used. If empty, no networks are banned. +

    itineraryFilters

    **Since version:** `2.0` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` @@ -710,26 +791,6 @@ Override the settings in `maxDirectStreetDuration` for specific street modes. Th done because some street modes searches are much more resource intensive than others. -

    preferredVehicleParkingTags

    - -**Since version:** `2.3` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults - -Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. - -Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - - -

    requiredVehicleParkingTags

    - -**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults - -Tags without which a vehicle parking will not be used. If empty, no tags are required. - -Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - -

    transferOptimization

    **Since version:** `2.1` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` @@ -873,20 +934,6 @@ The ids of the routes that incur an extra cost when being used. Format: `FeedId: How much cost is added is configured in `unpreferredCost`. -

    allowedNetworks

    - -**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults/vehicleRental - -The vehicle rental networks which may be used. If empty all networks may be used. - -

    bannedNetworks

    - -**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults/vehicleRental - -The vehicle rental networks which may not be used. If empty, no networks are banned. -

    maxSlope

    **Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.083` @@ -934,15 +981,9 @@ include stairs as a last result. { "routingDefaults" : { "walkSpeed" : 1.3, - "bikeSpeed" : 5, - "carSpeed" : 40, "numItineraries" : 12, "transferPenalty" : 0, "walkReluctance" : 4.0, - "bikeReluctance" : 5.0, - "bikeWalkingReluctance" : 10.0, - "bikeStairsReluctance" : 150.0, - "carReluctance" : 10.0, "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, @@ -950,17 +991,38 @@ include stairs as a last result. "elevatorHopTime" : 20, "elevatorHopCost" : 20, "escalatorReluctance" : 1.5, - "vehicleRental" : { - "pickupCost" : 120, - "dropOffTime" : 30, - "dropOffCost" : 30 + "bicycle" : { + "speed" : 5, + "reluctance" : 5.0, + "boardCost" : 600, + "walking" : { + "reluctance" : 10.0, + "stairsReluctance" : 150.0 + }, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "1m", + "parkCost" : 120 + } + }, + "car" : { + "speed" : 40, + "reluctance" : 10, + "dropoffTime" : 120, + "decelerationSpeed" : 2.9, + "accelerationSpeed" : 2.9, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + } }, - "bikeParkTime" : "1m", - "bikeParkCost" : 120, - "carDropoffTime" : 120, "waitReluctance" : 1.0, "walkBoardCost" : 600, - "bikeBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { @@ -997,8 +1059,6 @@ include stairs as a last result. "minBikeParkingDistance" : 300, "debug" : "limit-to-search-window" }, - "carDecelerationSpeed" : 2.9, - "carAccelerationSpeed" : 2.9, "ignoreRealtimeUpdates" : false, "geoidElevation" : false, "maxJourneyDuration" : "36h", diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 65f50260ee5..37a673ea7a2 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -452,15 +452,9 @@ Used to group requests when monitoring OTP. }, "routingDefaults" : { "walkSpeed" : 1.3, - "bikeSpeed" : 5, - "carSpeed" : 40, "numItineraries" : 12, "transferPenalty" : 0, "walkReluctance" : 4.0, - "bikeReluctance" : 5.0, - "bikeWalkingReluctance" : 10.0, - "bikeStairsReluctance" : 150.0, - "carReluctance" : 10.0, "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, @@ -468,17 +462,38 @@ Used to group requests when monitoring OTP. "elevatorHopTime" : 20, "elevatorHopCost" : 20, "escalatorReluctance" : 1.5, - "vehicleRental" : { - "pickupCost" : 120, - "dropOffTime" : 30, - "dropOffCost" : 30 + "bicycle" : { + "speed" : 5, + "reluctance" : 5.0, + "boardCost" : 600, + "walking" : { + "reluctance" : 10.0, + "stairsReluctance" : 150.0 + }, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "1m", + "parkCost" : 120 + } + }, + "car" : { + "speed" : 40, + "reluctance" : 10, + "dropoffTime" : 120, + "decelerationSpeed" : 2.9, + "accelerationSpeed" : 2.9, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + } }, - "bikeParkTime" : "1m", - "bikeParkCost" : 120, - "carDropoffTime" : 120, "waitReluctance" : 1.0, "walkBoardCost" : 600, - "bikeBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { @@ -515,8 +530,6 @@ Used to group requests when monitoring OTP. "minBikeParkingDistance" : 300, "debug" : "limit-to-search-window" }, - "carDecelerationSpeed" : 2.9, - "carAccelerationSpeed" : 2.9, "ignoreRealtimeUpdates" : false, "geoidElevation" : false, "maxJourneyDuration" : "36h", diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index 0023dab130a..2d217cb2402 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -2,31 +2,46 @@ "configVersion" : "{{ Entur CI config build number inserted here }}", "routingDefaults": { "walkSpeed": 1.3, - "bikeSpeed": 5, - "carSpeed": 40, "numItineraries": 12, "transferPenalty": 0, "walkReluctance": 4.0, - "bikeReluctance": 5.0, - "bikeWalkingReluctance": 10.0, - "carReluctance": 10.0, "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, "elevatorBoardCost": 90, "elevatorHopTime": 20, "elevatorHopCost": 20, - "vehicleRental": { - "pickupCost": 120, - "dropOffTime": 30, - "dropOffCost": 30 + "bicycle": { + "speed": 5, + "reluctance": 5.0, + "boardCost": 600, + "walking": { + "reluctance": 10.0 + }, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + }, + "parking": { + "parkTime": "1m", + "parkCost": 120 + } + }, + "car": { + "speed": 40, + "reluctance": 4.0, + "dropoffTime": 120, + "decelerationSpeed": 2.9, + "accelerationSpeed": 2.9, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + } }, - "bikeParkTime": "1m", - "bikeParkCost": 120, - "carDropoffTime": 120, "waitReluctance": 1.0, "walkBoardCost": 600, - "bikeBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) @@ -41,15 +56,13 @@ }, "accessEgress": { "maxDurationForMode": { - "BIKE_RENTAL": "20m" + "BIKE_RENTAL": "20m" } }, "itineraryFilters" : { "transitGeneralizedCostLimit" : "1h + 2.5 x", "bikeRentalDistanceRatio": 0.3 }, - "carDecelerationSpeed": 2.9, - "carAccelerationSpeed": 2.9, "ignoreRealtimeUpdates": false, "geoidElevation": false, "maxJourneyDuration": "36h", diff --git a/docs/examples/ibi/atlanta/router-config.json b/docs/examples/ibi/atlanta/router-config.json index 5202fe227c1..2aeb3e6434e 100644 --- a/docs/examples/ibi/atlanta/router-config.json +++ b/docs/examples/ibi/atlanta/router-config.json @@ -1,18 +1,28 @@ { "routingDefaults": { - "bikeTriangleSafetyFactor": 0.4, - "bikeTriangleSlopeFactor": 0.3, - "bikeTriangleTimeFactor": 0.3, + "bicycle": { + "triangle": { + "time": 0.3, + "flatness": 0.3, + "safety": 0.4 + }, + "rental": { + "pickupTime": 180, + "pickupCost": 850 + } + }, + "car": { + "rental": { + "pickupTime": 180, + "pickupCost": 850 + } + }, "itineraryFilters": { // only show non-transit (ie. walking) when it's at least as good as the transit option "nonTransitGeneralizedCostLimit": "0 + 1.0 x", // add IBI accessibility score between 0 and 1 "accessibilityScore": true }, - "vehicleRental": { - "pickupTime": 180, - "pickupCost": 850 - }, // use stop and trip with unknown wheelchair accessibility during routing "wheelchairAccessibility": { "trip": { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index e600f1f8f12..0ff1c48cf2b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -8,11 +8,13 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; import static org.opentripplanner.standalone.config.routerequest.ItineraryFiltersConfig.mapItineraryFilterParams; import static org.opentripplanner.standalone.config.routerequest.TransferConfig.mapTransferPreferences; -import static org.opentripplanner.standalone.config.routerequest.VehicleRentalConfig.setVehicleRental; +import static org.opentripplanner.standalone.config.routerequest.TriangleOptimizationConfig.mapOptimizationTriangle; +import static org.opentripplanner.standalone.config.routerequest.VehicleParkingConfig.mapParking; +import static org.opentripplanner.standalone.config.routerequest.VehicleRentalConfig.mapRental; +import static org.opentripplanner.standalone.config.routerequest.VehicleWalkingConfig.mapVehicleWalking; import static org.opentripplanner.standalone.config.routerequest.WheelchairConfig.mapWheelchairPreferences; import java.time.Duration; -import java.util.List; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.routing.api.request.RequestModes; @@ -25,7 +27,6 @@ import org.opentripplanner.routing.api.request.preference.StreetPreferences; import org.opentripplanner.routing.api.request.preference.SystemPreferences; import org.opentripplanner.routing.api.request.preference.TransitPreferences; -import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.WalkPreferences; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.sandbox.DataOverlayParametersMapper; @@ -335,176 +336,48 @@ The board time is added to the time when going from the stop (offboard) to onboa private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder builder) { var dft = builder.original(); + NodeAdapter cb = c.of("bicycle").since(V2_5).summary("Bicycle preferences.").asObject(); builder .withSpeed( - c - .of("bikeSpeed") + cb + .of("speed") .since(V2_0) - .summary("Max bike speed along streets, in meters per second") + .summary("Max bicycle speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - c - .of("bikeReluctance") + cb + .of("reluctance") .since(V2_0) .summary( - "A multiplier for how bad biking is, compared to being in transit for equal lengths of time." + "A multiplier for how bad cycling is, compared to being in transit for equal lengths of time." ) .asDouble(dft.reluctance()) ) .withBoardCost( - c - .of("bikeBoardCost") + cb + .of("boardCost") .since(V2_0) - .summary("Prevents unnecessary transfers by adding a cost for boarding a vehicle.") + .summary( + "Prevents unnecessary transfers by adding a cost for boarding a transit vehicle." + ) .description( "This is the cost that is used when boarding while cycling." + "This is usually higher that walkBoardCost." ) .asInt(dft.boardCost()) ) - .withWalkingSpeed( - c - .of("bikeWalkingSpeed") - .since(V2_1) - .summary( - "The user's bike walking speed in meters/second. Defaults to approximately 3 MPH." - ) - .asDouble(dft.walkingSpeed()) - ) - .withWalkingReluctance( - c - .of("bikeWalkingReluctance") - .since(V2_1) - .summary( - "A multiplier for how bad walking with a bike is, compared to being in transit for equal lengths of time." - ) - .asDouble(dft.walkingReluctance()) - ) - .withSwitchTime( - c - .of("bikeSwitchTime") - .since(V2_0) - .summary("The time it takes the user to fetch their bike and park it again in seconds.") - .asInt(dft.switchTime()) - ) - .withSwitchCost( - c - .of("bikeSwitchCost") - .since(V2_0) - .summary("The cost of the user fetching their bike and parking it again.") - .asInt(dft.switchCost()) - ) .withOptimizeType( - c - .of("optimize") + cb + .of("optimization") .since(V2_0) .summary("The set of characteristics that the user wants to optimize for.") .asEnum(dft.optimizeType()) ) - .withOptimizeTriangle(it -> - it - .withTime( - c - .of("bikeTriangleTimeFactor") - .since(V2_0) - .summary("For bike triangle routing, how much time matters (range 0-1).") - .asDouble(it.time()) - ) - .withSlope( - c - .of("bikeTriangleSlopeFactor") - .since(V2_0) - .summary("For bike triangle routing, how much slope matters (range 0-1).") - .asDouble(it.slope()) - ) - .withSafety( - c - .of("bikeTriangleSafetyFactor") - .since(V2_0) - .summary("For bike triangle routing, how much safety matters (range 0-1).") - .asDouble(it.safety()) - ) - ) - .withStairsReluctance( - c - .of("bikeStairsReluctance") - .since(V2_3) - .summary( - "How bad is it to walk the bicycle up/down a flight of stairs compared to taking a detour." - ) - .asDouble(dft.stairsReluctance()) - ) - .withParking(it -> - it - .withUnpreferredVehicleParkingTagCost( - c - .of("unpreferredVehicleParkingTagCost") - .since(V2_3) - .summary("What cost to add if a parking facility doesn't contain a preferred tag.") - .description("See `preferredVehicleParkingTags`.") - .asInt( - VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds() - ) - ) - .withBannedVehicleParkingTags( - c - .of("bannedVehicleParkingTags") - .since(V2_1) - .summary( - "Tags with which a vehicle parking will not be used. If empty, no tags are banned." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withRequiredVehicleParkingTags( - c - .of("requiredVehicleParkingTags") - .since(V2_1) - .summary( - "Tags without which a vehicle parking will not be used. If empty, no tags are required." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withParkTime( - c - .of("bikeParkTime") - .since(V2_0) - .summary("Time to park a bike.") - .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) - ) - .withParkCost( - c - .of("bikeParkCost") - .since(V2_0) - .summary("Cost to park a bike.") - .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) - ) - .withPreferredVehicleParkingTags( - c - .of("preferredVehicleParkingTags") - .since(V2_3) - .summary( - "Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - ) - .withRental(it -> setVehicleRental(c, it)); + .withOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) + .withWalking(it -> mapVehicleWalking(cb, it)) + .withParking(it -> mapParking(cb, it)) + .withRental(it -> mapRental(cb, it)); } private static void mapStreetPreferences(NodeAdapter c, StreetPreferences.Builder builder) { @@ -695,17 +568,18 @@ The street search(AStar) aborts after this duration and any paths found are retu private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder builder) { var dft = builder.original(); + NodeAdapter cc = c.of("car").since(V2_5).summary("Car preferences.").asObject(); builder .withSpeed( - c - .of("carSpeed") + cc + .of("speed") .since(V2_0) .summary("Max car speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - c - .of("carReluctance") + cc + .of("reluctance") .since(V2_0) .summary( "A multiplier for how bad driving is, compared to being in transit for equal lengths of time." @@ -713,8 +587,8 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .asDouble(dft.reluctance()) ) .withDropoffTime( - c - .of("carDropoffTime") + cc + .of("dropoffTime") .since(V2_0) .summary( "Time to park a car in a park and ride, w/o taking into account driving and walking cost." @@ -722,103 +596,35 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .asInt(dft.dropoffTime()) ) .withPickupCost( - c - .of("carPickupCost") + cc + .of("pickupCost") .since(V2_1) .summary("Add a cost for car pickup changes when a pickup or drop off takes place") .asInt(dft.pickupCost()) ) .withPickupTime( - c - .of("carPickupTime") + cc + .of("pickupTime") .since(V2_1) .summary("Add a time for car pickup changes when a pickup or drop off takes place") .asInt(dft.pickupTime()) ) .withAccelerationSpeed( - c - .of("carAccelerationSpeed") + cc + .of("accelerationSpeed") .since(V2_0) .summary("The acceleration speed of an automobile, in meters per second per second.") .asDouble(dft.accelerationSpeed()) ) .withDecelerationSpeed( - c - .of("carDecelerationSpeed") + cc + .of("decelerationSpeed") .since(V2_0) .summary("The deceleration speed of an automobile, in meters per second per second.") .asDouble(dft.decelerationSpeed()) ) - .withParking(it -> - it - .withUnpreferredVehicleParkingTagCost( - c - .of("unpreferredVehicleParkingTagCost") - .since(V2_3) - .summary("What cost to add if a parking facility doesn't contain a preferred tag.") - .description("See `preferredVehicleParkingTags`.") - .asInt( - VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds() - ) - ) - .withBannedVehicleParkingTags( - c - .of("bannedVehicleParkingTags") - .since(V2_1) - .summary( - "Tags with which a vehicle parking will not be used. If empty, no tags are banned." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withRequiredVehicleParkingTags( - c - .of("requiredVehicleParkingTags") - .since(V2_1) - .summary( - "Tags without which a vehicle parking will not be used. If empty, no tags are required." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withParkCost( - c - .of("carParkCost") - .since(V2_1) - .summary("Cost of parking a car.") - .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) - ) - .withParkTime( - c - .of("carParkTime") - .since(V2_1) - .summary("Time to park a car") - .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) - ) - .withPreferredVehicleParkingTags( - c - .of("preferredVehicleParkingTags") - .since(V2_3) - .summary( - "Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - ) - .withRental(it -> setVehicleRental(c, it)); + .withParking(it -> mapParking(cc, it)) + .withRental(it -> mapRental(cc, it)); } private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builder builder) { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java new file mode 100644 index 00000000000..e4988b02767 --- /dev/null +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java @@ -0,0 +1,53 @@ +package org.opentripplanner.standalone.config.routerequest; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; + +import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +public class TriangleOptimizationConfig { + + private static void mapTriangleParameters( + NodeAdapter c, + TimeSlopeSafetyTriangle.Builder builder + ) { + builder + .withTime( + c + .of("time") + .since(V2_0) + .summary("Relative importance of duration of travel (range 0-1).") + .asDouble(builder.time()) + ) + .withSlope( + c + .of("flatness") + .since(V2_0) + .summary("Relative importance of flat terrain (range 0-1).") + .asDouble(builder.slope()) + ) + .withSafety( + c + .of("safety") + .since(V2_0) + .summary("Relative importance of safety (range 0-1).") + .description( + """ + This factor can also include other concerns such as convenience and general cyclist + preferences by taking into account road surface etc. + """ + ) + .asDouble(builder.safety()) + ); + } + + static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Builder preferences) { + var optimizationTriangle = c + .of("triangle") + .since(V2_5) + .summary("Triangle optimization criteria.") + .asObject(); + mapTriangleParameters(optimizationTriangle, preferences); + } +} diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java new file mode 100644 index 00000000000..951129bc7b7 --- /dev/null +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java @@ -0,0 +1,93 @@ +package org.opentripplanner.standalone.config.routerequest; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; + +import java.util.List; +import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +public class VehicleParkingConfig { + + private static void mapParkingPreferences( + NodeAdapter c, + VehicleParkingPreferences.Builder builder + ) { + builder + .withUnpreferredVehicleParkingTagCost( + c + .of("unpreferredVehicleParkingTagCost") + .since(V2_3) + .summary("What cost to add if a parking facility doesn't contain a preferred tag.") + .description("See `preferredVehicleParkingTags`.") + .asInt(VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds()) + ) + .withBannedVehicleParkingTags( + c + .of("bannedVehicleParkingTags") + .since(V2_1) + .summary( + "Tags with which a vehicle parking will not be used. If empty, no tags are banned." + ) + .description( + """ + Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + """ + ) + .asStringSet(List.of()) + ) + .withRequiredVehicleParkingTags( + c + .of("requiredVehicleParkingTags") + .since(V2_1) + .summary( + "Tags without which a vehicle parking will not be used. If empty, no tags are required." + ) + .description( + """ + Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + """ + ) + .asStringSet(List.of()) + ) + .withParkTime( + c + .of("parkTime") + .since(V2_0) + .summary("Time to park a vehicle.") + .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) + ) + .withParkCost( + c + .of("parkCost") + .since(V2_0) + .summary("Cost to park a vehicle.") + .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) + ) + .withPreferredVehicleParkingTags( + c + .of("preferredVehicleParkingTags") + .since(V2_3) + .summary( + "Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised." + ) + .description( + """ + Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + """ + ) + .asStringSet(List.of()) + ); + } + + static void mapParking(NodeAdapter c, VehicleParkingPreferences.Builder preferences) { + var vehicleParking = c + .of("parking") + .since(V2_5) + .summary("Preferences for parking a vehicle.") + .asObject(); + mapParkingPreferences(vehicleParking, preferences); + } +} diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index 057daa7001c..3d1534f5753 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -80,12 +80,8 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder ); } - static void setVehicleRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { - var vehicleRental = c - .of("vehicleRental") - .since(V2_3) - .summary("Vehicle rental options") - .asObject(); + static void mapRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { + var vehicleRental = c.of("rental").since(V2_3).summary("Vehicle rental options").asObject(); mapRentalPreferences(vehicleRental, preferences); } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java new file mode 100644 index 00000000000..e8ccbffe4df --- /dev/null +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -0,0 +1,82 @@ +package org.opentripplanner.standalone.config.routerequest; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; + +import org.opentripplanner.routing.api.request.preference.VehicleWalkingPreferences; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +public class VehicleWalkingConfig { + + private static void mapVehicleWalkingPreferences( + NodeAdapter c, + VehicleWalkingPreferences.Builder builder + ) { + var dft = builder.original(); + builder + .withSpeed( + c + .of("speed") + .since(V2_1) + .summary( + "The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH." + ) + .asDouble(dft.speed()) + ) + .withReluctance( + c + .of("reluctance") + .since(V2_1) + .summary( + "A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time." + ) + .asDouble(dft.reluctance()) + ) + .withHopTime( + c + .of("hopTime") + .since(V2_0) + .summary("The time it takes the user to hop on or off a vehicle in seconds.") + .description( + """ + Time it takes to rent or park a vehicle have their own parameters and this is not meant + for controlling the duration of those events. + """ + ) + .asDuration(dft.hopTime()) + ) + .withHopCost( + c + .of("hopCost") + .since(V2_0) + .summary("The cost of hopping on or off a vehicle.") + .description( + """ + There are different parameters for the cost of renting or parking a vehicle and this is + not meant for controlling the cost of those events. + """ + ) + .asInt(dft.hopCost().toSeconds()) + ) + .withStairsReluctance( + c + .of("stairsReluctance") + .since(V2_3) + .summary( + "How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour." + ) + .asDouble(dft.stairsReluctance()) + ); + } + + static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { + var vehicleWalking = c + .of("walking") + .since(V2_5) + .summary("Preferences for walking a vehicle.") + .asObject(); + mapVehicleWalkingPreferences(vehicleWalking, preferences); + } +} diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 69f859d784d..d9c1e8e8c19 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -13,15 +13,9 @@ }, "routingDefaults": { "walkSpeed": 1.3, - "bikeSpeed": 5, - "carSpeed": 40, "numItineraries": 12, "transferPenalty": 0, "walkReluctance": 4.0, - "bikeReluctance": 5.0, - "bikeWalkingReluctance": 10.0, - "bikeStairsReluctance": 150.0, - "carReluctance": 10.0, "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, @@ -29,17 +23,38 @@ "elevatorHopTime": 20, "elevatorHopCost": 20, "escalatorReluctance": 1.5, - "vehicleRental": { - "pickupCost": 120, - "dropOffTime": 30, - "dropOffCost": 30 + "bicycle": { + "speed": 5, + "reluctance": 5.0, + "boardCost": 600, + "walking": { + "reluctance": 10.0, + "stairsReluctance": 150.0 + }, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + }, + "parking": { + "parkTime": "1m", + "parkCost": 120 + } + }, + "car": { + "speed": 40, + "reluctance": 10, + "dropoffTime": 120, + "decelerationSpeed": 2.9, + "accelerationSpeed": 2.9, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + } }, - "bikeParkTime": "1m", - "bikeParkCost": 120, - "carDropoffTime": 120, "waitReluctance": 1.0, "walkBoardCost": 600, - "bikeBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) @@ -74,8 +89,6 @@ "minBikeParkingDistance": 300, "debug": "limit-to-search-window" }, - "carDecelerationSpeed": 2.9, - "carAccelerationSpeed": 2.9, "ignoreRealtimeUpdates": false, "geoidElevation": false, "maxJourneyDuration": "36h", diff --git a/test/performance/norway/speed-test-config.json b/test/performance/norway/speed-test-config.json index e673155eb4f..cef9b1ef061 100644 --- a/test/performance/norway/speed-test-config.json +++ b/test/performance/norway/speed-test-config.json @@ -41,8 +41,10 @@ "routingDefaults": { // Default is 1.4 m/s = ~ 5.0 km/t "walkSpeed": 1.4, - // Should not be used - a high cost indicate an error - "bikeBoardCost": 222000, + "bicycle": { + // Should not be used - a high cost indicate an error + "boardCost": 222000 + }, "walkBoardCost": 600, "transferPenalty": 0, "walkReluctance": 4.0, diff --git a/test/performance/switzerland/speed-test-config.json b/test/performance/switzerland/speed-test-config.json index f37c8497ffa..8b622825d09 100644 --- a/test/performance/switzerland/speed-test-config.json +++ b/test/performance/switzerland/speed-test-config.json @@ -41,8 +41,10 @@ "routingDefaults": { // Default is 1.4 m/s = ~ 5.0 km/t "walkSpeed": 1.4, - // Should not be used - a high cost indicate an error - "bikeBoardCost": 222000, + "bicycle": { + // Should not be used - a high cost indicate an error + "boardCost": 222000 + }, "walkBoardCost": 600, "transferPenalty": 0, "walkReluctance": 4.0, From d199e392e90062e810ea749312964eab21ab4851 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:56:19 +0200 Subject: [PATCH 078/356] Make own wrapper for walk preferences in router-config --- docs/RouteRequest.md | 95 ++++++++++--------- docs/RouterConfiguration.md | 12 ++- docs/examples/entur/router-config.json | 10 +- docs/examples/ibi/portland/router-config.json | 6 +- .../examples/skanetrafiken/router-config.json | 4 +- .../routerequest/RouteRequestConfig.java | 23 ++--- .../standalone/config/router-config.json | 12 ++- .../performance/norway/speed-test-config.json | 10 +- .../skanetrafiken/speed-test-config.json | 6 +- .../switzerland/speed-test-config.json | 10 +- 10 files changed, 104 insertions(+), 84 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 755f5f73e28..f6b461c5212 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -23,7 +23,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 | | elevatorHopCost | `integer` | What is the cost of travelling one floor on an elevator? | *Optional* | `20` | 2.0 | | elevatorHopTime | `integer` | How long does it take to advance one floor on an elevator? | *Optional* | `20` | 2.0 | -| escalatorReluctance | `double` | A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time | *Optional* | `1.5` | 2.4 | | geoidElevation | `boolean` | If true, the Graph's ellipsoidToGeoidDifference is applied to all elevations returned by this query. | *Optional* | `false` | 2.0 | | ignoreRealtimeUpdates | `boolean` | When true, real-time updates are ignored during this search. | *Optional* | `false` | 2.0 | | [intersectionTraversalModel](#rd_intersectionTraversalModel) | `enum` | The model that computes the costs of turns. | *Optional* | `"simple"` | 2.2 | @@ -37,18 +36,12 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [relaxTransitPriorityGroup](#rd_relaxTransitPriorityGroup) | `string` | The relax function for transit-priority-groups | *Optional* | `"0s + 1.00 t"` | 2.5 | | [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | | [searchWindow](#rd_searchWindow) | `duration` | The duration of the search-window. | *Optional* | | 2.0 | -| stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | -| [stairsTimeFactor](#rd_stairsTimeFactor) | `double` | How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. | *Optional* | `3.0` | 2.1 | | [streetRoutingTimeout](#rd_streetRoutingTimeout) | `duration` | The maximum time a street routing request is allowed to take before returning the results. | *Optional* | `"PT5S"` | 2.2 | | [transferPenalty](#rd_transferPenalty) | `integer` | An additional penalty added to boardings after the first. | *Optional* | `0` | 2.0 | | [transferSlack](#rd_transferSlack) | `integer` | The extra time needed to make a safe transfer in seconds. | *Optional* | `120` | 2.0 | | turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 | | [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 | | waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 | -| walkBoardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | -| [walkReluctance](#rd_walkReluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -| [walkSafetyFactor](#rd_walkSafetyFactor) | `double` | Factor for how much the walk safety is considered in routing. | *Optional* | `1.0` | 2.2 | -| walkSpeed | `double` | The user's walking speed in meters/second. | *Optional* | `1.33` | 2.0 | | accessEgress | `object` | Parameters for access and egress routing. | *Optional* | | 2.4 | |    [maxDuration](#rd_accessEgress_maxDuration) | `duration` | This is the maximum duration for access/egress for street searches. | *Optional* | `"PT45M"` | 2.1 | |    [maxStopCount](#rd_accessEgress_maxStopCount) | `integer` | Maximal number of stops collected in access/egress routing | *Optional* | `500` | 2.4 | @@ -134,6 +127,14 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | |    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | |    [routes](#rd_unpreferred_routes) | `feed-scoped-id[]` | The ids of the routes that incur an extra cost when being used. Format: `FeedId:RouteId` | *Optional* | | 2.2 | +| walk | `object` | Walking preferences. | *Optional* | | 2.5 | +|    boardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | +|    escalatorReluctance | `double` | A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time | *Optional* | `1.5` | 2.4 | +|    [reluctance](#rd_walk_reluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    [safetyFactor](#rd_walk_safetyFactor) | `double` | Factor for how much the walk safety is considered in routing. | *Optional* | `1.0` | 2.2 | +|    speed | `double` | The user's walking speed in meters/second. | *Optional* | `1.33` | 2.0 | +|    stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | +|    [stairsTimeFactor](#rd_walk_stairsTimeFactor) | `double` | How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. | *Optional* | `3.0` | 2.1 | | wheelchairAccessibility | `object` | See [Wheelchair Accessibility](Accessibility.md) | *Optional* | | 2.2 | |    enabled | `boolean` | Enable wheelchair accessibility. | *Optional* | `false` | 2.0 | |    inaccessibleStreetReluctance | `double` | The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. | *Optional* | `25.0` | 2.2 | @@ -297,17 +298,6 @@ There is no need to set this when going to the next/previous page. The OTP Serve increase/decrease the search-window when paging to match the requested number of itineraries. -

    stairsTimeFactor

    - -**Since version:** `2.1` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `3.0` -**Path:** /routingDefaults - -How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. - -Default value is based on: Fujiyama, T., & Tyler, N. (2010). Predicting the walking -speed of pedestrians on stairs. Transportation Planning and Technology, 33(2), 177–202. - -

    streetRoutingTimeout

    **Since version:** `2.2` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT5S"` @@ -358,29 +348,6 @@ Function should return number of seconds that we are willing to wait for preferr or for an unpreferred agency's departure. For example: `5m + 2.0 t` -

    walkReluctance

    - -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `2.0` -**Path:** /routingDefaults - -A multiplier for how bad walking is, compared to being in transit for equal lengths of time. - -Empirically, values between 2 and 4 seem to correspond well to the concept of not wanting to walk -too much without asking for totally ridiculous itineraries, but this observation should in no way -be taken as scientific or definitive. Your mileage may vary. -See https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on performance with -high values. - - -

    walkSafetyFactor

    - -**Since version:** `2.2` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `1.0` -**Path:** /routingDefaults - -Factor for how much the walk safety is considered in routing. - -Value should be between 0 and 1. If the value is set to be 0, safety is ignored. -

    maxDuration

    **Since version:** `2.1` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT45M"` @@ -934,6 +901,40 @@ The ids of the routes that incur an extra cost when being used. Format: `FeedId: How much cost is added is configured in `unpreferredCost`. +

    reluctance

    + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `2.0` +**Path:** /routingDefaults/walk + +A multiplier for how bad walking is, compared to being in transit for equal lengths of time. + +Empirically, values between 2 and 4 seem to correspond well to the concept of not wanting to walk +too much without asking for totally ridiculous itineraries, but this observation should in no way +be taken as scientific or definitive. Your mileage may vary. +See https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on performance with +high values. + + +

    safetyFactor

    + +**Since version:** `2.2` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `1.0` +**Path:** /routingDefaults/walk + +Factor for how much the walk safety is considered in routing. + +Value should be between 0 and 1. If the value is set to be 0, safety is ignored. + +

    stairsTimeFactor

    + +**Since version:** `2.1` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `3.0` +**Path:** /routingDefaults/walk + +How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. + +Default value is based on: Fujiyama, T., & Tyler, N. (2010). Predicting the walking +speed of pedestrians on stairs. Transportation Planning and Technology, 33(2), 177–202. + +

    maxSlope

    **Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.083` @@ -980,17 +981,13 @@ include stairs as a last result. // router-config.json { "routingDefaults" : { - "walkSpeed" : 1.3, "numItineraries" : 12, "transferPenalty" : 0, - "walkReluctance" : 4.0, - "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, "elevatorBoardCost" : 90, "elevatorHopTime" : 20, "elevatorHopCost" : 20, - "escalatorReluctance" : 1.5, "bicycle" : { "speed" : 5, "reluctance" : 5.0, @@ -1021,8 +1018,14 @@ include stairs as a last result. "dropOffCost" : 30 } }, + "walk" : { + "speed" : 1.3, + "reluctance" : 4.0, + "stairsReluctance" : 1.65, + "boardCost" : 600, + "escalatorReluctance" : 1.5 + }, "waitReluctance" : 1.0, - "walkBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 37a673ea7a2..35020637894 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -451,17 +451,13 @@ Used to group requests when monitoring OTP. ] }, "routingDefaults" : { - "walkSpeed" : 1.3, "numItineraries" : 12, "transferPenalty" : 0, - "walkReluctance" : 4.0, - "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, "elevatorBoardCost" : 90, "elevatorHopTime" : 20, "elevatorHopCost" : 20, - "escalatorReluctance" : 1.5, "bicycle" : { "speed" : 5, "reluctance" : 5.0, @@ -492,8 +488,14 @@ Used to group requests when monitoring OTP. "dropOffCost" : 30 } }, + "walk" : { + "speed" : 1.3, + "reluctance" : 4.0, + "stairsReluctance" : 1.65, + "boardCost" : 600, + "escalatorReluctance" : 1.5 + }, "waitReluctance" : 1.0, - "walkBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index 2d217cb2402..cd4736263ce 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -1,11 +1,8 @@ { "configVersion" : "{{ Entur CI config build number inserted here }}", "routingDefaults": { - "walkSpeed": 1.3, "numItineraries": 12, "transferPenalty": 0, - "walkReluctance": 4.0, - "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, "elevatorBoardCost": 90, @@ -40,8 +37,13 @@ "dropOffCost": 30 } }, + "walk": { + "speed": 1.3, + "reluctance": 4.0, + "stairsReluctance": 1.65, + "boardCost": 600 + }, "waitReluctance": 1.0, - "walkBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) diff --git a/docs/examples/ibi/portland/router-config.json b/docs/examples/ibi/portland/router-config.json index 55a487fcfdc..445738762a1 100644 --- a/docs/examples/ibi/portland/router-config.json +++ b/docs/examples/ibi/portland/router-config.json @@ -5,8 +5,10 @@ "alightSlack": "0s", "transferSlack": 180, "waitReluctance": 0.9, - "walkReluctance": 1.75, - "stairsReluctance": 1.65, + "walk": { + "reluctance": 1.75, + "stairsReluctance": 1.65 + }, "numItineraries": 3, "geoidElevation": true, "streetRoutingTimeout": "7s" diff --git a/docs/examples/skanetrafiken/router-config.json b/docs/examples/skanetrafiken/router-config.json index ddec543e516..d65604aaa00 100644 --- a/docs/examples/skanetrafiken/router-config.json +++ b/docs/examples/skanetrafiken/router-config.json @@ -5,7 +5,9 @@ }, "transferSlack": 180, "waitReluctance": 0.175, - "walkReluctance": 5, + "walk": { + "reluctance": 5 + }, "maxDirectStreetDuration": "3700s" }, "transit": { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 0ff1c48cf2b..f15f6acdfe1 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -677,17 +677,18 @@ private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builde private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder walk) { var dft = walk.original(); + NodeAdapter cw = c.of("walk").since(V2_5).summary("Walking preferences.").asObject(); walk .withSpeed( - c - .of("walkSpeed") + cw + .of("speed") .since(V2_0) .summary("The user's walking speed in meters/second.") .asDouble(dft.speed()) ) .withReluctance( - c - .of("walkReluctance") + cw + .of("reluctance") .since(V2_0) .summary( "A multiplier for how bad walking is, compared to being in transit for equal lengths of time." @@ -704,8 +705,8 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.reluctance()) ) .withBoardCost( - c - .of("walkBoardCost") + cw + .of("boardCost") .since(V2_0) .summary( """ @@ -716,14 +717,14 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asInt(dft.boardCost()) ) .withStairsReluctance( - c + cw .of("stairsReluctance") .since(V2_0) .summary("Used instead of walkReluctance for stairs.") .asDouble(dft.stairsReluctance()) ) .withStairsTimeFactor( - c + cw .of("stairsTimeFactor") .since(V2_1) .summary( @@ -738,8 +739,8 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.stairsTimeFactor()) ) .withSafetyFactor( - c - .of("walkSafetyFactor") + cw + .of("safetyFactor") .since(V2_2) .summary("Factor for how much the walk safety is considered in routing.") .description( @@ -748,7 +749,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.safetyFactor()) ) .withEscalatorReluctance( - c + cw .of("escalatorReluctance") .since(V2_4) .summary( diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index d9c1e8e8c19..1d023c25688 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -12,17 +12,13 @@ ] }, "routingDefaults": { - "walkSpeed": 1.3, "numItineraries": 12, "transferPenalty": 0, - "walkReluctance": 4.0, - "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, "elevatorBoardCost": 90, "elevatorHopTime": 20, "elevatorHopCost": 20, - "escalatorReluctance": 1.5, "bicycle": { "speed": 5, "reluctance": 5.0, @@ -53,8 +49,14 @@ "dropOffCost": 30 } }, + "walk": { + "speed": 1.3, + "reluctance": 4.0, + "stairsReluctance": 1.65, + "boardCost": 600, + "escalatorReluctance": 1.5 + }, "waitReluctance": 1.0, - "walkBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) diff --git a/test/performance/norway/speed-test-config.json b/test/performance/norway/speed-test-config.json index cef9b1ef061..e4ca99d7fe5 100644 --- a/test/performance/norway/speed-test-config.json +++ b/test/performance/norway/speed-test-config.json @@ -39,15 +39,17 @@ } }, "routingDefaults": { - // Default is 1.4 m/s = ~ 5.0 km/t - "walkSpeed": 1.4, "bicycle": { // Should not be used - a high cost indicate an error "boardCost": 222000 }, - "walkBoardCost": 600, + "walk": { + // Default is 1.4 m/s = ~ 5.0 km/t + "speed": 1.4, + "boardCost": 600, + "reluctance": 4.0 + }, "transferPenalty": 0, - "walkReluctance": 4.0, "waitReluctance": 1.0, "boardSlack": "30s", "alightSlack": "15s", diff --git a/test/performance/skanetrafiken/speed-test-config.json b/test/performance/skanetrafiken/speed-test-config.json index a43cc97095d..66184ab124f 100644 --- a/test/performance/skanetrafiken/speed-test-config.json +++ b/test/performance/skanetrafiken/speed-test-config.json @@ -15,10 +15,12 @@ } }, "routingDefaults": { - "walkSpeed": 1.38, + "walk": { + "speed": 1.38, + "reluctance": 5 + }, "transferSlack": 180, "waitReluctance": 0.175, - "walkReluctance": 5, "maxDirectStreetDuration": "1h1m", "boardSlackForMode": { "RAIL": "12m" diff --git a/test/performance/switzerland/speed-test-config.json b/test/performance/switzerland/speed-test-config.json index 8b622825d09..19ac7a1358a 100644 --- a/test/performance/switzerland/speed-test-config.json +++ b/test/performance/switzerland/speed-test-config.json @@ -39,15 +39,17 @@ } }, "routingDefaults": { - // Default is 1.4 m/s = ~ 5.0 km/t - "walkSpeed": 1.4, "bicycle": { // Should not be used - a high cost indicate an error "boardCost": 222000 }, - "walkBoardCost": 600, + "walk": { + // Default is 1.4 m/s = ~ 5.0 km/t + "speed": 1.4, + "boardCost": 600, + "reluctance": 4.0 + }, "transferPenalty": 0, - "walkReluctance": 4.0, "waitReluctance": 1.0, "boardSlack": "30s", "alightSlack": "15s", From 845532a26090ad1954f9595b81bed3ba0b756de7 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 18:12:08 +0200 Subject: [PATCH 079/356] Rename walking -> walk --- docs/RouteRequest.md | 16 ++++++++-------- docs/RouterConfiguration.md | 2 +- docs/examples/entur/router-config.json | 2 +- .../routerequest/VehicleWalkingConfig.java | 2 +- .../standalone/config/router-config.json | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index f6b461c5212..6577789f361 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -74,9 +74,9 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | |    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | -|    walking | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | -|       [hopCost](#rd_bicycle_walking_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [hopTime](#rd_bicycle_walking_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | +|       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | |       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | |       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | |       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | @@ -495,10 +495,10 @@ The vehicle rental networks which may be used. If empty all networks may be used The vehicle rental networks which may not be used. If empty, no networks are banned. -

    hopCost

    +

    hopCost

    **Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` -**Path:** /routingDefaults/bicycle/walking +**Path:** /routingDefaults/bicycle/walk The cost of hopping on or off a vehicle. @@ -506,10 +506,10 @@ There are different parameters for the cost of renting or parking a vehicle and not meant for controlling the cost of those events. -

    hopTime

    +

    hopTime

    **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` -**Path:** /routingDefaults/bicycle/walking +**Path:** /routingDefaults/bicycle/walk The time it takes the user to hop on or off a vehicle in seconds. @@ -992,7 +992,7 @@ include stairs as a last result. "speed" : 5, "reluctance" : 5.0, "boardCost" : 600, - "walking" : { + "walk" : { "reluctance" : 10.0, "stairsReluctance" : 150.0 }, diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 35020637894..a1541288c75 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -462,7 +462,7 @@ Used to group requests when monitoring OTP. "speed" : 5, "reluctance" : 5.0, "boardCost" : 600, - "walking" : { + "walk" : { "reluctance" : 10.0, "stairsReluctance" : 150.0 }, diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index cd4736263ce..06ee5590eed 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -12,7 +12,7 @@ "speed": 5, "reluctance": 5.0, "boardCost": 600, - "walking": { + "walk": { "reluctance": 10.0 }, "rental": { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index e8ccbffe4df..ac6ac7d92f4 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -73,7 +73,7 @@ private static void mapVehicleWalkingPreferences( static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { var vehicleWalking = c - .of("walking") + .of("walk") .since(V2_5) .summary("Preferences for walking a vehicle.") .asObject(); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 1d023c25688..996505b5296 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -23,7 +23,7 @@ "speed": 5, "reluctance": 5.0, "boardCost": 600, - "walking": { + "walk": { "reluctance": 10.0, "stairsReluctance": 150.0 }, From ee99250f7184e790e145e711e0a7ed15f73cb806 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 29 Dec 2023 18:30:29 +0200 Subject: [PATCH 080/356] Rename/type rental preferences and remove unused carDropoffTime --- docs/RouteRequest.md | 18 ++-- docs/RouterConfiguration.md | 5 +- docs/examples/entur/router-config.json | 5 +- docs/examples/ibi/atlanta/router-config.json | 4 +- .../common/RequestToPreferencesMapper.java | 2 +- .../model/DefaultRouteRequestType.java | 10 +- .../request/preference/CarPreferences.java | 21 ---- .../preference/VehicleRentalPreferences.java | 100 ++++++++++-------- .../street/VehicleRentalEdge.java | 10 +- .../routerequest/RouteRequestConfig.java | 9 -- .../routerequest/VehicleRentalConfig.java | 22 ++-- .../model/edge/StreetTransitEntityLink.java | 2 +- .../street/model/edge/TemporaryFreeEdge.java | 2 +- .../preference/BikePreferencesTest.java | 4 - .../preference/CarPreferencesTest.java | 8 -- .../VehicleRentalPreferencesTest.java | 25 +++-- .../street/integration/BikeRentalTest.java | 2 +- .../standalone/config/router-config.json | 5 +- 18 files changed, 118 insertions(+), 136 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 6577789f361..aff3f3e5758 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -66,10 +66,10 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | |       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | |       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | |       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | @@ -84,7 +84,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | car | `object` | Car preferences. | *Optional* | | 2.5 | |    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | |    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -|    dropoffTime | `integer` | Time to park a car in a park and ride, w/o taking into account driving and walking cost. | *Optional* | `120` | 2.0 | |    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | |    pickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | @@ -93,10 +92,10 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | |       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | |       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | |       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | |       [allowedNetworks](#rd_car_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_car_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | @@ -998,7 +997,7 @@ include stairs as a last result. }, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 }, "parking" : { @@ -1009,12 +1008,11 @@ include stairs as a last result. "car" : { "speed" : 40, "reluctance" : 10, - "dropoffTime" : 120, "decelerationSpeed" : 2.9, "accelerationSpeed" : 2.9, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 } }, diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index a1541288c75..af2c0a9630a 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -468,7 +468,7 @@ Used to group requests when monitoring OTP. }, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 }, "parking" : { @@ -479,12 +479,11 @@ Used to group requests when monitoring OTP. "car" : { "speed" : 40, "reluctance" : 10, - "dropoffTime" : 120, "decelerationSpeed" : 2.9, "accelerationSpeed" : 2.9, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 } }, diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index 06ee5590eed..cd8a393a3c3 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -17,7 +17,7 @@ }, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 }, "parking": { @@ -28,12 +28,11 @@ "car": { "speed": 40, "reluctance": 4.0, - "dropoffTime": 120, "decelerationSpeed": 2.9, "accelerationSpeed": 2.9, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 } }, diff --git a/docs/examples/ibi/atlanta/router-config.json b/docs/examples/ibi/atlanta/router-config.json index 2aeb3e6434e..909c164ec43 100644 --- a/docs/examples/ibi/atlanta/router-config.json +++ b/docs/examples/ibi/atlanta/router-config.json @@ -7,13 +7,13 @@ "safety": 0.4 }, "rental": { - "pickupTime": 180, + "pickupTime": "3m", "pickupCost": 850 } }, "car": { "rental": { - "pickupTime": 180, + "pickupTime": "3m", "pickupCost": 850 } }, diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 68e61d6fe4e..5da43e9a179 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -147,7 +147,7 @@ private void mapRental(VehicleRentalPreferences.Builder rental) { setIfNotNull( req.keepingRentedBicycleAtDestinationCost, - rental::withArrivingInRentalVehicleAtDestinationCost + cost -> rental.withArrivingInRentalVehicleAtDestinationCost((int) Math.round(cost)) ); rental.withUseAvailabilityInformation(isPlannedForNow); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java index 5e4dca2bfc2..aadd73dcddb 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java @@ -184,7 +184,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalPickupTime") .description("Time to rent a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().pickupTime()) + .dataFetcher(env -> (int) preferences.bike().rental().pickupTime().toSeconds()) .build() ) .field( @@ -193,7 +193,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalPickupCost") .description("Cost to rent a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().pickupCost()) + .dataFetcher(env -> preferences.bike().rental().pickupCost().toSeconds()) .build() ) .field( @@ -202,7 +202,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalDropOffTime") .description("Time to drop-off a rented bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().dropoffTime()) + .dataFetcher(env -> (int) preferences.bike().rental().dropOffTime().toSeconds()) .build() ) .field( @@ -211,7 +211,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalDropOffCost") .description("Cost to drop-off a rented bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().dropoffCost()) + .dataFetcher(env -> preferences.bike().rental().dropOffCost().toSeconds()) .build() ) .field( @@ -240,7 +240,7 @@ private GraphQLObjectType createGraphQLType() { "Time to park a car in a park and ride, w/o taking into account driving and walking cost." ) .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.car().dropoffTime()) + .dataFetcher(env -> 0) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java index 6b103e8f3b7..9615a586335 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java @@ -27,7 +27,6 @@ public final class CarPreferences implements Serializable { private final VehicleRentalPreferences rental; private final int pickupTime; private final Cost pickupCost; - private final int dropoffTime; private final double accelerationSpeed; private final double decelerationSpeed; @@ -39,7 +38,6 @@ private CarPreferences() { this.rental = VehicleRentalPreferences.DEFAULT; this.pickupTime = 60; this.pickupCost = Cost.costOfMinutes(2); - this.dropoffTime = 120; this.accelerationSpeed = 2.9; this.decelerationSpeed = 2.9; } @@ -51,7 +49,6 @@ private CarPreferences(Builder builder) { this.rental = builder.rental; this.pickupTime = Units.duration(builder.pickupTime); this.pickupCost = builder.pickupCost; - this.dropoffTime = Units.duration(builder.dropoffTime); this.accelerationSpeed = Units.acceleration(builder.accelerationSpeed); this.decelerationSpeed = Units.acceleration(builder.decelerationSpeed); } @@ -97,14 +94,6 @@ public int pickupCost() { return pickupCost.toSeconds(); } - /** - * Time to park a car in a park and ride, w/o taking into account driving and walking cost (time - * to park, switch off, pick your stuff, lock the car, etc...) - */ - public int dropoffTime() { - return dropoffTime; - } - /** * The acceleration speed of an automobile, in meters per second per second. * Default is 2.9 m/s^2 (0 mph to 65 mph in 10 seconds) @@ -133,7 +122,6 @@ public boolean equals(Object o) { rental.equals(that.rental) && pickupTime == that.pickupTime && pickupCost.equals(that.pickupCost) && - dropoffTime == that.dropoffTime && DoubleUtils.doubleEquals(that.accelerationSpeed, accelerationSpeed) && DoubleUtils.doubleEquals(that.decelerationSpeed, decelerationSpeed) ); @@ -148,7 +136,6 @@ public int hashCode() { rental, pickupTime, pickupCost, - dropoffTime, accelerationSpeed, decelerationSpeed ); @@ -164,7 +151,6 @@ public String toString() { .addObj("rental", rental, DEFAULT.rental) .addNum("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) - .addNum("dropoffTime", dropoffTime, DEFAULT.dropoffTime) .addNum("accelerationSpeed", accelerationSpeed, DEFAULT.accelerationSpeed) .addNum("decelerationSpeed", decelerationSpeed, DEFAULT.decelerationSpeed) .toString(); @@ -180,7 +166,6 @@ public static class Builder { private VehicleRentalPreferences rental; private int pickupTime; private Cost pickupCost; - private int dropoffTime; private double accelerationSpeed; private double decelerationSpeed; @@ -192,7 +177,6 @@ public Builder(CarPreferences original) { this.rental = original.rental; this.pickupTime = original.pickupTime; this.pickupCost = original.pickupCost; - this.dropoffTime = original.dropoffTime; this.accelerationSpeed = original.accelerationSpeed; this.decelerationSpeed = original.decelerationSpeed; } @@ -231,11 +215,6 @@ public Builder withPickupCost(int pickupCost) { return this; } - public Builder withDropoffTime(int dropoffTime) { - this.dropoffTime = dropoffTime; - return this; - } - public Builder withAccelerationSpeed(double accelerationSpeed) { this.accelerationSpeed = accelerationSpeed; return this; diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java index 8e18d2a81d5..6c9bbfea875 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java @@ -1,10 +1,10 @@ package org.opentripplanner.routing.api.request.preference; import java.io.Serializable; +import java.time.Duration; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; -import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; import org.opentripplanner.framework.tostring.ToStringBuilder; @@ -17,38 +17,38 @@ public final class VehicleRentalPreferences implements Serializable { public static final VehicleRentalPreferences DEFAULT = new VehicleRentalPreferences(); - private final int pickupTime; + private final Duration pickupTime; private final Cost pickupCost; - private final int dropoffTime; - private final Cost dropoffCost; + private final Duration dropOffTime; + private final Cost dropOffCost; private final boolean useAvailabilityInformation; - private final double arrivingInRentalVehicleAtDestinationCost; + private final Cost arrivingInRentalVehicleAtDestinationCost; private final boolean allowArrivingInRentedVehicleAtDestination; private final Set allowedNetworks; private final Set bannedNetworks; private VehicleRentalPreferences() { - this.pickupTime = 60; + this.pickupTime = Duration.ofMinutes(1); this.pickupCost = Cost.costOfMinutes(2); - this.dropoffTime = 30; - this.dropoffCost = Cost.costOfSeconds(30); + this.dropOffTime = Duration.ofSeconds(30); + this.dropOffCost = Cost.costOfSeconds(30); this.useAvailabilityInformation = false; - this.arrivingInRentalVehicleAtDestinationCost = 0; + this.arrivingInRentalVehicleAtDestinationCost = Cost.costOfSeconds(0); this.allowArrivingInRentedVehicleAtDestination = false; this.allowedNetworks = Set.of(); this.bannedNetworks = Set.of(); } private VehicleRentalPreferences(Builder builder) { - this.pickupTime = builder.pickupTime; + this.pickupTime = Duration.ofSeconds(Units.duration(builder.pickupTime)); this.pickupCost = builder.pickupCost; - this.dropoffTime = builder.dropoffTime; - this.dropoffCost = builder.dropoffCost; + this.dropOffTime = Duration.ofSeconds(Units.duration(builder.dropOffTime)); + this.dropOffCost = builder.dropOffCost; this.useAvailabilityInformation = builder.useAvailabilityInformation; this.arrivingInRentalVehicleAtDestinationCost = - DoubleUtils.roundTo1Decimal(builder.arrivingInRentalVehicleAtDestinationCost); + builder.arrivingInRentalVehicleAtDestinationCost; this.allowArrivingInRentedVehicleAtDestination = builder.allowArrivingInRentedVehicleAtDestination; this.allowedNetworks = builder.allowedNetworks; @@ -64,7 +64,7 @@ public Builder copyOf() { } /** Time to rent a vehicle */ - public int pickupTime() { + public Duration pickupTime() { return pickupTime; } @@ -72,18 +72,18 @@ public int pickupTime() { * Cost of renting a vehicle. The cost is a bit more than actual time to model the associated cost * and trouble. */ - public int pickupCost() { - return pickupCost.toSeconds(); + public Cost pickupCost() { + return pickupCost; } /** Time to drop-off a rented vehicle */ - public int dropoffTime() { - return dropoffTime; + public Duration dropOffTime() { + return dropOffTime; } /** Cost of dropping-off a rented vehicle */ - public int dropoffCost() { - return dropoffCost.toSeconds(); + public Cost dropOffCost() { + return dropOffCost; } /** @@ -97,7 +97,7 @@ public boolean useAvailabilityInformation() { /** * The cost of arriving at the destination with the rented vehicle, to discourage doing so. */ - public double arrivingInRentalVehicleAtDestinationCost() { + public Cost arrivingInRentalVehicleAtDestinationCost() { return arrivingInRentalVehicleAtDestinationCost; } @@ -127,16 +127,15 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; VehicleRentalPreferences that = (VehicleRentalPreferences) o; return ( - pickupTime == that.pickupTime && + Objects.equals(pickupTime, that.pickupTime) && Objects.equals(pickupCost, that.pickupCost) && - dropoffTime == that.dropoffTime && - Objects.equals(dropoffCost, that.dropoffCost) && + Objects.equals(dropOffTime, that.dropOffTime) && + Objects.equals(dropOffCost, that.dropOffCost) && useAvailabilityInformation == that.useAvailabilityInformation && - Double.compare( + Objects.equals( that.arrivingInRentalVehicleAtDestinationCost, arrivingInRentalVehicleAtDestinationCost - ) == - 0 && + ) && allowArrivingInRentedVehicleAtDestination == that.allowArrivingInRentedVehicleAtDestination && allowedNetworks.equals(that.allowedNetworks) && bannedNetworks.equals(that.bannedNetworks) @@ -148,8 +147,8 @@ public int hashCode() { return Objects.hash( pickupTime, pickupCost, - dropoffTime, - dropoffCost, + dropOffTime, + dropOffCost, useAvailabilityInformation, arrivingInRentalVehicleAtDestinationCost, allowArrivingInRentedVehicleAtDestination, @@ -162,12 +161,12 @@ public int hashCode() { public String toString() { return ToStringBuilder .of(VehicleRentalPreferences.class) - .addDurationSec("pickupTime", pickupTime, DEFAULT.pickupTime) + .addDuration("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) - .addDurationSec("dropoffTime", dropoffTime, DEFAULT.dropoffTime) - .addObj("dropoffCost", dropoffCost, DEFAULT.dropoffCost) + .addDuration("dropOffTime", dropOffTime, DEFAULT.dropOffTime) + .addObj("dropOffCost", dropOffCost, DEFAULT.dropOffCost) .addBoolIfTrue("useAvailabilityInformation", useAvailabilityInformation) - .addNum( + .addObj( "arrivingInRentalVehicleAtDestinationCost", arrivingInRentalVehicleAtDestinationCost, DEFAULT.arrivingInRentalVehicleAtDestinationCost @@ -186,20 +185,20 @@ public static class Builder { private final VehicleRentalPreferences original; private int pickupTime; private Cost pickupCost; - private int dropoffTime; - private Cost dropoffCost; + private int dropOffTime; + private Cost dropOffCost; private boolean useAvailabilityInformation; - private double arrivingInRentalVehicleAtDestinationCost; + private Cost arrivingInRentalVehicleAtDestinationCost; private boolean allowArrivingInRentedVehicleAtDestination; private Set allowedNetworks; private Set bannedNetworks; private Builder(VehicleRentalPreferences original) { this.original = original; - this.pickupTime = Units.duration(original.pickupTime); + this.pickupTime = (int) original.pickupTime.toSeconds(); this.pickupCost = original.pickupCost; - this.dropoffTime = Units.duration(original.dropoffTime); - this.dropoffCost = original.dropoffCost; + this.dropOffTime = (int) original.dropOffTime.toSeconds(); + this.dropOffCost = original.dropOffCost; this.useAvailabilityInformation = original.useAvailabilityInformation; this.arrivingInRentalVehicleAtDestinationCost = original.arrivingInRentalVehicleAtDestinationCost; @@ -218,18 +217,28 @@ public Builder withPickupTime(int pickupTime) { return this; } + public Builder withPickupTime(Duration pickupTime) { + this.pickupTime = (int) pickupTime.toSeconds(); + return this; + } + public Builder withPickupCost(int pickupCost) { this.pickupCost = Cost.costOfSeconds(pickupCost); return this; } - public Builder withDropoffTime(int dropoffTime) { - this.dropoffTime = dropoffTime; + public Builder withDropOffTime(int dropOffTime) { + this.dropOffTime = dropOffTime; return this; } - public Builder withDropoffCost(int dropoffCost) { - this.dropoffCost = Cost.costOfSeconds(dropoffCost); + public Builder withDropOffTime(Duration dropOffTime) { + this.dropOffTime = (int) dropOffTime.toSeconds(); + return this; + } + + public Builder withDropOffCost(int dropOffCost) { + this.dropOffCost = Cost.costOfSeconds(dropOffCost); return this; } @@ -239,9 +248,10 @@ public Builder withUseAvailabilityInformation(boolean useAvailabilityInformation } public Builder withArrivingInRentalVehicleAtDestinationCost( - double arrivingInRentalVehicleAtDestinationCost + int arrivingInRentalVehicleAtDestinationCost ) { - this.arrivingInRentalVehicleAtDestinationCost = arrivingInRentalVehicleAtDestinationCost; + this.arrivingInRentalVehicleAtDestinationCost = + Cost.costOfSeconds(arrivingInRentalVehicleAtDestinationCost); return this; } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java b/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java index 66665f73b54..dc9fed8b9a3 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java +++ b/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java @@ -161,8 +161,14 @@ public State[] traverse(State s0) { } } - s1.incrementWeight(pickedUp ? preferences.pickupCost() : preferences.dropoffCost()); - s1.incrementTimeInSeconds(pickedUp ? preferences.pickupTime() : preferences.dropoffTime()); + s1.incrementWeight( + pickedUp ? preferences.pickupCost().toSeconds() : preferences.dropOffCost().toSeconds() + ); + s1.incrementTimeInSeconds( + pickedUp + ? (int) preferences.pickupTime().toSeconds() + : (int) preferences.dropOffTime().toSeconds() + ); s1.setBackMode(null); return s1.makeStateArray(); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index f15f6acdfe1..fab5262988b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -586,15 +586,6 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil ) .asDouble(dft.reluctance()) ) - .withDropoffTime( - cc - .of("dropoffTime") - .since(V2_0) - .summary( - "Time to park a car in a park and ride, w/o taking into account driving and walking cost." - ) - .asInt(dft.dropoffTime()) - ) .withPickupCost( cc .of("pickupCost") diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index 3d1534f5753..f862e9b9628 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -13,25 +13,33 @@ public class VehicleRentalConfig { static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder builder) { var dft = builder.original(); builder - .withDropoffCost( + .withDropOffCost( c .of("dropOffCost") .since(V2_0) .summary("Cost to drop-off a rented vehicle.") - .asInt(dft.dropoffCost()) + .asInt(dft.dropOffCost().toSeconds()) ) - .withDropoffTime( + .withDropOffTime( c .of("dropOffTime") .since(V2_0) .summary("Time to drop-off a rented vehicle.") - .asInt(dft.dropoffTime()) + .asDuration(dft.dropOffTime()) ) .withPickupCost( - c.of("pickupCost").since(V2_0).summary("Cost to rent a vehicle.").asInt(dft.pickupCost()) + c + .of("pickupCost") + .since(V2_0) + .summary("Cost to rent a vehicle.") + .asInt(dft.pickupCost().toSeconds()) ) .withPickupTime( - c.of("pickupTime").since(V2_0).summary("Time to rent a vehicle.").asInt(dft.pickupTime()) + c + .of("pickupTime") + .since(V2_0) + .summary("Time to rent a vehicle.") + .asDuration(dft.pickupTime()) ) .withUseAvailabilityInformation( c @@ -49,7 +57,7 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder .summary( "The cost of arriving at the destination with the rented vehicle, to discourage doing so." ) - .asDouble(dft.arrivingInRentalVehicleAtDestinationCost()) + .asInt(dft.arrivingInRentalVehicleAtDestinationCost().toSeconds()) ) .withAllowArrivingInRentedVehicleAtDestination( c diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index 926eebc31d9..df5b24a5928 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -143,7 +143,7 @@ private State[] buildState(State s0, StateEditor s1, RoutingPreferences pref) { s0.mayKeepRentedVehicleAtDestination() && rentalPreferences.allowArrivingInRentedVehicleAtDestination() ) { - s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost()); + s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds()); } s1.setBackMode(null); diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java index 011d0fec7f1..d825a8fcbea 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java @@ -48,7 +48,7 @@ public State[] traverse(State s0) { s0.mayKeepRentedVehicleAtDestination() && rentalPreferences.allowArrivingInRentedVehicleAtDestination() ) { - s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost()); + s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds()); } return s1.makeStateArray(); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 9bf287737df..4591d689f6c 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -91,10 +91,6 @@ void testToString() { "speed: 2.0, " + "reluctance: 1.2, " + "boardCost: $660, " + - "walkingSpeed: 1.15, " + - "walkingReluctance: 1.45, " + - "switchTime: 3m20s, " + - "switchCost: $450, " + "parking: VehicleParkingPreferences{parkCost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "optimizeType: TRIANGLE, " + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index c81cb41d883..a21dfadbed0 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -16,7 +16,6 @@ class CarPreferencesTest { private static final int PICKUP_COST = 500; private static final double ACCELERATION_SPEED = 3.1; private static final double DECELERATION_SPEED = 3.5; - public static final int DROPOFF_TIME = 450; public static final int RENTAL_PICKUP_TIME = 30; public static final int PARK_COST = 30; @@ -26,7 +25,6 @@ class CarPreferencesTest { .withReluctance(RELUCTANCE) .withPickupTime(PICKUP_TIME) .withPickupCost(PICKUP_COST) - .withDropoffTime(DROPOFF_TIME) .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) @@ -53,11 +51,6 @@ void pickupCost() { assertEquals(PICKUP_COST, subject.pickupCost()); } - @Test - void dropoffTime() { - assertEquals(DROPOFF_TIME, subject.dropoffTime()); - } - @Test void accelerationSpeed() { assertEquals(ACCELERATION_SPEED, subject.accelerationSpeed()); @@ -103,7 +96,6 @@ void testToString() { "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "pickupTime: 600, " + "pickupCost: $500, " + - "dropoffTime: 450, " + "accelerationSpeed: 3.1, decelerationSpeed: 3.5" + "}", subject.toString() diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java index 6092c8139bc..1b7068d0cd4 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java @@ -4,8 +4,10 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; +import java.time.Duration; import java.util.Set; import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; class VehicleRentalPreferencesTest { @@ -23,8 +25,8 @@ class VehicleRentalPreferencesTest { .of() .withPickupTime(PICKUP_TIME) .withPickupCost(PICKUP_COST) - .withDropoffTime(DROPOFF_TIME) - .withDropoffCost(DROPOFF_COST) + .withDropOffTime(DROPOFF_TIME) + .withDropOffCost(DROPOFF_COST) .withArrivingInRentalVehicleAtDestinationCost(ARRIVE_IN_RENTAL_COST) .withUseAvailabilityInformation(USE_AVAILABILITY_INFORMATION) .withAllowArrivingInRentedVehicleAtDestination(ALLOW_ARRIVING_IN_RENTED_VEHICLE) @@ -34,22 +36,22 @@ class VehicleRentalPreferencesTest { @Test void pickupTime() { - assertEquals(PICKUP_TIME, subject.pickupTime()); + assertEquals(Duration.ofSeconds(PICKUP_TIME), subject.pickupTime()); } @Test void pickupCost() { - assertEquals(PICKUP_COST, subject.pickupCost()); + assertEquals(Cost.costOfSeconds(PICKUP_COST), subject.pickupCost()); } @Test void dropoffTime() { - assertEquals(DROPOFF_TIME, subject.dropoffTime()); + assertEquals(Duration.ofSeconds(DROPOFF_TIME), subject.dropOffTime()); } @Test void dropoffCost() { - assertEquals(DROPOFF_COST, subject.dropoffCost()); + assertEquals(Cost.costOfSeconds(DROPOFF_COST), subject.dropOffCost()); } @Test @@ -59,7 +61,10 @@ void useAvailabilityInformation() { @Test void arrivingInRentalVehicleAtDestinationCost() { - assertEquals(ARRIVE_IN_RENTAL_COST, subject.arrivingInRentalVehicleAtDestinationCost()); + assertEquals( + Cost.costOfSeconds(ARRIVE_IN_RENTAL_COST), + subject.arrivingInRentalVehicleAtDestinationCost() + ); } @Test @@ -102,10 +107,10 @@ void testToString() { "VehicleRentalPreferences{" + "pickupTime: 25s, " + "pickupCost: $250, " + - "dropoffTime: 45s, " + - "dropoffCost: $450, " + + "dropOffTime: 45s, " + + "dropOffCost: $450, " + "useAvailabilityInformation, " + - "arrivingInRentalVehicleAtDestinationCost: 500.0, " + + "arrivingInRentalVehicleAtDestinationCost: $500, " + "allowArrivingInRentedVehicleAtDestination, " + "allowedNetworks: [foo], " + "bannedNetworks: [bar]" + diff --git a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java b/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java index 0694a991069..8dc1e240392 100644 --- a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java @@ -620,7 +620,7 @@ private List runStreetSearchAndCreateDescriptor( request.withPreferences(preferences -> preferences.withBike(bike -> bike.withRental(rental -> - rental.withPickupTime(42).withPickupCost(62).withDropoffCost(33).withDropoffTime(15) + rental.withPickupTime(42).withPickupCost(62).withDropOffCost(33).withDropOffTime(15) ) ) ); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 996505b5296..c3b99284dbd 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -29,7 +29,7 @@ }, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 }, "parking": { @@ -40,12 +40,11 @@ "car": { "speed": 40, "reluctance": 10, - "dropoffTime": 120, "decelerationSpeed": 2.9, "accelerationSpeed": 2.9, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 } }, From 3bbe2d05ed14071e02536f04ed05177e6b9d9614 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 2 Jan 2024 14:34:43 +0200 Subject: [PATCH 081/356] Retype pickupTime and expose cost as Cost --- docs/RouteRequest.md | 2 +- .../request/preference/CarPreferences.java | 23 ++++++++++--------- .../routerequest/RouteRequestConfig.java | 4 ++-- .../street/model/edge/CarPickupableEdge.java | 8 +++---- .../preference/CarPreferencesTest.java | 10 ++++---- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index aff3f3e5758..f682eedcaa7 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -85,7 +85,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | |    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | |    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | -|    pickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | +|    pickupTime | `duration` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `"PT1M"` | 2.1 | |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java index 9615a586335..b2f226cf307 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java @@ -3,6 +3,7 @@ import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; import java.io.Serializable; +import java.time.Duration; import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.lang.DoubleUtils; @@ -25,7 +26,7 @@ public final class CarPreferences implements Serializable { private final double reluctance; private final VehicleParkingPreferences parking; private final VehicleRentalPreferences rental; - private final int pickupTime; + private final Duration pickupTime; private final Cost pickupCost; private final double accelerationSpeed; private final double decelerationSpeed; @@ -36,7 +37,7 @@ private CarPreferences() { this.reluctance = 2.0; this.parking = VehicleParkingPreferences.DEFAULT; this.rental = VehicleRentalPreferences.DEFAULT; - this.pickupTime = 60; + this.pickupTime = Duration.ofMinutes(1); this.pickupCost = Cost.costOfMinutes(2); this.accelerationSpeed = 2.9; this.decelerationSpeed = 2.9; @@ -47,7 +48,7 @@ private CarPreferences(Builder builder) { this.reluctance = Units.reluctance(builder.reluctance); this.parking = builder.parking; this.rental = builder.rental; - this.pickupTime = Units.duration(builder.pickupTime); + this.pickupTime = Duration.ofSeconds(Units.duration(builder.pickupTime)); this.pickupCost = builder.pickupCost; this.accelerationSpeed = Units.acceleration(builder.accelerationSpeed); this.decelerationSpeed = Units.acceleration(builder.decelerationSpeed); @@ -85,13 +86,13 @@ public VehicleRentalPreferences rental() { } /** Time of getting in/out of a carPickup (taxi) */ - public int pickupTime() { + public Duration pickupTime() { return pickupTime; } /** Cost of getting in/out of a carPickup (taxi) */ - public int pickupCost() { - return pickupCost.toSeconds(); + public Cost pickupCost() { + return pickupCost; } /** @@ -120,7 +121,7 @@ public boolean equals(Object o) { DoubleUtils.doubleEquals(that.reluctance, reluctance) && parking.equals(that.parking) && rental.equals(that.rental) && - pickupTime == that.pickupTime && + Objects.equals(pickupTime, that.pickupTime) && pickupCost.equals(that.pickupCost) && DoubleUtils.doubleEquals(that.accelerationSpeed, accelerationSpeed) && DoubleUtils.doubleEquals(that.decelerationSpeed, decelerationSpeed) @@ -149,7 +150,7 @@ public String toString() { .addNum("reluctance", reluctance, DEFAULT.reluctance) .addObj("parking", parking, DEFAULT.parking) .addObj("rental", rental, DEFAULT.rental) - .addNum("pickupTime", pickupTime, DEFAULT.pickupTime) + .addObj("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) .addNum("accelerationSpeed", accelerationSpeed, DEFAULT.accelerationSpeed) .addNum("decelerationSpeed", decelerationSpeed, DEFAULT.decelerationSpeed) @@ -175,7 +176,7 @@ public Builder(CarPreferences original) { this.reluctance = original.reluctance; this.parking = original.parking; this.rental = original.rental; - this.pickupTime = original.pickupTime; + this.pickupTime = (int) original.pickupTime.toSeconds(); this.pickupCost = original.pickupCost; this.accelerationSpeed = original.accelerationSpeed; this.decelerationSpeed = original.decelerationSpeed; @@ -205,8 +206,8 @@ public Builder withRental(Consumer body) { return this; } - public Builder withPickupTime(int pickupTime) { - this.pickupTime = pickupTime; + public Builder withPickupTime(Duration pickupTime) { + this.pickupTime = (int) pickupTime.toSeconds(); return this; } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index fab5262988b..1e4f1e860c4 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -591,14 +591,14 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .of("pickupCost") .since(V2_1) .summary("Add a cost for car pickup changes when a pickup or drop off takes place") - .asInt(dft.pickupCost()) + .asInt(dft.pickupCost().toSeconds()) ) .withPickupTime( cc .of("pickupTime") .since(V2_1) .summary("Add a time for car pickup changes when a pickup or drop off takes place") - .asInt(dft.pickupTime()) + .asDuration(dft.pickupTime()) ) .withAccelerationSpeed( cc diff --git a/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java b/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java index ec50e3b60ca..7ea1678bbe7 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java @@ -30,13 +30,13 @@ default void dropOffAfterDriving(State state, StateEditor editor) { ? CarPickupState.WALK_TO_PICKUP : CarPickupState.WALK_FROM_DROP_OFF ); - editor.incrementTimeInSeconds(state.getPreferences().car().pickupTime()); - editor.incrementWeight(state.getPreferences().car().pickupCost()); + editor.incrementTimeInSeconds((int) state.getPreferences().car().pickupTime().toSeconds()); + editor.incrementWeight(state.getPreferences().car().pickupCost().toSeconds()); } default void driveAfterPickup(State state, StateEditor editor) { editor.setCarPickupState(CarPickupState.IN_CAR); - editor.incrementTimeInSeconds(state.getPreferences().car().pickupTime()); - editor.incrementWeight(state.getPreferences().car().pickupCost()); + editor.incrementTimeInSeconds((int) state.getPreferences().car().pickupTime().toSeconds()); + editor.incrementWeight(state.getPreferences().car().pickupCost().toSeconds()); } } diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index a21dfadbed0..3c0a294d7e2 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -4,7 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; +import java.time.Duration; import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; class CarPreferencesTest { @@ -23,7 +25,7 @@ class CarPreferencesTest { .of() .withSpeed(SPEED) .withReluctance(RELUCTANCE) - .withPickupTime(PICKUP_TIME) + .withPickupTime(Duration.ofSeconds(PICKUP_TIME)) .withPickupCost(PICKUP_COST) .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) @@ -43,12 +45,12 @@ void reluctance() { @Test void pickupTime() { - assertEquals(PICKUP_TIME, subject.pickupTime()); + assertEquals(Duration.ofSeconds(PICKUP_TIME), subject.pickupTime()); } @Test void pickupCost() { - assertEquals(PICKUP_COST, subject.pickupCost()); + assertEquals(Cost.costOfSeconds(PICKUP_COST), subject.pickupCost()); } @Test @@ -94,7 +96,7 @@ void testToString() { "reluctance: 5.1, " + "parking: VehicleParkingPreferences{parkCost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + - "pickupTime: 600, " + + "pickupTime: PT10M, " + "pickupCost: $500, " + "accelerationSpeed: 3.1, decelerationSpeed: 3.5" + "}", From 4009ade94fb5b4cf1fcea30f8c1f30a32bdef4c4 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 2 Jan 2024 15:10:15 +0200 Subject: [PATCH 082/356] Add car parking to doc --- docs/RouteRequest.md | 49 +++++++++++++++++++ docs/RouterConfiguration.md | 4 ++ .../standalone/config/router-config.json | 4 ++ 3 files changed, 57 insertions(+) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index f682eedcaa7..f16a4996ffe 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -89,6 +89,12 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       [unpreferredVehicleParkingTagCost](#rd_car_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | +|       [bannedVehicleParkingTags](#rd_car_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +|       [preferredVehicleParkingTags](#rd_car_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | +|       [requiredVehicleParkingTags](#rd_car_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | |    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | |       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | |       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | @@ -528,6 +534,45 @@ Sometimes there is a need to configure a board times for specific modes, such as ferries, where the check-in process needs to be done in good time before ride. +

    unpreferredVehicleParkingTagCost

    + +**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` +**Path:** /routingDefaults/car/parking + +What cost to add if a parking facility doesn't contain a preferred tag. + +See `preferredVehicleParkingTags`. + +

    bannedVehicleParkingTags

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/parking + +Tags with which a vehicle parking will not be used. If empty, no tags are banned. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

    preferredVehicleParkingTags

    + +**Since version:** `2.3` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/parking + +Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

    requiredVehicleParkingTags

    + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/parking + +Tags without which a vehicle parking will not be used. If empty, no tags are required. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + +

    allowedNetworks

    **Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` @@ -1014,6 +1059,10 @@ include stairs as a last result. "pickupCost" : 120, "dropOffTime" : "30s", "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "5m", + "parkCost" : 600 } }, "walk" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index af2c0a9630a..9c794b3086d 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -485,6 +485,10 @@ Used to group requests when monitoring OTP. "pickupCost" : 120, "dropOffTime" : "30s", "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "5m", + "parkCost" : 600 } }, "walk" : { diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index c3b99284dbd..8dfb1434ce4 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -46,6 +46,10 @@ "pickupCost": 120, "dropOffTime": "30s", "dropOffCost": 30 + }, + "parking": { + "parkTime": "5m", + "parkCost": 600 } }, "walk": { From 27d49214f488efdb9d37564ea8d9b85d71621247 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 2 Jan 2024 16:41:25 +0200 Subject: [PATCH 083/356] Expose triangle in docs --- docs/RouteRequest.md | 19 +++++++++++++++++++ docs/RouterConfiguration.md | 5 +++++ .../standalone/config/router-config.json | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index f16a4996ffe..4f52149aad1 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -74,6 +74,9 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | |    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | +|       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | +|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | |    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | |       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | |       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | @@ -500,6 +503,17 @@ The vehicle rental networks which may be used. If empty all networks may be used The vehicle rental networks which may not be used. If empty, no networks are banned. +

    safety

    + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.0` +**Path:** /routingDefaults/bicycle/triangle + +Relative importance of safety (range 0-1). + +This factor can also include other concerns such as convenience and general cyclist +preferences by taking into account road surface etc. + +

    hopCost

    **Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` @@ -1048,6 +1062,11 @@ include stairs as a last result. "parking" : { "parkTime" : "1m", "parkCost" : 120 + }, + "triangle" : { + "safety" : 0.4, + "flatness" : 0.3, + "time" : 0.3 } }, "car" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 9c794b3086d..f49a5bf9745 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -474,6 +474,11 @@ Used to group requests when monitoring OTP. "parking" : { "parkTime" : "1m", "parkCost" : 120 + }, + "triangle" : { + "safety" : 0.4, + "flatness" : 0.3, + "time" : 0.3 } }, "car" : { diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 8dfb1434ce4..9f6b336fde5 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -35,6 +35,11 @@ "parking": { "parkTime": "1m", "parkCost": 120 + }, + "triangle": { + "safety": 0.4, + "flatness": 0.3, + "time": 0.3 } }, "car": { From 831a4d8605a97d112111633ff848fd60679a6272 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 4 Jan 2024 11:22:11 +0200 Subject: [PATCH 084/356] Rename bicycle optimization types in the internal model and ease triangle configuration --- docs/RouteRequest.md | 19 +++++++++++---- .../common/RequestToPreferencesMapper.java | 9 ++++--- .../api/common/RoutingResource.java | 4 ++-- .../mapping/LegacyBicycleOptimizeType.java | 24 +++++++++++++++++++ .../gtfs/mapping/OptimizationTypeMapper.java | 19 +++++++++++++++ .../apis/gtfs/mapping/RouteRequestMapper.java | 7 +++++- .../apis/transmodel/model/EnumTypes.java | 8 +++---- .../request/preference/BikePreferences.java | 17 +++++++++++-- .../preference/TimeSlopeSafetyTriangle.java | 8 +++++++ .../routing/core/BicycleOptimizeType.java | 12 ++++++---- .../routerequest/RouteRequestConfig.java | 6 ++++- .../TriangleOptimizationConfig.java | 1 + .../street/model/edge/StreetEdge.java | 14 +++++------ .../visualizer/GraphVisualizer.java | 10 ++++---- .../gtfs/mapping/RouteRequestMapperTest.java | 17 ++++++------- .../mapping/TripRequestMapperTest.java | 2 +- .../preference/BikePreferencesTest.java | 23 ++++++++++++++++++ .../integration/BicycleRoutingTest.java | 4 +++- 18 files changed, 161 insertions(+), 43 deletions(-) create mode 100644 src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java create mode 100644 src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 4f52149aad1..b95c58ec32f 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -53,7 +53,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [alightSlackForMode](#rd_alightSlackForMode) | `enum map of duration` | How much extra time should be given when alighting a vehicle for each given mode. | *Optional* | | 2.0 | | bicycle | `object` | Bicycle preferences. | *Optional* | | 2.5 | |    [boardCost](#rd_bicycle_boardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. | *Optional* | `600` | 2.0 | -|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | +|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | |    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | @@ -73,7 +73,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | -|    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|    [triangle](#rd_bicycle_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | |       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | |       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | |       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | @@ -444,12 +444,14 @@ This is the cost that is used when boarding while cycling.This is usually higher

    optimization

    -**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe"` +**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe-streets"` **Path:** /routingDefaults/bicycle -**Enum values:** `quick` | `safe` | `flat` | `greenways` | `triangle` +**Enum values:** `shortest-duration` | `safe-streets` | `flat-streets` | `safest-streets` | `triangle` The set of characteristics that the user wants to optimize for. +If the triangle optimization is used, it's enough to just define the triangle parameters +

    unpreferredVehicleParkingTagCost

    **Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` @@ -503,6 +505,15 @@ The vehicle rental networks which may be used. If empty all networks may be used The vehicle rental networks which may not be used. If empty, no networks are banned. +

    triangle

    + +**Since version:** `2.5` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle + +Triangle optimization criteria. + +Optimization type doesn't need to be defined if these values are defined. +

    safety

    **Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.0` diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 5da43e9a179..e4878e6c7d9 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -2,6 +2,7 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; +import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; @@ -10,7 +11,6 @@ import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; class RequestToPreferencesMapper { @@ -67,9 +67,12 @@ private void mapBike() { setIfNotNull(req.bikeSpeed, bike::withSpeed); setIfNotNull(req.bikeReluctance, bike::withReluctance); setIfNotNull(req.bikeBoardCost, bike::withBoardCost); - setIfNotNull(req.bikeOptimizeType, bike::withOptimizeType); + setIfNotNull( + req.bikeOptimizeType, + optimizeType -> bike.withOptimizeType(LegacyBicycleOptimizeType.map(optimizeType)) + ); - if (req.bikeOptimizeType == BicycleOptimizeType.TRIANGLE) { + if (req.bikeOptimizeType == LegacyBicycleOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { setIfNotNull(req.triangleTimeFactor, triangle::withTime); setIfNotNull(req.triangleSlopeFactor, triangle::withSlope); diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/main/java/org/opentripplanner/api/common/RoutingResource.java index 8e7501c77fd..374e5515e3d 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/main/java/org/opentripplanner/api/common/RoutingResource.java @@ -18,6 +18,7 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; +import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; import org.opentripplanner.framework.application.OTPFeature; @@ -27,7 +28,6 @@ import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; -import org.opentripplanner.routing.core.BicycleOptimizeType; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.framework.file.ConfigFileLoader; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -248,7 +248,7 @@ public abstract class RoutingResource { */ @Deprecated @QueryParam("optimize") - protected BicycleOptimizeType bikeOptimizeType; + protected LegacyBicycleOptimizeType bikeOptimizeType; /** * The set of modes that a user is willing to use, with qualifiers stating whether vehicles should diff --git a/src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java b/src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java new file mode 100644 index 00000000000..1cc262ad720 --- /dev/null +++ b/src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java @@ -0,0 +1,24 @@ +package org.opentripplanner.api.mapping; + +import org.opentripplanner.routing.core.BicycleOptimizeType; + +/** + * Bicycle optimization types that are only meant to be used by the REST API. Related to {@link org.opentripplanner.routing.core.BicycleOptimizeType} + */ +public enum LegacyBicycleOptimizeType { + QUICK, + SAFE, + FLAT, + GREENWAYS, + TRIANGLE; + + public static BicycleOptimizeType map(LegacyBicycleOptimizeType type) { + return switch (type) { + case QUICK -> BicycleOptimizeType.SHORTEST_DURATION; + case FLAT -> BicycleOptimizeType.FLAT_STREETS; + case SAFE -> BicycleOptimizeType.SAFE_STREETS; + case GREENWAYS -> BicycleOptimizeType.SAFEST_STREETS; + case TRIANGLE -> BicycleOptimizeType.TRIANGLE; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java new file mode 100644 index 00000000000..1f53652f7b7 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java @@ -0,0 +1,19 @@ +package org.opentripplanner.apis.gtfs.mapping; + +import javax.annotation.Nonnull; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.routing.core.BicycleOptimizeType; + +public final class OptimizationTypeMapper { + + @Nonnull + public static BicycleOptimizeType map(GraphQLTypes.GraphQLOptimizeType optimizeType) { + return switch (optimizeType) { + case QUICK -> BicycleOptimizeType.SHORTEST_DURATION; + case FLAT -> BicycleOptimizeType.FLAT_STREETS; + case SAFE -> BicycleOptimizeType.SAFE_STREETS; + case GREENWAYS -> BicycleOptimizeType.SAFEST_STREETS; + case TRIANGLE -> BicycleOptimizeType.TRIANGLE; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index a12ef45f6fb..13593a99e58 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -16,6 +16,7 @@ import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.RouteRequest; @@ -71,7 +72,11 @@ public static RouteRequest toRouteRequest( callWith.argument("bikeBoardCost", bike::withBoardCost); if (environment.getArgument("optimize") != null) { - bike.withOptimizeType(BicycleOptimizeType.valueOf(environment.getArgument("optimize"))); + bike.withOptimizeType( + OptimizationTypeMapper.map( + GraphQLTypes.GraphQLOptimizeType.valueOf(environment.getArgument("optimize")) + ) + ); } if (bike.optimizeType() == BicycleOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java index 12aa19fbaea..e2897d868c9 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java @@ -64,10 +64,10 @@ public class EnumTypes { public static final GraphQLEnumType BICYCLE_OPTIMISATION_METHOD = GraphQLEnumType .newEnum() .name("BicycleOptimisationMethod") - .value("quick", BicycleOptimizeType.QUICK) - .value("safe", BicycleOptimizeType.SAFE) - .value("flat", BicycleOptimizeType.FLAT) - .value("greenways", BicycleOptimizeType.GREENWAYS) + .value("quick", BicycleOptimizeType.SHORTEST_DURATION) + .value("safe", BicycleOptimizeType.SAFE_STREETS) + .value("flat", BicycleOptimizeType.FLAT_STREETS) + .value("greenways", BicycleOptimizeType.SAFEST_STREETS) .value("triangle", BicycleOptimizeType.TRIANGLE) .build(); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index f282e02340c..2d887eba596 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -2,6 +2,8 @@ import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; +import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; +import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; import java.io.Serializable; import java.util.Objects; @@ -37,7 +39,7 @@ private BikePreferences() { this.boardCost = Cost.costOfMinutes(10); this.parking = VehicleParkingPreferences.DEFAULT; this.rental = VehicleRentalPreferences.DEFAULT; - this.optimizeType = BicycleOptimizeType.SAFE; + this.optimizeType = SAFE_STREETS; this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; this.walking = VehicleWalkingPreferences.DEFAULT; } @@ -92,7 +94,7 @@ public VehicleRentalPreferences rental() { } /** - * The set of characteristics that the user wants to optimize for -- defaults to SAFE. + * The set of characteristics that the user wants to optimize for -- defaults to SAFE_STREETS. */ public BicycleOptimizeType optimizeType() { return optimizeType; @@ -233,6 +235,17 @@ public TimeSlopeSafetyTriangle optimizeTriangle() { return optimizeTriangle; } + /** This also sets the optimization type as TRIANGLE if triangle parameters are defined */ + public Builder withForcedOptimizeTriangle(Consumer body) { + var builder = TimeSlopeSafetyTriangle.of(); + body.accept(builder); + this.optimizeTriangle = builder.buildOrDefault(this.optimizeTriangle); + if (!builder.isEmpty()) { + this.optimizeType = TRIANGLE; + } + return this; + } + public Builder withOptimizeTriangle(Consumer body) { var builder = TimeSlopeSafetyTriangle.of(); body.accept(builder); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java b/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java index b901d738213..99925a441fd 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java @@ -1,5 +1,6 @@ package org.opentripplanner.routing.api.request.preference; +import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; /** @@ -109,6 +110,13 @@ public Builder withSafety(double safety) { return this; } + /** + * Returns true if none of the values are set (i.e. all values are zero). + */ + public boolean isEmpty() { + return doubleEquals(time, ZERO) && doubleEquals(slope, ZERO) && doubleEquals(safety, ZERO); + } + public TimeSlopeSafetyTriangle build() { return new TimeSlopeSafetyTriangle(time, slope, safety); } diff --git a/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java b/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java index b5a47af82de..1d639e0af8b 100644 --- a/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java +++ b/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java @@ -9,10 +9,14 @@ * combined presets of routing parameters, except for triangle. */ public enum BicycleOptimizeType { - QUICK,/* the fastest trip */ - SAFE, - FLAT,/* needs a rewrite */ - GREENWAYS, + /** This was previously called QUICK */ + SHORTEST_DURATION, + /** This was previously called SAFE */ + SAFE_STREETS, + /** This was previously called FLAT. Needs a rewrite. */ + FLAT_STREETS, + /** This was previously called GREENWAYS. */ + SAFEST_STREETS, TRIANGLE; private static final Set NON_TRIANGLE_VALUES = Collections.unmodifiableSet( diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 1e4f1e860c4..8aaa0b1d243 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -372,9 +372,13 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .of("optimization") .since(V2_0) .summary("The set of characteristics that the user wants to optimize for.") + .description( + "If the triangle optimization is used, it's enough to just define the triangle parameters" + ) .asEnum(dft.optimizeType()) ) - .withOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) + // triangle overrides the optimization type if defined + .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) .withWalking(it -> mapVehicleWalking(cb, it)) .withParking(it -> mapParking(cb, it)) .withRental(it -> mapRental(cb, it)); diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java index e4988b02767..361e591891c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java @@ -47,6 +47,7 @@ static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Build .of("triangle") .since(V2_5) .summary("Triangle optimization criteria.") + .description("Optimization type doesn't need to be defined if these values are defined.") .asObject(); mapTriangleParameters(optimizationTriangle, preferences); } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index 3f17081b6cb..1e3594ee04b 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -51,7 +51,7 @@ public class StreetEdge private static final Logger LOG = LoggerFactory.getLogger(StreetEdge.class); - private static final double GREENWAY_SAFETY_FACTOR = 0.1; + private static final double SAFEST_STREETS_SAFETY_FACTOR = 0.1; /** If you have more than 16 flags, increase flags to short or int */ static final int BACK_FLAG_INDEX = 0; @@ -1217,17 +1217,17 @@ private TraversalCosts bicycleTraversalCost(RoutingPreferences pref, double spee double time = getEffectiveBikeDistance() / speed; double weight; switch (pref.bike().optimizeType()) { - case GREENWAYS -> { + case SAFEST_STREETS -> { weight = bicycleSafetyFactor * getDistanceMeters() / speed; - if (bicycleSafetyFactor <= GREENWAY_SAFETY_FACTOR) { - // greenways are treated as even safer than they really are + if (bicycleSafetyFactor <= SAFEST_STREETS_SAFETY_FACTOR) { + // safest streets are treated as even safer than they really are weight *= 0.66; } } - case SAFE -> weight = getEffectiveBicycleSafetyDistance() / speed; - case FLAT -> /* see notes in StreetVertex on speed overhead */weight = + case SAFE_STREETS -> weight = getEffectiveBicycleSafetyDistance() / speed; + case FLAT_STREETS -> /* see notes in StreetVertex on speed overhead */weight = getEffectiveBikeDistanceForWorkCost() / speed; - case QUICK -> weight = getEffectiveBikeDistance() / speed; + case SHORTEST_DURATION -> weight = getEffectiveBikeDistance() / speed; case TRIANGLE -> { double quick = getEffectiveBikeDistance(); double safety = getEffectiveBicycleSafetyDistance(); diff --git a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java index 73516b0348f..4154ee6362a 100644 --- a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java +++ b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java @@ -545,18 +545,18 @@ protected void route(String from, String to) { BicycleOptimizeType getSelectedOptimizeType() { if (opQuick.isSelected()) { - return BicycleOptimizeType.QUICK; + return BicycleOptimizeType.SHORTEST_DURATION; } if (opSafe.isSelected()) { - return BicycleOptimizeType.SAFE; + return BicycleOptimizeType.SAFE_STREETS; } if (opFlat.isSelected()) { - return BicycleOptimizeType.FLAT; + return BicycleOptimizeType.FLAT_STREETS; } if (opGreenways.isSelected()) { - return BicycleOptimizeType.GREENWAYS; + return BicycleOptimizeType.SAFEST_STREETS; } - return BicycleOptimizeType.QUICK; + return BicycleOptimizeType.SHORTEST_DURATION; } private Container makeDiffTab() { diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java index fba953cd93a..f52b81717d4 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java @@ -4,13 +4,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.params.provider.Arguments.of; -import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE; +import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; import graphql.ExecutionInput; import graphql.execution.ExecutionId; import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingEnvironmentImpl; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Map; @@ -21,12 +22,12 @@ import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.TestRoutingService; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.ext.fares.impl.DefaultFareService; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.GraphFinder; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; @@ -149,7 +150,7 @@ private static Map mode(String mode) { void defaultBikeOptimize() { Map arguments = Map.of(); var routeRequest = RouteRequestMapper.toRouteRequest(executionContext(arguments), context); - assertEquals(SAFE, routeRequest.preferences().bike().optimizeType()); + assertEquals(SAFE_STREETS, routeRequest.preferences().bike().optimizeType()); } @Test @@ -170,14 +171,14 @@ void bikeTriangle() { ); } - static Stream noTriangleCases = BicycleOptimizeType - .nonTriangleValues() - .stream() + static Stream noTriangleCases = Arrays + .stream(GraphQLTypes.GraphQLOptimizeType.values()) + .filter(value -> value != GraphQLTypes.GraphQLOptimizeType.TRIANGLE) .map(Arguments::of); @ParameterizedTest @VariableSource("noTriangleCases") - void noTriangle(BicycleOptimizeType bot) { + void noTriangle(GraphQLTypes.GraphQLOptimizeType bot) { Map arguments = Map.of( "optimize", bot.name(), @@ -187,7 +188,7 @@ void noTriangle(BicycleOptimizeType bot) { var routeRequest = RouteRequestMapper.toRouteRequest(executionContext(arguments), context); - assertEquals(bot, routeRequest.preferences().bike().optimizeType()); + assertEquals(OptimizationTypeMapper.map(bot), routeRequest.preferences().bike().optimizeType()); assertEquals( TimeSlopeSafetyTriangle.DEFAULT, routeRequest.preferences().bike().optimizeTriangle() diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java index 3058f622281..9a01a36cbcb 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java @@ -272,7 +272,7 @@ public void testBikeTriangleFactors() { @Test void testDefaultTriangleFactors() { var req2 = TripRequestMapper.createRequest(executionContext(Map.of())); - assertEquals(BicycleOptimizeType.SAFE, req2.preferences().bike().optimizeType()); + assertEquals(BicycleOptimizeType.SAFE_STREETS, req2.preferences().bike().optimizeType()); assertEquals(TimeSlopeSafetyTriangle.DEFAULT, req2.preferences().bike().optimizeTriangle()); } diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 4591d689f6c..a314aa48799 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -99,4 +99,27 @@ void testToString() { subject.toString() ); } + + @Test + void testForcedTriangleOptimization() { + var trianglePreferences = BikePreferences + .of() + .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + assertEquals(BicycleOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); + + var conflictingPreferences = BikePreferences + .of() + .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + assertEquals(BicycleOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); + + var emptyTrianglePreferences = BikePreferences + .of() + .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withForcedOptimizeTriangle(it -> it.build()) + .build(); + assertEquals(BicycleOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); + } } diff --git a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java b/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java index 300615269a1..d5b7733f3e8 100644 --- a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java @@ -75,7 +75,9 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic request.setDateTime(dateTime); request.setFrom(from); request.setTo(to); - request.withPreferences(p -> p.withBike(it -> it.withOptimizeType(BicycleOptimizeType.QUICK))); + request.withPreferences(p -> + p.withBike(it -> it.withOptimizeType(BicycleOptimizeType.SHORTEST_DURATION)) + ); request.journey().direct().setMode(StreetMode.BIKE); var temporaryVertices = new TemporaryVerticesContainer( From bed4effd5ea740572583055ea1385c37381e7765 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 12:31:29 +0100 Subject: [PATCH 085/356] Rename the feature flag DebugClient to DebugUi, remove separate one for the debug tiles --- docs/Configuration.md | 63 +++++++++---------- .../api/configuration/APIEndpoints.java | 6 +- .../framework/application/OTPFeature.java | 23 ++++--- .../standalone/server/GrizzlyServer.java | 2 +- 4 files changed, 50 insertions(+), 44 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index f1c0af287ab..7a81e68fb4a 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -219,38 +219,37 @@ Here is a list of all features which can be toggled on/off and their default val -| Feature | Description | Enabled by default | Sandbox | -|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------:|:-------:| -| `APIBikeRental` | Enable the bike rental endpoint. | ✓️ | | -| `APIServerInfo` | Enable the server info endpoint. | ✓️ | | -| `APIGraphInspectorTile` | Enable the inspector endpoint for graph information for inspection/debugging purpose. | ✓️ | | -| `APIUpdaterStatus` | Enable endpoint for graph updaters status. | ✓️ | | -| `ConsiderPatternsForDirectTransfers` | Enable limiting transfers so that there is only a single transfer to each pattern. | ✓️ | | -| `DebugClient` | Enable the debug web client located at the root of the web server. | ✓️ | | -| `FloatingBike` | Enable floating bike routing. | ✓️ | | -| `GtfsGraphQlApi` | Enable GTFS GraphQL API. | ✓️ | | -| `GtfsGraphQlApiRentalStationFuzzyMatching` | Does vehicleRentalStation query also allow ids that are not feed scoped. | | | -| `MinimumTransferTimeIsDefinitive` | If the minimum transfer time is a lower bound (default) or the definitive time for the transfer. Set this to `true` if you want to set a transfer time lower than what OTP derives from OSM data. | | | -| `OptimizeTransfers` | OTP will inspect all itineraries found and optimize where (which stops) the transfer will happen. Waiting time, priority and guaranteed transfers are taken into account. | ✓️ | | -| `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | -| `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | -| `TransmodelGraphQlApi` | Enable Transmodel (NeTEx) GraphQL API. | ✓️ | ✓️ | -| `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | -| `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | -| `Co2Emissions` | Enable the emissions sandbox module. | | ✓️ | -| `DataOverlay` | Enable usage of data overlay when calculating costs for the street network. | | ✓️ | -| `FaresV2` | Enable import of GTFS-Fares v2 data. | | ✓️ | -| `FlexRouting` | Enable FLEX routing. | | ✓️ | -| `GoogleCloudStorage` | Enable Google Cloud Storage integration. | | ✓️ | -| `RealtimeResolver` | When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data | | ✓️ | -| `ReportApi` | Enable the report API. | | ✓️ | -| `RestAPIPassInDefaultConfigAsJson` | Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! | | | -| `SandboxAPIGeocoder` | Enable the Geocoder API. | | ✓️ | -| `SandboxAPIMapboxVectorTilesApi` | Enable Mapbox vector tiles API. | | ✓️ | -| `SandboxAPIParkAndRideApi` | Enable park-and-ride endpoint. | | ✓️ | -| `SandboxAPITravelTime` | Enable the isochrone/travel time surface API. | | ✓️ | -| `TransferAnalyzer` | Analyze transfers during graph build. | | ✓️ | -| `VehicleToStopHeuristics` | Enable improved heuristic for park-and-ride queries. | | ✓️ | +| Feature | Description | Enabled by default | Sandbox | +|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------:|:-------:| +| `APIBikeRental` | Enable the bike rental endpoint. | ✓️ | | +| `APIServerInfo` | Enable the server info endpoint. | ✓️ | | +| `APIUpdaterStatus` | Enable endpoint for graph updaters status. | ✓️ | | +| `ConsiderPatternsForDirectTransfers` | Enable limiting transfers so that there is only a single transfer to each pattern. | ✓️ | | +| `DebugUi` | Enable the debug GraphQL client and web UI and located at the root of the web server as well as the debug map tiles it uses. Be aware that the map tiles are not a stable API and can change without notice. Use the [vector tiles feature if](sandbox/MapboxVectorTilesApi.md) you want a stable map tiles API. | ✓️ | | +| `FloatingBike` | Enable floating bike routing. | ✓️ | | +| `GtfsGraphQlApi` | Enable the [GTFS GraphQL API](apis/GTFS-GraphQL-API.md). | ✓️ | | +| `GtfsGraphQlApiRentalStationFuzzyMatching` | Does vehicleRentalStation query also allow ids that are not feed scoped. | | | +| `MinimumTransferTimeIsDefinitive` | If the minimum transfer time is a lower bound (default) or the definitive time for the transfer. Set this to `true` if you want to set a transfer time lower than what OTP derives from OSM data. | | | +| `OptimizeTransfers` | OTP will inspect all itineraries found and optimize where (which stops) the transfer will happen. Waiting time, priority and guaranteed transfers are taken into account. | ✓️ | | +| `ParallelRouting` | Enable performing parts of the trip planning in parallel. | | | +| `TransferConstraints` | Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little. | ✓️ | | +| `TransmodelGraphQlApi` | Enable the [Transmodel (NeTEx) GraphQL API](apis/TransmodelApi.md). | ✓️ | ✓️ | +| `ActuatorAPI` | Endpoint for actuators (service health status). | | ✓️ | +| `AsyncGraphQLFetchers` | Whether the @async annotation in the GraphQL schema should lead to the fetch being executed asynchronously. This allows batch or alias queries to run in parallel at the cost of consuming extra threads. | | | +| `Co2Emissions` | Enable the emissions sandbox module. | | ✓️ | +| `DataOverlay` | Enable usage of data overlay when calculating costs for the street network. | | ✓️ | +| `FaresV2` | Enable import of GTFS-Fares v2 data. | | ✓️ | +| `FlexRouting` | Enable FLEX routing. | | ✓️ | +| `GoogleCloudStorage` | Enable Google Cloud Storage integration. | | ✓️ | +| `RealtimeResolver` | When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data | | ✓️ | +| `ReportApi` | Enable the report API. | | ✓️ | +| `RestAPIPassInDefaultConfigAsJson` | Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! | | | +| `SandboxAPIGeocoder` | Enable the Geocoder API. | | ✓️ | +| `SandboxAPIMapboxVectorTilesApi` | Enable Mapbox vector tiles API. | | ✓️ | +| `SandboxAPIParkAndRideApi` | Enable park-and-ride endpoint. | | ✓️ | +| `SandboxAPITravelTime` | Enable the isochrone/travel time surface API. | | ✓️ | +| `TransferAnalyzer` | Analyze transfers during graph build. | | ✓️ | +| `VehicleToStopHeuristics` | Enable improved heuristic for park-and-ride queries. | | ✓️ | diff --git a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java b/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java index 64bbb2896a2..79556302f04 100644 --- a/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/api/configuration/APIEndpoints.java @@ -1,10 +1,10 @@ package org.opentripplanner.api.configuration; import static org.opentripplanner.framework.application.OTPFeature.APIBikeRental; -import static org.opentripplanner.framework.application.OTPFeature.APIGraphInspectorTile; import static org.opentripplanner.framework.application.OTPFeature.APIServerInfo; import static org.opentripplanner.framework.application.OTPFeature.APIUpdaterStatus; import static org.opentripplanner.framework.application.OTPFeature.ActuatorAPI; +import static org.opentripplanner.framework.application.OTPFeature.DebugUi; import static org.opentripplanner.framework.application.OTPFeature.GtfsGraphQlApi; import static org.opentripplanner.framework.application.OTPFeature.ReportApi; import static org.opentripplanner.framework.application.OTPFeature.SandboxAPIGeocoder; @@ -51,10 +51,10 @@ private APIEndpoints() { // Add feature enabled APIs, these can be enabled by default, some is not. // See the OTPFeature enum for details. addIfEnabled(APIBikeRental, BikeRental.class); - addIfEnabled(APIGraphInspectorTile, GraphInspectorTileResource.class); - addIfEnabled(APIGraphInspectorTile, GraphInspectorVectorTileResource.class); addIfEnabled(APIServerInfo, ServerInfo.class); addIfEnabled(APIUpdaterStatus, UpdaterStatusResource.class); + addIfEnabled(DebugUi, GraphInspectorTileResource.class); + addIfEnabled(DebugUi, GraphInspectorVectorTileResource.class); addIfEnabled(GtfsGraphQlApi, GtfsGraphQLAPI.class); addIfEnabled(TransmodelGraphQlApi, TransmodelAPI.class); diff --git a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java index 05d1284a883..308710ef5a0 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java +++ b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java @@ -16,20 +16,23 @@ public enum OTPFeature { APIBikeRental(true, false, "Enable the bike rental endpoint."), APIServerInfo(true, false, "Enable the server info endpoint."), - APIGraphInspectorTile( - true, - false, - "Enable the inspector endpoint for graph information for inspection/debugging purpose." - ), APIUpdaterStatus(true, false, "Enable endpoint for graph updaters status."), ConsiderPatternsForDirectTransfers( true, false, "Enable limiting transfers so that there is only a single transfer to each pattern." ), - DebugClient(true, false, "Enable the debug web client located at the root of the web server."), + DebugUi( + true, + false, + """ + Enable the debug GraphQL client and web UI and located at the root of the web server as well as the debug map tiles it uses. + Be aware that the map tiles are not a stable API and can change without notice. + Use the [vector tiles feature if](sandbox/MapboxVectorTilesApi.md) you want a stable map tiles API. + """ + ), FloatingBike(true, false, "Enable floating bike routing."), - GtfsGraphQlApi(true, false, "Enable GTFS GraphQL API."), + GtfsGraphQlApi(true, false, "Enable the [GTFS GraphQL API](apis/GTFS-GraphQL-API.md)."), GtfsGraphQlApiRentalStationFuzzyMatching( false, false, @@ -63,7 +66,11 @@ public enum OTPFeature { false, "Enforce transfers to happen according to the _transfers.txt_ (GTFS) and Interchanges (NeTEx). Turning this _off_ will increase the routing performance a little." ), - TransmodelGraphQlApi(true, true, "Enable Transmodel (NeTEx) GraphQL API."), + TransmodelGraphQlApi( + true, + true, + "Enable the [Transmodel (NeTEx) GraphQL API](apis/TransmodelApi.md)." + ), /* Sandbox extension features - Must be turned OFF by default */ diff --git a/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java b/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java index c422e9c24f3..7dc7c87f735 100644 --- a/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java +++ b/src/main/java/org/opentripplanner/standalone/server/GrizzlyServer.java @@ -102,7 +102,7 @@ public void run() { httpServer.getServerConfiguration().addHttpHandler(dynamicHandler, "/otp/"); /* 2. A static content handler to serve the client JS apps etc. from the classpath. */ - if (OTPFeature.DebugClient.isOn()) { + if (OTPFeature.DebugUi.isOn()) { CLStaticHttpHandler staticHandler = new CLStaticHttpHandler( GrizzlyServer.class.getClassLoader(), "/client/" From 4b9889101a59b4cfce3704a7e6e23db8315f7b25 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 12:49:06 +0100 Subject: [PATCH 086/356] Update comment --- .../inspector/vector/stop/StopLayerBuilder.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java index 40784ab5b3b..70ce6a58735 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLayerBuilder.java @@ -8,11 +8,14 @@ import org.locationtech.jts.geom.Geometry; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; +import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; /** - * A vector tile layer containing all {@link RegularStop}s inside the vector tile bounds. + * A vector tile layer for {@link StopLocation}s inside the vector tile bounds. These can be further + * filtered to get only a subset of stop implementations like {@link RegularStop} + * or {@link AreaStop}. */ public class StopLayerBuilder extends LayerBuilder { From 2b65d5702838d92a71a84923fb81afd8eb765a5c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 13:14:20 +0100 Subject: [PATCH 087/356] Make mapStyle configurable --- client-next/.env | 3 ++- client-next/.env.development | 3 ++- client-next/src/components/MapView/MapView.tsx | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client-next/.env b/client-next/.env index 003970b4e1f..e8a9667bc23 100644 --- a/client-next/.env +++ b/client-next/.env @@ -1 +1,2 @@ -VITE_API_URL=/otp/routers/default/transmodel/index/graphql \ No newline at end of file +VITE_API_URL=/otp/routers/default/transmodel/index/graphql +VITE_DEBUG_STYLE_URL=/otp/routers/default/inspector/vectortile/style.json diff --git a/client-next/.env.development b/client-next/.env.development index e11b45c4411..b10ac31fdf9 100644 --- a/client-next/.env.development +++ b/client-next/.env.development @@ -1 +1,2 @@ -VITE_API_URL=http://localhost:8080/otp/routers/default/transmodel/index/graphql \ No newline at end of file +VITE_API_URL=http://localhost:8080/otp/routers/default/transmodel/index/graphql +VITE_DEBUG_STYLE_URL=http://localhost:8080/otp/routers/default/inspector/vectortile/style.json \ No newline at end of file diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 95c898c4a28..e401b1756e6 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -15,6 +15,8 @@ const initialViewState = { zoom: 4, }; +const styleUrl = import.meta.env.VITE_DEBUG_STYLE_URL; + type PopupData = { coordinates: LngLat; feature: MapboxGeoJSONFeature }; export function MapView({ @@ -40,7 +42,7 @@ export function MapView({ // @ts-ignore mapLib={import('maplibre-gl')} // @ts-ignore - mapStyle="http://localhost:8080/otp/routers/default/inspector/vectortile/style.json" + mapStyle={styleUrl} initialViewState={initialViewState} onDblClick={onMapDoubleClick} onContextMenu={(e) => { From 756a2890d67f805111250364d6822962fb0c7ae9 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 13:16:58 +0100 Subject: [PATCH 088/356] Use proper copyright symbol --- .../org/opentripplanner/apis/vectortiles/DebugStyleSpec.java | 2 +- .../resources/org/opentripplanner/apis/vectortiles/style.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 9a4fe9be123..ff933901cf8 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -17,7 +17,7 @@ public class DebugStyleSpec { "background", List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), 256, - "© OpenStreetMap Contributors" + "© OpenStreetMap Contributors" ); public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index 6f95471a667..f5bb18f6f6a 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -7,7 +7,7 @@ "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" ], "tileSize": 256, - "attribution" : "© OpenStreetMap Contributors", + "attribution" : "© OpenStreetMap Contributors", "type": "raster" }, "vectorSource": { From a3f55d5d69c87669b1779b7dee2aa6abe56a7b31 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 9 Jan 2024 14:59:20 +0200 Subject: [PATCH 089/356] Update src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java Co-authored-by: Leonard Ehrenfried --- .../api/request/preference/VehicleWalkingPreferences.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java index 0abf2926f42..aa3631e1c6b 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java @@ -33,7 +33,7 @@ private VehicleWalkingPreferences() { } /** - * Sets the vehicle walking preferences and does some input value validation and rounds + * Sets the vehicle walking preferences, does some input value validation and rounds * reluctances and speed to not have too many decimals. */ private VehicleWalkingPreferences(Builder builder) { From c7497c7680b5ced640819927b6ac9bf04105b735 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 9 Jan 2024 15:14:30 +0100 Subject: [PATCH 090/356] refactor: Rename MaxLimitFilter to MAxLimit (it is not a filter) --- .../ItineraryListFilterChainBuilder.java | 86 +++++++++++-------- .../{MaxLimitFilter.java => MaxLimit.java} | 4 +- .../framework/spi/ItineraryListFilter.java | 4 +- .../framework/filter/GroupByFilterTest.java | 2 +- ...LimitFilterTest.java => MaxLimitTest.java} | 10 +-- 5 files changed, 58 insertions(+), 48 deletions(-) rename src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/{MaxLimitFilter.java => MaxLimit.java} (87%) rename src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/{MaxLimitFilterTest.java => MaxLimitTest.java} (82%) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index c95005acd32..ec14286e6ca 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -37,7 +37,7 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.transit.group.RemoveOtherThanSameLegsMaxGeneralizedCost; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.DecorateFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimit; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.RemoveFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.SortingFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filterchain.DeleteResultHandler; @@ -373,12 +373,12 @@ public ItineraryListFilterChain build() { filters.addAll(buildGroupByTripIdAndDistanceFilters()); if (removeItinerariesWithSameRoutesAndStops) { - filters.addAll(buildGroupBySameRoutesAndStopsFilter()); + filters.add(buildGroupBySameRoutesAndStopsFilter()); } if (sameFirstOrLastTripFilter) { - filters.add(new SortingFilter(generalizedCostComparator())); - addRmFilter(filters, new RemoveIfFirstOrLastTripIsTheSame()); + addSort(filters, generalizedCostComparator()); + addRemoveFilter(filters, new RemoveIfFirstOrLastTripIsTheSame()); } if (minBikeParkingDistance > 0) { @@ -390,7 +390,7 @@ public ItineraryListFilterChain build() { // Filter transit itineraries on generalized-cost if (transitGeneralizedCostFilterParams != null) { - addRmFilter( + addRemoveFilter( filters, new TransitGeneralizedCostFilter( transitGeneralizedCostFilterParams.costLimitFunction(), @@ -401,7 +401,7 @@ public ItineraryListFilterChain build() { // Filter non-transit itineraries on generalized-cost if (nonTransitGeneralizedCostLimit != null) { - addRmFilter( + addRemoveFilter( filters, new RemoveNonTransitItinerariesBasedOnGeneralizedCost(nonTransitGeneralizedCostLimit) ); @@ -419,26 +419,26 @@ public ItineraryListFilterChain build() { { // Filter transit itineraries by comparing against non-transit using generalized-cost if (removeTransitWithHigherCostThanBestOnStreetOnly != null) { - addRmFilter( + addRemoveFilter( filters, new RemoveTransitIfStreetOnlyIsBetter(removeTransitWithHigherCostThanBestOnStreetOnly) ); } if (removeTransitIfWalkingIsBetter) { - addRmFilter(filters, new RemoveTransitIfWalkingIsBetter()); + addRemoveFilter(filters, new RemoveTransitIfWalkingIsBetter()); } if (removeWalkAllTheWayResults) { - addRmFilter(filters, new RemoveWalkOnlyFilter()); + addRemoveFilter(filters, new RemoveWalkOnlyFilter()); } if (bikeRentalDistanceRatio > 0) { - addRmFilter(filters, new RemoveBikeRentalWithMostlyWalking(bikeRentalDistanceRatio)); + addRemoveFilter(filters, new RemoveBikeRentalWithMostlyWalking(bikeRentalDistanceRatio)); } if (parkAndRideDurationRatio > 0) { - addRmFilter( + addRemoveFilter( filters, new RemoveParkAndRideWithMostlyWalkingFilter(parkAndRideDurationRatio) ); @@ -452,18 +452,24 @@ public ItineraryListFilterChain build() { { // Limit to search-window if (earliestDepartureTime != null) { - addRmFilter(filters, new OutsideSearchWindowFilter(earliestDepartureTime, searchWindow)); + addRemoveFilter( + filters, + new OutsideSearchWindowFilter(earliestDepartureTime, searchWindow) + ); } // Remove itineraries present in the page retrieved before this page/search. if (itineraryPageCut != null) { - addRmFilter(filters, new PagingFilter(sortOrder, deduplicateSection(), itineraryPageCut)); + addRemoveFilter( + filters, + new PagingFilter(sortOrder, deduplicateSection(), itineraryPageCut) + ); } // Remove itineraries if max limit is set if (maxNumberOfItineraries > 0) { - filters.add(new SortingFilter(SortOrderComparator.comparator(sortOrder))); - addRmFilter( + addSort(filters, SortOrderComparator.comparator(sortOrder)); + addRemoveFilter( filters, new NumItinerariesFilter( maxNumberOfItineraries, @@ -475,27 +481,30 @@ public ItineraryListFilterChain build() { } // Do the final itineraries sort - filters.add(new SortingFilter(SortOrderComparator.comparator(sortOrder))); + addSort(filters, SortOrderComparator.comparator(sortOrder)); // Decorate itineraries { if (transitAlertService != null) { - addDecorator(filters, new DecorateTransitAlert(transitAlertService, getMultiModalStation)); + addDecorateFilter( + filters, + new DecorateTransitAlert(transitAlertService, getMultiModalStation) + ); } // Sandbox filters to decorate itineraries if (accessibilityScore) { // TODO: This should be injected to avoid circular dependencies (dep. on sandbox here) - addDecorator(filters, new DecorateWithAccessibilityScore(wheelchairMaxSlope)); + addDecorateFilter(filters, new DecorateWithAccessibilityScore(wheelchairMaxSlope)); } if (emissionDecorator != null) { - addDecorator(filters, emissionDecorator); + addDecorateFilter(filters, emissionDecorator); } if (fareDecorator != null) { - addDecorator(filters, fareDecorator); + addDecorateFilter(filters, fareDecorator); } if (rideHailingDecorator != null) { @@ -503,7 +512,7 @@ public ItineraryListFilterChain build() { } if (stopConsolidationDecorator != null) { - addDecorator(filters, stopConsolidationDecorator); + addDecorateFilter(filters, stopConsolidationDecorator); } } @@ -517,22 +526,20 @@ public ItineraryListFilterChain build() { * These are sometimes called "time-shifted duplicates" but since those terms have so many * meanings we chose to use a long, but descriptive name instead. */ - private List buildGroupBySameRoutesAndStopsFilter() { - return List.of( - new GroupByFilter<>( - GroupBySameRoutesAndStops::new, - List.of( - new SortingFilter(SortOrderComparator.comparator(sortOrder)), - new RemoveFilter(new MaxLimitFilter(GroupBySameRoutesAndStops.TAG, 1)) - ) + private ItineraryListFilter buildGroupBySameRoutesAndStopsFilter() { + return new GroupByFilter<>( + GroupBySameRoutesAndStops::new, + List.of( + new SortingFilter(SortOrderComparator.comparator(sortOrder)), + new RemoveFilter(new MaxLimit(GroupBySameRoutesAndStops.TAG, 1)) ) ); } /** * These filters will group the itineraries by the main-legs and reduce the number of itineraries - * in each group. The main legs is the legs that together constitute more than a given percentage - * of the total travel distance. + * in each group. The main legs are the legs that together constitute more than a given + * percentage of the total travel distance. *

    * Each group is filtered using generalized-cost, keeping only the itineraries with the lowest * cost. If there is a tie, the filter look at the number-of-transfers as a tiebreaker. @@ -567,7 +574,7 @@ private List buildGroupByTripIdAndDistanceFilters() { GroupByAllSameStations::new, List.of( new SortingFilter(generalizedCostComparator()), - new RemoveFilter(new MaxLimitFilter(innerGroupName, 1)) + new RemoveFilter(new MaxLimit(innerGroupName, 1)) ) ) ); @@ -576,12 +583,11 @@ private List buildGroupByTripIdAndDistanceFilters() { if (group.maxCostOtherLegsFactor > 1.0) { var flagger = new RemoveOtherThanSameLegsMaxGeneralizedCost(group.maxCostOtherLegsFactor); sysTags.add(flagger.name()); - addRmFilter(nested, flagger); + addRemoveFilter(nested, flagger); } - nested.add(new SortingFilter(generalizedCostComparator())); - - addRmFilter(nested, new MaxLimitFilter(tag, group.maxNumOfItinerariesPerGroup)); + addSort(nested, generalizedCostComparator()); + addRemoveFilter(nested, new MaxLimit(tag, group.maxNumOfItinerariesPerGroup)); nested.add(new KeepItinerariesWithFewestTransfers(sysTags)); @@ -597,14 +603,18 @@ private ListSection deduplicateSection() { return maxNumberOfItinerariesCropSection.invert(); } - private static void addRmFilter( + private static void addSort(List filters, SortOrderComparator comparator) { + filters.add(new SortingFilter(comparator)); + } + + private static void addRemoveFilter( List filters, RemoveItineraryFlagger removeFilter ) { filters.add(new RemoveFilter(removeFilter)); } - private static void addDecorator( + private static void addDecorateFilter( List filters, ItineraryDecorator decorator ) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java similarity index 87% rename from src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilter.java rename to src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java index 4c786455dba..5ab1e88f730 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimit.java @@ -8,12 +8,12 @@ * Flags the itineraries at the end of the list for removal. The list should be sorted on the * desired key before this filter is applied. */ -public class MaxLimitFilter implements RemoveItineraryFlagger { +public class MaxLimit implements RemoveItineraryFlagger { private final String name; private final int maxLimit; - public MaxLimitFilter(String name, int maxLimit) { + public MaxLimit(String name, int maxLimit) { this.name = name; this.maxLimit = maxLimit; } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java index c56b4fe42c9..b0a67ab147f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java @@ -2,7 +2,7 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimitFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimit; /** * Filter, sort or decorate itineraries. A filter can modify the elements in the list, but not the @@ -14,7 +14,7 @@ * chain. *

    * This allows decoration of each filter and makes it easier to reuse logic. Like the {@link - * MaxLimitFilter} is reused in + * MaxLimit} is reused in * several places. */ public interface ItineraryListFilter { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java index 8bf29be62fa..adecedce669 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/GroupByFilterTest.java @@ -97,7 +97,7 @@ private GroupByFilter createFilter(int maxNumberOfItinerariesPrGroup) i -> new AGroupId(i.firstLeg().getTrip().getId().getId()), List.of( new SortingFilter(SortOrderComparator.defaultComparatorDepartAfter()), - new RemoveFilter(new MaxLimitFilter(TEST_FILTER_TAG, maxNumberOfItinerariesPrGroup)) + new RemoveFilter(new MaxLimit(TEST_FILTER_TAG, maxNumberOfItinerariesPrGroup)) ) ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java similarity index 82% rename from src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilterTest.java rename to src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java index 2fa10761c36..25d9188524d 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/MaxLimitTest.java @@ -9,7 +9,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -public class MaxLimitFilterTest implements PlanTestConstants { +public class MaxLimitTest implements PlanTestConstants { private static final Itinerary i1 = newItinerary(A, 6).walk(1, B).build(); private static final Itinerary i2 = newItinerary(A).bicycle(6, 8, B).build(); @@ -17,27 +17,27 @@ public class MaxLimitFilterTest implements PlanTestConstants { @Test public void name() { - MaxLimitFilter subject = new MaxLimitFilter("Test", 3); + MaxLimit subject = new MaxLimit("Test", 3); assertEquals("Test", subject.name()); } @Test public void testNormalFilterMaxLimit3() { - MaxLimitFilter subject = new MaxLimitFilter("Test", 3); + MaxLimit subject = new MaxLimit("Test", 3); List itineraries = List.of(i1, i2, i3); assertEquals(toStr(itineraries), toStr(subject.removeMatchesForTest(itineraries))); } @Test public void testNormalFilterMaxLimit1() { - MaxLimitFilter subject = new MaxLimitFilter("Test", 1); + MaxLimit subject = new MaxLimit("Test", 1); List itineraries = List.of(i1, i2, i3); assertEquals(toStr(List.of(i1)), toStr(subject.removeMatchesForTest(itineraries))); } @Test public void testNormalFilterMaxLimit0() { - MaxLimitFilter subject = new MaxLimitFilter("Test", 0); + MaxLimit subject = new MaxLimit("Test", 0); List itineraries = List.of(i1, i2, i3); var result = subject.removeMatchesForTest(itineraries); assertEquals(toStr(List.of()), toStr(result)); From 69bd96562f8f63a4aaec237292898709b15a62e1 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 14:07:13 +0100 Subject: [PATCH 091/356] Add API mapper test for walk reluctance --- .../apis/gtfs/mapping/RouteRequestMapperTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java index f52b81717d4..b05dd77e2a9 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java @@ -2,6 +2,7 @@ import static graphql.execution.ExecutionContextBuilder.newExecutionContextBuilder; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.params.provider.Arguments.of; import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; @@ -195,6 +196,18 @@ void noTriangle(GraphQLTypes.GraphQLOptimizeType bot) { ); } + @Test + void walkReluctance() { + var reluctance = 119d; + Map arguments = Map.of("walkReluctance", reluctance); + + var routeRequest = RouteRequestMapper.toRouteRequest(executionContext(arguments), context); + assertEquals(reluctance, routeRequest.preferences().walk().reluctance()); + + var noParamsRequest = RouteRequestMapper.toRouteRequest(executionContext(Map.of()), context); + assertNotEquals(reluctance, noParamsRequest.preferences().walk().reluctance()); + } + private DataFetchingEnvironment executionContext(Map arguments) { ExecutionInput executionInput = ExecutionInput .newExecutionInput() From 9b075d2965c6c719f63900a95cc85a85f8a32e83 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 9 Jan 2024 17:48:42 +0200 Subject: [PATCH 092/356] Rename park cost/time --- docs/RouteRequest.md | 16 +++--- docs/RouterConfiguration.md | 8 +-- docs/examples/entur/router-config.json | 4 +- .../common/RequestToPreferencesMapper.java | 8 +-- .../model/DefaultRouteRequestType.java | 4 +- .../preference/VehicleParkingPreferences.java | 50 +++++++++---------- .../routerequest/VehicleParkingConfig.java | 12 ++--- .../street/model/edge/VehicleParkingEdge.java | 22 +++----- .../preference/BikePreferencesTest.java | 6 +-- .../preference/CarPreferencesTest.java | 6 +-- .../VehicleParkingPreferencesTest.java | 20 ++++---- .../street/integration/ParkAndRideTest.java | 8 +-- .../edge/StreetVehicleParkingLinkTest.java | 2 +- .../edge/VehicleParkingPreferredTagsTest.java | 2 +- .../standalone/config/router-config.json | 8 +-- 15 files changed, 83 insertions(+), 93 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index b95c58ec32f..06c7b55c521 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -57,8 +57,8 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | -|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | -|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       [unpreferredVehicleParkingTagCost](#rd_bicycle_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | |       [bannedVehicleParkingTags](#rd_bicycle_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | |       [preferredVehicleParkingTags](#rd_bicycle_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | @@ -92,8 +92,8 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | -|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | -|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       [unpreferredVehicleParkingTagCost](#rd_car_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | |       [bannedVehicleParkingTags](#rd_car_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | |       [preferredVehicleParkingTags](#rd_car_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | @@ -1071,8 +1071,8 @@ include stairs as a last result. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "1m", - "parkCost" : 120 + "time" : "1m", + "cost" : 120 }, "triangle" : { "safety" : 0.4, @@ -1091,8 +1091,8 @@ include stairs as a last result. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "5m", - "parkCost" : 600 + "time" : "5m", + "cost" : 600 } }, "walk" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index f49a5bf9745..df08b852fd5 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -472,8 +472,8 @@ Used to group requests when monitoring OTP. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "1m", - "parkCost" : 120 + "time" : "1m", + "cost" : 120 }, "triangle" : { "safety" : 0.4, @@ -492,8 +492,8 @@ Used to group requests when monitoring OTP. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "5m", - "parkCost" : 600 + "time" : "5m", + "cost" : 600 } }, "walk" : { diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index cd8a393a3c3..ffdec9ded79 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -21,8 +21,8 @@ "dropOffCost": 30 }, "parking": { - "parkTime": "1m", - "parkCost": 120 + "time": "1m", + "cost": 120 } }, "car": { diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index e4878e6c7d9..2a97cd63a75 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -46,8 +46,8 @@ private void mapCar() { setIfNotNull(req.carReluctance, car::withReluctance); car.withParking(parking -> { mapParking(parking); - setIfNotNull(req.carParkCost, parking::withParkCost); - setIfNotNull(req.carParkTime, parking::withParkTime); + setIfNotNull(req.carParkCost, parking::withCost); + setIfNotNull(req.carParkTime, parking::withTime); }); car.withRental(this::mapRental); }); @@ -82,8 +82,8 @@ private void mapBike() { bike.withParking(parking -> { mapParking(parking); - setIfNotNull(req.bikeParkCost, parking::withParkCost); - setIfNotNull(req.bikeParkTime, parking::withParkTime); + setIfNotNull(req.bikeParkCost, parking::withCost); + setIfNotNull(req.bikeParkTime, parking::withTime); }); bike.withRental(this::mapRental); bike.withWalking(walk -> { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java index aadd73dcddb..80b6418c314 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java @@ -220,7 +220,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeParkTime") .description("Time to park a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> (int) preferences.bike().parking().parkTime().toSeconds()) + .dataFetcher(env -> (int) preferences.bike().parking().time().toSeconds()) .build() ) .field( @@ -229,7 +229,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeParkCost") .description("Cost to park a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().parking().parkCost().toSeconds()) + .dataFetcher(env -> preferences.bike().parking().cost().toSeconds()) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java index c02862c4d79..f7183812c3a 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java @@ -23,16 +23,16 @@ public final class VehicleParkingPreferences implements Serializable { private final Cost unpreferredVehicleParkingTagCost; private final VehicleParkingFilter filter; private final VehicleParkingFilter preferred; - private final Duration parkTime; - private final Cost parkCost; + private final Duration time; + private final Cost cost; /** Create a new instance with default values. */ private VehicleParkingPreferences() { this.unpreferredVehicleParkingTagCost = Cost.costOfMinutes(5); this.filter = VehicleParkingFilter.empty(); this.preferred = VehicleParkingFilter.empty(); - this.parkTime = Duration.ofMinutes(1); - this.parkCost = Cost.costOfMinutes(2); + this.time = Duration.ofMinutes(1); + this.cost = Cost.costOfMinutes(2); } private VehicleParkingPreferences(Builder builder) { @@ -47,8 +47,8 @@ private VehicleParkingPreferences(Builder builder) { builder.notPreferredVehicleParkingTags, builder.preferredVehicleParkingTags ); - this.parkTime = builder.parkTime; - this.parkCost = builder.parkCost; + this.time = builder.time; + this.cost = builder.cost; } public static VehicleParkingPreferences.Builder of() { @@ -85,13 +85,13 @@ public VehicleParkingFilter preferred() { } /** Time to park a vehicle */ - public Duration parkTime() { - return parkTime; + public Duration time() { + return time; } /** Cost of parking a bike. */ - public Cost parkCost() { - return parkCost; + public Cost cost() { + return cost; } @Override @@ -103,14 +103,14 @@ public boolean equals(Object o) { Objects.equals(unpreferredVehicleParkingTagCost, that.unpreferredVehicleParkingTagCost) && Objects.equals(filter, that.filter) && Objects.equals(preferred, that.preferred) && - Objects.equals(parkCost, that.parkCost) && - Objects.equals(parkTime, that.parkTime) + Objects.equals(cost, that.cost) && + Objects.equals(time, that.time) ); } @Override public int hashCode() { - return Objects.hash(unpreferredVehicleParkingTagCost, filter, preferred, parkCost, parkTime); + return Objects.hash(unpreferredVehicleParkingTagCost, filter, preferred, cost, time); } @Override @@ -124,8 +124,8 @@ public String toString() { ) .addObj("filter", filter, DEFAULT.filter) .addObj("preferred", preferred, DEFAULT.preferred) - .addObj("parkCost", parkCost, DEFAULT.parkCost) - .addObj("parkTime", parkTime, DEFAULT.parkTime) + .addObj("cost", cost, DEFAULT.cost) + .addObj("time", time, DEFAULT.time) .toString(); } @@ -137,8 +137,8 @@ public static class Builder { private List requiredVehicleParkingTags; private List preferredVehicleParkingTags; private List notPreferredVehicleParkingTags; - private Cost parkCost; - private Duration parkTime; + private Cost cost; + private Duration time; private Builder(VehicleParkingPreferences original) { this.original = original; @@ -147,8 +147,8 @@ private Builder(VehicleParkingPreferences original) { this.requiredVehicleParkingTags = original.filter.select(); this.preferredVehicleParkingTags = original.preferred.select(); this.notPreferredVehicleParkingTags = original.preferred.not(); - this.parkCost = original.parkCost; - this.parkTime = original.parkTime; + this.cost = original.cost; + this.time = original.time; } public Builder withUnpreferredVehicleParkingTagCost(int cost) { @@ -180,18 +180,18 @@ public Builder withNotPreferredVehicleParkingTags(Set notPreferredVehicl return this; } - public Builder withParkCost(int cost) { - this.parkCost = Cost.costOfSeconds(cost); + public Builder withCost(int cost) { + this.cost = Cost.costOfSeconds(cost); return this; } - public Builder withParkTime(int seconds) { - this.parkTime = Duration.ofSeconds(seconds); + public Builder withTime(int seconds) { + this.time = Duration.ofSeconds(seconds); return this; } - public Builder withParkTime(Duration duration) { - this.parkTime = duration; + public Builder withTime(Duration duration) { + this.time = duration; return this; } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java index 951129bc7b7..b4afc67e31c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java @@ -52,19 +52,19 @@ Vehicle parking tags can originate from different places depending on the origin ) .asStringSet(List.of()) ) - .withParkTime( + .withTime( c - .of("parkTime") + .of("time") .since(V2_0) .summary("Time to park a vehicle.") - .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) + .asDuration(VehicleParkingPreferences.DEFAULT.time()) ) - .withParkCost( + .withCost( c - .of("parkCost") + .of("cost") .since(V2_0) .summary("Cost to park a vehicle.") - .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) + .asInt(VehicleParkingPreferences.DEFAULT.cost().toSeconds()) ) .withPreferredVehicleParkingTags( c diff --git a/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java b/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java index be909c1dc4c..d32f13d6ea4 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java @@ -94,20 +94,10 @@ protected State[] traverseUnPark(State s0) { if (streetMode.includesBiking()) { final BikePreferences bike = s0.getPreferences().bike(); - return traverseUnPark( - s0, - bike.parking().parkCost(), - bike.parking().parkTime(), - TraverseMode.BICYCLE - ); + return traverseUnPark(s0, bike.parking().cost(), bike.parking().time(), TraverseMode.BICYCLE); } else if (streetMode.includesDriving()) { final CarPreferences car = s0.getPreferences().car(); - return traverseUnPark( - s0, - car.parking().parkCost(), - car.parking().parkTime(), - TraverseMode.CAR - ); + return traverseUnPark(s0, car.parking().cost(), car.parking().time(), TraverseMode.CAR); } else { return State.empty(); } @@ -151,14 +141,14 @@ private State[] traversePark(State s0) { return traversePark( s0, - preferences.bike().parking().parkCost(), - preferences.bike().parking().parkTime() + preferences.bike().parking().cost(), + preferences.bike().parking().time() ); } else if (streetMode.includesDriving()) { return traversePark( s0, - preferences.car().parking().parkCost(), - preferences.car().parking().parkTime() + preferences.car().parking().cost(), + preferences.car().parking().time() ); } else { return State.empty(); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index a314aa48799..8a6ac3f4f45 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -27,7 +27,7 @@ class BikePreferencesTest { .withBoardCost(BOARD_COST) .withOptimizeType(OPTIMIZE_TYPE) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) - .withParking(parking -> parking.withParkCost(PARK_COST).build()) + .withParking(parking -> parking.withCost(PARK_COST).build()) .withOptimizeTriangle(it -> it.withSlope(1).build()) .build(); @@ -64,7 +64,7 @@ void rental() { @Test void parking() { - var vehicleParking = VehicleParkingPreferences.of().withParkCost(PARK_COST).build(); + var vehicleParking = VehicleParkingPreferences.of().withCost(PARK_COST).build(); assertEquals(vehicleParking, subject.parking()); } @@ -91,7 +91,7 @@ void testToString() { "speed: 2.0, " + "reluctance: 1.2, " + "boardCost: $660, " + - "parking: VehicleParkingPreferences{parkCost: $30}, " + + "parking: VehicleParkingPreferences{cost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "optimizeType: TRIANGLE, " + "optimizeTriangle: TimeSlopeSafetyTriangle[time=0.0, slope=1.0, safety=0.0]" + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index 3c0a294d7e2..4359ed9b33d 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -30,7 +30,7 @@ class CarPreferencesTest { .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) - .withParking(parking -> parking.withParkCost(PARK_COST).build()) + .withParking(parking -> parking.withCost(PARK_COST).build()) .build(); @Test @@ -71,7 +71,7 @@ void rental() { @Test void parking() { - var vehicleParking = VehicleParkingPreferences.of().withParkCost(PARK_COST).build(); + var vehicleParking = VehicleParkingPreferences.of().withCost(PARK_COST).build(); assertEquals(vehicleParking, subject.parking()); } @@ -94,7 +94,7 @@ void testToString() { "CarPreferences{" + "speed: 20.0, " + "reluctance: 5.1, " + - "parking: VehicleParkingPreferences{parkCost: $30}, " + + "parking: VehicleParkingPreferences{cost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "pickupTime: PT10M, " + "pickupCost: $500, " + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java index 35666b53f9f..ff43a7ddba6 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java @@ -38,20 +38,20 @@ void unpreferredCost() { } @Test - void parkCost() { - assertEquals(PARKING_COST, subject.parkCost()); + void cost() { + assertEquals(PARKING_COST, subject.cost()); } @Test - void parkTime() { - assertEquals(PARKING_TIME, subject.parkTime()); + void time() { + assertEquals(PARKING_TIME, subject.time()); } @Test void testCopyOfEqualsAndHashCode() { // Create a copy, make a change and set it back again to force creating a new object - var other = subject.copyOf().withParkCost(10).build(); - var same = other.copyOf().withParkCost(PARKING_COST.toSeconds()).build(); + var other = subject.copyOf().withCost(10).build(); + var same = other.copyOf().withCost(PARKING_COST.toSeconds()).build(); assertEqualsAndHashCode(subject, other, same); } @@ -63,8 +63,8 @@ void testToString() { "unpreferredVehicleParkingTagCost: $360, " + "filter: VehicleParkingFilter{not: [tags=[not]], select: [tags=[bar]]}, " + "preferred: VehicleParkingFilter{not: [tags=[bar]], select: [tags=[foo]]}, " + - "parkCost: $240, " + - "parkTime: PT2M}", + "cost: $240, " + + "time: PT2M}", subject.toString() ); } @@ -81,8 +81,8 @@ private VehicleParkingPreferences createPreferences() { .withUnpreferredVehicleParkingTagCost(UNPREFERRED_COST) .withRequiredVehicleParkingTags(REQUIRED_TAGS) .withBannedVehicleParkingTags(BANNED_TAGS) - .withParkCost(PARKING_COST.toSeconds()) - .withParkTime(PARKING_TIME) + .withCost(PARKING_COST.toSeconds()) + .withTime(PARKING_TIME) .build(); } } diff --git a/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java b/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java index 6dd53ae0c6e..c4f7f52f4ec 100644 --- a/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java +++ b/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java @@ -142,16 +142,16 @@ protected List runStreetSearchAndCreateDescriptor( b.withParking(parking -> { parking.withRequiredVehicleParkingTags(requiredTags); parking.withBannedVehicleParkingTags(bannedTags); - parking.withParkCost(120); - parking.withParkTime(60); + parking.withCost(120); + parking.withTime(60); }) ) .withCar(c -> c.withParking(parking -> { parking.withRequiredVehicleParkingTags(requiredTags); parking.withBannedVehicleParkingTags(bannedTags); - parking.withParkCost(240); - parking.withParkTime(180); + parking.withCost(240); + parking.withTime(180); }) ) ); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java index a9932381b40..a2a052d3b5c 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java @@ -64,7 +64,7 @@ void foo(Set parkingTags, Set not, Set select, boolean s bike.withParking(parkingPreferences -> { parkingPreferences.withRequiredVehicleParkingTags(select); parkingPreferences.withBannedVehicleParkingTags(not); - parkingPreferences.withParkCost(0); + parkingPreferences.withCost(0); }); }) ); diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java b/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java index 41ecbe162bb..5969121b6d6 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java @@ -88,7 +88,7 @@ private void runTest( bike.withParking(parkingPreferences -> { parkingPreferences.withUnpreferredVehicleParkingTagCost(EXTRA_COST); parkingPreferences.withPreferredVehicleParkingTags(preferredTags); - parkingPreferences.withParkCost(0); + parkingPreferences.withCost(0); }); }) ); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 9f6b336fde5..089c2481dca 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -33,8 +33,8 @@ "dropOffCost": 30 }, "parking": { - "parkTime": "1m", - "parkCost": 120 + "time": "1m", + "cost": 120 }, "triangle": { "safety": 0.4, @@ -53,8 +53,8 @@ "dropOffCost": 30 }, "parking": { - "parkTime": "5m", - "parkCost": 600 + "time": "5m", + "cost": 600 } }, "walk": { From 173df94640a2fa09351cdaa82568bb7f933041da Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 9 Jan 2024 17:59:47 +0200 Subject: [PATCH 093/356] Update docs --- docs/RouteRequest.md | 6 +++--- .../standalone/config/routerequest/RouteRequestConfig.java | 2 +- .../config/routerequest/VehicleWalkingConfig.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 06c7b55c521..f9a4e7e5d2f 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -79,7 +79,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | |    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | |       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle. | *Optional* | `"PT0S"` | 2.0 | |       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | |       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | |       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | @@ -440,7 +440,7 @@ Sometimes there is a need to configure a longer alighting times for specific mod Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. -This is the cost that is used when boarding while cycling.This is usually higher that walkBoardCost. +This is the cost that is used when boarding while cycling. This is usually higher that walkBoardCost.

    optimization

    @@ -541,7 +541,7 @@ not meant for controlling the cost of those events. **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` **Path:** /routingDefaults/bicycle/walk -The time it takes the user to hop on or off a vehicle in seconds. +The time it takes the user to hop on or off a vehicle. Time it takes to rent or park a vehicle have their own parameters and this is not meant for controlling the duration of those events. diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 8aaa0b1d243..6ee164f0083 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -362,7 +362,7 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu "Prevents unnecessary transfers by adding a cost for boarding a transit vehicle." ) .description( - "This is the cost that is used when boarding while cycling." + + "This is the cost that is used when boarding while cycling. " + "This is usually higher that walkBoardCost." ) .asInt(dft.boardCost()) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index ac6ac7d92f4..6bc3bd3ffca 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -38,7 +38,7 @@ private static void mapVehicleWalkingPreferences( c .of("hopTime") .since(V2_0) - .summary("The time it takes the user to hop on or off a vehicle in seconds.") + .summary("The time it takes the user to hop on or off a vehicle.") .description( """ Time it takes to rent or park a vehicle have their own parameters and this is not meant From cdc09ca6e59bce534e4c4759955bfd902dec87f0 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 17:16:31 +0100 Subject: [PATCH 094/356] Move server info classes back into main code --- .../org/opentripplanner/api}/model/serverinfo/ApiConfigInfo.java | 0 .../opentripplanner/api}/model/serverinfo/ApiProjectVersion.java | 0 .../org/opentripplanner/api}/model/serverinfo/ApiServerInfo.java | 0 .../api}/model/serverinfo/ApiVersionControlInfo.java | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/{ext/java/org/opentripplanner/ext/restapi => main/java/org/opentripplanner/api}/model/serverinfo/ApiConfigInfo.java (100%) rename src/{ext/java/org/opentripplanner/ext/restapi => main/java/org/opentripplanner/api}/model/serverinfo/ApiProjectVersion.java (100%) rename src/{ext/java/org/opentripplanner/ext/restapi => main/java/org/opentripplanner/api}/model/serverinfo/ApiServerInfo.java (100%) rename src/{ext/java/org/opentripplanner/ext/restapi => main/java/org/opentripplanner/api}/model/serverinfo/ApiVersionControlInfo.java (100%) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiConfigInfo.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiConfigInfo.java rename to src/main/java/org/opentripplanner/api/model/serverinfo/ApiConfigInfo.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiProjectVersion.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiProjectVersion.java rename to src/main/java/org/opentripplanner/api/model/serverinfo/ApiProjectVersion.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiServerInfo.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiServerInfo.java rename to src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiVersionControlInfo.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java similarity index 100% rename from src/ext/java/org/opentripplanner/ext/restapi/model/serverinfo/ApiVersionControlInfo.java rename to src/main/java/org/opentripplanner/api/model/serverinfo/ApiVersionControlInfo.java From 3c8fd3ed0696b0a41e1f3e0a6999c8f372ee25b8 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 9 Jan 2024 20:26:26 +0100 Subject: [PATCH 095/356] review: Six spelling removeNone -> removeNon --- .../transit/AccessEgressFunctions.java | 10 ++-- .../rangeraptor/transit/AccessPaths.java | 8 +-- .../rangeraptor/transit/EgressPaths.java | 8 +-- .../transit/AccessEgressFunctionsTest.java | 50 +++++++++---------- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java index 275a0f85cf3..d4bf4d1ef92 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java @@ -81,10 +81,10 @@ private AccessEgressFunctions() {} * Filter non-optimal paths away for the standard search. This method does not * look at the c1 value. */ - static Collection removeNoneOptimalPathsForStandardRaptor( + static Collection removeNonOptimalPathsForStandardRaptor( Collection paths ) { - return removeNoneOptimalPaths(paths, STANDARD_COMPARATOR); + return removeNonOptimalPaths(paths, STANDARD_COMPARATOR); } /** @@ -92,10 +92,10 @@ static Collection removeNoneOptimalPathsForStandardRaptor( * not remove any paths since the caller should not pass in duplicates, but it turns out that * this happens, so we do it. */ - static Collection removeNoneOptimalPathsForMcRaptor( + static Collection removeNonOptimalPathsForMcRaptor( Collection paths ) { - var result = removeNoneOptimalPaths(paths, MC_COMPARATOR); + var result = removeNonOptimalPaths(paths, MC_COMPARATOR); if (LOG.isDebugEnabled() && result.size() < paths.size()) { var duplicates = new ArrayList<>(paths); duplicates.removeAll(result); @@ -137,7 +137,7 @@ static TIntObjectMap> groupByStop(Collection removeNoneOptimalPaths( + static Collection removeNonOptimalPaths( Collection paths, ParetoComparator comparator ) { diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java index dd757ac0415..5c26a10db23 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessPaths.java @@ -1,8 +1,8 @@ package org.opentripplanner.raptor.rangeraptor.transit; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByRound; -import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForMcRaptor; -import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForStandardRaptor; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForMcRaptor; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForStandardRaptor; import gnu.trove.map.TIntObjectMap; import java.util.Arrays; @@ -59,9 +59,9 @@ public int calculateMaxNumberOfRides() { */ public static AccessPaths create(Collection paths, RaptorProfile profile) { if (profile.is(RaptorProfile.MULTI_CRITERIA)) { - paths = removeNoneOptimalPathsForMcRaptor(paths); + paths = removeNonOptimalPathsForMcRaptor(paths); } else { - paths = removeNoneOptimalPathsForStandardRaptor(paths); + paths = removeNonOptimalPathsForStandardRaptor(paths); } return new AccessPaths( groupByRound(paths, RaptorAccessEgress::stopReachedByWalking), diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java index a1688ff8f5b..374fc050782 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/EgressPaths.java @@ -2,8 +2,8 @@ import static org.opentripplanner.raptor.api.request.RaptorProfile.MULTI_CRITERIA; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByStop; -import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForMcRaptor; -import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForStandardRaptor; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForMcRaptor; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForStandardRaptor; import gnu.trove.map.TIntObjectMap; import java.util.Collection; @@ -33,9 +33,9 @@ private EgressPaths(TIntObjectMap> pathsByStop) { */ public static EgressPaths create(Collection paths, RaptorProfile profile) { if (MULTI_CRITERIA.is(profile)) { - paths = removeNoneOptimalPathsForMcRaptor(paths); + paths = removeNonOptimalPathsForMcRaptor(paths); } else { - paths = removeNoneOptimalPathsForStandardRaptor(paths); + paths = removeNonOptimalPathsForStandardRaptor(paths); } return new EgressPaths(groupByStop(paths)); } diff --git a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java b/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java index 041d74786d7..1d4f90557b0 100644 --- a/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java +++ b/src/test/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctionsTest.java @@ -6,8 +6,8 @@ import static org.opentripplanner.raptor._data.transit.TestAccessEgress.flexAndWalk; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByRound; import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.groupByStop; -import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForMcRaptor; -import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNoneOptimalPathsForStandardRaptor; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForMcRaptor; +import static org.opentripplanner.raptor.rangeraptor.transit.AccessEgressFunctions.removeNonOptimalPathsForStandardRaptor; import java.util.Arrays; import java.util.Collection; @@ -48,127 +48,127 @@ class AccessEgressFunctionsTest implements RaptorTestConstants { .openingHours(T00_10, T01_00); @Test - void removeNoneOptimalPathsForStandardRaptorTest() { + void removeNonOptimalPathsForStandardRaptorTest() { // Empty set - assertElements(List.of(), removeNoneOptimalPathsForStandardRaptor(List.of())); + assertElements(List.of(), removeNonOptimalPathsForStandardRaptor(List.of())); // One element - assertElements(List.of(WALK_8m), removeNoneOptimalPathsForStandardRaptor(List.of(WALK_8m))); + assertElements(List.of(WALK_8m), removeNonOptimalPathsForStandardRaptor(List.of(WALK_8m))); // Shortest duration assertElements( List.of(WALK_8m), - removeNoneOptimalPathsForStandardRaptor(List.of(WALK_8m, WALK_10m)) + removeNonOptimalPathsForStandardRaptor(List.of(WALK_8m, WALK_10m)) ); // Fewest rides assertElements( List.of(FLEX_1x_8m), - removeNoneOptimalPathsForStandardRaptor(List.of(FLEX_1x_8m, FLEX_2x_8m)) + removeNonOptimalPathsForStandardRaptor(List.of(FLEX_1x_8m, FLEX_2x_8m)) ); // Arriving at the stop on-board, and by-foot. // OnBoard is better because we can do a transfer walk to nearby stops. assertElements( List.of(FLEX_1x_8m), - removeNoneOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_8m)) + removeNonOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_8m)) ); // Flex+walk is faster, flex arrive on-board, both is optimal assertElements( List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m), - removeNoneOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m)) + removeNonOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m)) ); // Walk has few rides, and Flex is faster - both is optimal assertElements( List.of(WALK_10m, FLEX_1x_8m), - removeNoneOptimalPathsForStandardRaptor(List.of(WALK_10m, FLEX_1x_8m)) + removeNonOptimalPathsForStandardRaptor(List.of(WALK_10m, FLEX_1x_8m)) ); // Walk without opening hours is better than with, because it can be time-shifted without // any constraints assertElements( List.of(WALK_8m), - removeNoneOptimalPathsForStandardRaptor(List.of(WALK_8m, WALK_W_OPENING_HOURS_8m)) + removeNonOptimalPathsForStandardRaptor(List.of(WALK_8m, WALK_W_OPENING_HOURS_8m)) ); // Walk with opening hours can NOT dominate another access/egress without - even if it is // faster. The reason is that it may not be allowed to time-shift it to the desired time. assertElements( List.of(WALK_10m, WALK_W_OPENING_HOURS_8m), - removeNoneOptimalPathsForStandardRaptor(List.of(WALK_10m, WALK_W_OPENING_HOURS_8m)) + removeNonOptimalPathsForStandardRaptor(List.of(WALK_10m, WALK_W_OPENING_HOURS_8m)) ); // If two paths both have opening hours, both should be accepted. assertElements( List.of(WALK_W_OPENING_HOURS_8m, WALK_W_OPENING_HOURS_8m_OTHER), - removeNoneOptimalPathsForStandardRaptor( + removeNonOptimalPathsForStandardRaptor( List.of(WALK_W_OPENING_HOURS_8m, WALK_W_OPENING_HOURS_8m_OTHER) ) ); } @Test - void removeNoneOptimalPathsForMcRaptorTest() { + void removeNonOptimalPathsForMcRaptorTest() { // Empty set - assertElements(List.of(), removeNoneOptimalPathsForMcRaptor(List.of())); + assertElements(List.of(), removeNonOptimalPathsForMcRaptor(List.of())); // One element - assertElements(List.of(WALK_8m), removeNoneOptimalPathsForMcRaptor(List.of(WALK_8m))); + assertElements(List.of(WALK_8m), removeNonOptimalPathsForMcRaptor(List.of(WALK_8m))); // Lowest cost assertElements( List.of(WALK_10m_C1_LOW), - removeNoneOptimalPathsForMcRaptor(List.of(WALK_10m, WALK_10m_C1_LOW)) + removeNonOptimalPathsForMcRaptor(List.of(WALK_10m, WALK_10m_C1_LOW)) ); // Shortest duration - assertElements(List.of(WALK_8m), removeNoneOptimalPathsForMcRaptor(List.of(WALK_8m, WALK_10m))); + assertElements(List.of(WALK_8m), removeNonOptimalPathsForMcRaptor(List.of(WALK_8m, WALK_10m))); // Fewest rides assertElements( List.of(FLEX_1x_8m), - removeNoneOptimalPathsForMcRaptor(List.of(FLEX_1x_8m, FLEX_2x_8m)) + removeNonOptimalPathsForMcRaptor(List.of(FLEX_1x_8m, FLEX_2x_8m)) ); // Arriving at the stop on-board, and by-foot. // OnBoard is better because we can do a transfer walk to nearby stops. assertElements( List.of(FLEX_1x_8m), - removeNoneOptimalPathsForMcRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_8m)) + removeNonOptimalPathsForMcRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_8m)) ); // Flex+walk is faster, flex arrive on-board, both is optimal assertElements( List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m), - removeNoneOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m)) + removeNonOptimalPathsForStandardRaptor(List.of(FLEX_AND_WALK_1x_8m, FLEX_1x_10m)) ); // Walk has few rides, and Flex is faster - both is optimal assertElements( List.of(WALK_10m, FLEX_1x_8m), - removeNoneOptimalPathsForMcRaptor(List.of(WALK_10m, FLEX_1x_8m)) + removeNonOptimalPathsForMcRaptor(List.of(WALK_10m, FLEX_1x_8m)) ); // Walk without opening hours is better than with, because it can be time-shifted without // any constraints assertElements( List.of(WALK_8m), - removeNoneOptimalPathsForMcRaptor(List.of(WALK_8m, WALK_W_OPENING_HOURS_8m)) + removeNonOptimalPathsForMcRaptor(List.of(WALK_8m, WALK_W_OPENING_HOURS_8m)) ); // Walk with opening hours can NOT dominate another access/egress without - even if it is // faster. The reason is that it may not be allowed to time-shift it to the desired time. assertElements( List.of(WALK_10m, WALK_W_OPENING_HOURS_8m), - removeNoneOptimalPathsForMcRaptor(List.of(WALK_10m, WALK_W_OPENING_HOURS_8m)) + removeNonOptimalPathsForMcRaptor(List.of(WALK_10m, WALK_W_OPENING_HOURS_8m)) ); // If two paths both have opening hours, both should be accepted. assertElements( List.of(WALK_W_OPENING_HOURS_8m, WALK_W_OPENING_HOURS_8m_OTHER), - removeNoneOptimalPathsForMcRaptor( + removeNonOptimalPathsForMcRaptor( List.of(WALK_W_OPENING_HOURS_8m, WALK_W_OPENING_HOURS_8m_OTHER) ) ); From de319cdf178a35f85e114d28945ab5c51e9cb2ad Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 9 Jan 2024 20:30:21 +0100 Subject: [PATCH 096/356] review: Make sure ParetoComparator is as readable as possible using white-space. --- .../rangeraptor/transit/AccessEgressFunctions.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java index d4bf4d1ef92..1ab737ae907 100644 --- a/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java +++ b/src/main/java/org/opentripplanner/raptor/rangeraptor/transit/AccessEgressFunctions.java @@ -29,7 +29,7 @@ public final class AccessEgressFunctions { private static final Logger LOG = LoggerFactory.getLogger(AccessEgressFunctions.class); /** - * Filter standard(not multi-criteria) Raptor access and egress paths. A path is pareto optimal + * Filter standard (not multi-criteria) Raptor access and egress paths. A path is pareto optimal * for a given stop if *
      *
    1. @@ -53,8 +53,7 @@ public final class AccessEgressFunctions { */ private static final ParetoComparator STANDARD_COMPARATOR = (l, r) -> ( - l.stopReachedOnBoard() && - !r.stopReachedOnBoard() || + (l.stopReachedOnBoard() && !r.stopReachedOnBoard()) || r.hasOpeningHours() || l.numberOfRides() < r.numberOfRides() || l.durationInSeconds() < r.durationInSeconds() @@ -66,13 +65,7 @@ public final class AccessEgressFunctions { * Raptor - it is a bug. */ private static final ParetoComparator MC_COMPARATOR = (l, r) -> - ( - (l.stopReachedOnBoard() && !r.stopReachedOnBoard()) || - r.hasOpeningHours() || - l.numberOfRides() < r.numberOfRides() || - l.durationInSeconds() < r.durationInSeconds() || - l.c1() < r.c1() - ); + STANDARD_COMPARATOR.leftDominanceExist(l, r) || l.c1() < r.c1(); /** private constructor to prevent instantiation of utils class. */ private AccessEgressFunctions() {} From 4b7cffa65b032e57925eb16b4807e45e0b385d7e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 16:41:32 +0100 Subject: [PATCH 097/356] Update dev meeting calendar instructions --- docs/Developers-Guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Developers-Guide.md b/docs/Developers-Guide.md index e12d9cf6c1b..8a68f83f301 100644 --- a/docs/Developers-Guide.md +++ b/docs/Developers-Guide.md @@ -63,8 +63,8 @@ There are several ways to get involved: * Create pull requests citing the relevant issue. -* Join developer meetings hosted twice a week. Check the specific times - on [this calendar](https://calendar.google.com/calendar/u/0/embed?src=ormbltvsqb6adl80ejgudt0glc@group.calendar.google.com) +* Join developer meetings hosted twice a week. Check the specific times and URLs + on [this page](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CONTRIBUTING.md#developer-meetings) ### Branches and Branch Protection From 41b5cf0fce39a93b59f4dbbca22134cf748217f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Wed, 10 Jan 2024 22:20:11 +0100 Subject: [PATCH 098/356] Improve: Pin all dependencies, past and future --- client-next/.npmrc | 1 + client-next/package-lock.json | 50 +++++++++++++++++------------------ client-next/package.json | 50 +++++++++++++++++------------------ 3 files changed, 51 insertions(+), 50 deletions(-) create mode 100644 client-next/.npmrc diff --git a/client-next/.npmrc b/client-next/.npmrc new file mode 100644 index 00000000000..449691b70fd --- /dev/null +++ b/client-next/.npmrc @@ -0,0 +1 @@ +save-exact=true \ No newline at end of file diff --git a/client-next/package-lock.json b/client-next/package-lock.json index 85a29784489..19909ba109d 100644 --- a/client-next/package-lock.json +++ b/client-next/package-lock.json @@ -8,36 +8,36 @@ "name": "otp-debug-client-next", "version": "0.0.0", "dependencies": { - "@googlemaps/polyline-codec": "^1.0.28", - "bootstrap": "^5.3.1", - "graphql": "^16.8.0", - "graphql-request": "^6.1.0", - "maplibre-gl": "^3.3.0", - "react": "^18.2.0", - "react-bootstrap": "^2.8.0", - "react-dom": "^18.2.0", - "react-map-gl": "^7.1.5" + "@googlemaps/polyline-codec": "1.0.28", + "bootstrap": "5.3.1", + "graphql": "16.8.0", + "graphql-request": "6.1.0", + "maplibre-gl": "3.3.0", + "react": "18.2.0", + "react-bootstrap": "2.8.0", + "react-dom": "18.2.0", + "react-map-gl": "7.1.5" }, "devDependencies": { "@graphql-codegen/cli": "5.0.0", "@graphql-codegen/client-preset": "4.1.0", "@graphql-codegen/introspection": "4.0.0", - "@parcel/watcher": "^2.3.0", - "@types/react": "^18.2.15", - "@types/react-dom": "^18.2.7", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vitejs/plugin-react": "^4.0.3", - "eslint": "^8.45.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", - "prettier": "^3.0.3", - "typescript": "^5.2.2", - "vite": "^4.4.5" + "@parcel/watcher": "2.3.0", + "@types/react": "18.2.21", + "@types/react-dom": "18.2.7", + "@typescript-eslint/eslint-plugin": "6.5.0", + "@typescript-eslint/parser": "6.5.0", + "@vitejs/plugin-react": "4.0.4", + "eslint": "8.48.0", + "eslint-config-prettier": "9.0.0", + "eslint-plugin-import": "2.28.1", + "eslint-plugin-jsx-a11y": "6.7.1", + "eslint-plugin-react": "7.33.2", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-react-refresh": "0.4.3", + "prettier": "3.0.3", + "typescript": "5.2.2", + "vite": "4.4.9" } }, "node_modules/@aashutoshrathi/word-wrap": { diff --git a/client-next/package.json b/client-next/package.json index 4d453ed37ca..79d2c7942f1 100644 --- a/client-next/package.json +++ b/client-next/package.json @@ -15,35 +15,35 @@ "codegen": "graphql-codegen --config codegen.ts" }, "dependencies": { - "@googlemaps/polyline-codec": "^1.0.28", - "bootstrap": "^5.3.1", - "graphql": "^16.8.0", - "graphql-request": "^6.1.0", - "maplibre-gl": "^3.3.0", - "react": "^18.2.0", - "react-bootstrap": "^2.8.0", - "react-dom": "^18.2.0", - "react-map-gl": "^7.1.5" + "@googlemaps/polyline-codec": "1.0.28", + "bootstrap": "5.3.1", + "graphql": "16.8.0", + "graphql-request": "6.1.0", + "maplibre-gl": "3.3.0", + "react": "18.2.0", + "react-bootstrap": "2.8.0", + "react-dom": "18.2.0", + "react-map-gl": "7.1.5" }, "devDependencies": { "@graphql-codegen/cli": "5.0.0", "@graphql-codegen/client-preset": "4.1.0", "@graphql-codegen/introspection": "4.0.0", - "@parcel/watcher": "^2.3.0", - "@types/react": "^18.2.15", - "@types/react-dom": "^18.2.7", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "@vitejs/plugin-react": "^4.0.3", - "eslint": "^8.45.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", - "prettier": "^3.0.3", - "typescript": "^5.2.2", - "vite": "^4.4.5" + "@parcel/watcher": "2.3.0", + "@types/react": "18.2.21", + "@types/react-dom": "18.2.7", + "@typescript-eslint/eslint-plugin": "6.5.0", + "@typescript-eslint/parser": "6.5.0", + "@vitejs/plugin-react": "4.0.4", + "eslint": "8.48.0", + "eslint-config-prettier": "9.0.0", + "eslint-plugin-import": "2.28.1", + "eslint-plugin-jsx-a11y": "6.7.1", + "eslint-plugin-react": "7.33.2", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-react-refresh": "0.4.3", + "prettier": "3.0.3", + "typescript": "5.2.2", + "vite": "4.4.9" } } From c99c52cea163f0c93330577d7bda0fbf2a827476 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 11 Jan 2024 01:45:35 +0100 Subject: [PATCH 099/356] Update src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java Co-authored-by: Leonard Ehrenfried --- .../RemoveItinerariesWithShortStreetLeg.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java index 010828c4cff..3f587840690 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java @@ -11,13 +11,15 @@ * leg followed by parking the bike and taking transit. In such a case you would not need a bike * could just walk to the stop instead. *

      - * TODO: THIS FILTER DOES NOT FOLLOW THE ITINERARY FILTER FRAMEWORK. This filter should implement the - * {@link org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger}. - * - * TODO: This filter build on assumptions that is more or less an implementation detail. The - * filter should compare itineraries and remove them if a condition is meet, not just - * assume that a better option exist. Perhaps the access and egress should be filtered - * instead of filtering the transit itineraries? + * This filter does not follow the regular filter framework as it is intended only for use cases where + * several queries are combined in the frontend. + *

      + * Example: you have two queries for bike+transit and walk+transit each. Both give you very short legs + * to reach a train station. A user would not expect to see a bike+transit shorted than 200m leg when it's + * presented right next to a walk+transit leg of the same length. + *

      + * In other words, this offloads the comparison part of the filter chain to a system outside of OTP and + * that is the reason for this non-standard approach. */ public class RemoveItinerariesWithShortStreetLeg implements ItineraryListFilter { From bdb5355ca8e08111c45a6a06089879097059a674 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 11 Jan 2024 07:03:32 +0000 Subject: [PATCH 100/356] Add changelog entry for #5580 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 9f755bd8f8f..23bf7b11ad7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -70,6 +70,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Consider escalator edges in island pruning [#5591](https://github.com/opentripplanner/OpenTripPlanner/pull/5591) - Create own rental preferences for bike and car in the internal model [#5562](https://github.com/opentripplanner/OpenTripPlanner/pull/5562) - Adding situation-version to TransmodelGraphQL API [#5592](https://github.com/opentripplanner/OpenTripPlanner/pull/5592) +- Move REST API into sandbox [#5580](https://github.com/opentripplanner/OpenTripPlanner/pull/5580) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 8a67be4e70b33b6a63a34b6080d79a1e22778785 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 09:59:47 +0100 Subject: [PATCH 101/356] Apply review feedback --- .github/workflows/performance-test.yml | 1 - .../opentripplanner/street/search/state/TestStateBuilder.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/performance-test.yml b/.github/workflows/performance-test.yml index d764fdbeff0..c2168a79a06 100644 --- a/.github/workflows/performance-test.yml +++ b/.github/workflows/performance-test.yml @@ -4,7 +4,6 @@ on: push: branches: - dev-2.x - - max-count-rental jobs: perf-test: diff --git a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java b/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java index 752985de51e..a4dbf76e55e 100644 --- a/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java +++ b/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java @@ -93,7 +93,7 @@ public static TestStateBuilder ofScooterRental() { } /** - * Creates a state starts the scooter rental but in arriveBy mode, so therefore starting with + * Creates a state that starts the scooter rental in arriveBy mode, so starting with * a rental scooter and going backwards until it finds a rental vertex where to drop it. */ public static TestStateBuilder ofScooterRentalArriveBy() { From 43438baf59cd6a734859b509bd932aaa711d9c6f Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 11 Jan 2024 09:11:03 +0000 Subject: [PATCH 102/356] Add changelog entry for #5605 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 23bf7b11ad7..7458295b9ba 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -71,6 +71,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Create own rental preferences for bike and car in the internal model [#5562](https://github.com/opentripplanner/OpenTripPlanner/pull/5562) - Adding situation-version to TransmodelGraphQL API [#5592](https://github.com/opentripplanner/OpenTripPlanner/pull/5592) - Move REST API into sandbox [#5580](https://github.com/opentripplanner/OpenTripPlanner/pull/5580) +- Fix high walk reluctance leading to zero egress results for rental searches [#5605](https://github.com/opentripplanner/OpenTripPlanner/pull/5605) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 5972e5d4260192621c62be4019c63f71f327c005 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 10:26:37 +0100 Subject: [PATCH 103/356] Resolve merge artifacts --- .../inspector/vector/stop/StopLocationPropertyMapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java index 44729bcb407..ab9685dd0f6 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/StopLocationPropertyMapper.java @@ -5,13 +5,13 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -import org.opentripplanner.api.mapping.I18NStringMapper; -import org.opentripplanner.api.mapping.PropertyMapper; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.i18n.I18NStringMapper; import org.opentripplanner.inspector.vector.KeyValue; import org.opentripplanner.transit.model.site.StopLocation; /** - * A {@link PropertyMapper} for the {@link AreaStopsLayerBuilder} for the OTP debug client. + * A {@link PropertyMapper} for the {@link StopLocationPropertyMapper} for the OTP debug client. */ public class StopLocationPropertyMapper extends PropertyMapper { From 4fd4325127655df8f0fb7c0ea26a672b961e7e2d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 10:27:32 +0100 Subject: [PATCH 104/356] Update docs --- docs/Configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index b376b6b91dc..d43ff150926 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -241,7 +241,7 @@ Here is a list of all features which can be toggled on/off and their default val | `FaresV2` | Enable import of GTFS-Fares v2 data. | | ✓️ | | `FlexRouting` | Enable FLEX routing. | | ✓️ | | `GoogleCloudStorage` | Enable Google Cloud Storage integration. | | ✓️ | -| `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | +| `LegacyRestApi` | Enable legacy REST API. This API will be removed in the future. | ✓️ | ✓️ | | `RealtimeResolver` | When routing with ignoreRealtimeUpdates=true, add an extra step which populates results with real-time data | | ✓️ | | `ReportApi` | Enable the report API. | | ✓️ | | `RestAPIPassInDefaultConfigAsJson` | Enable a default RouteRequest to be passed in as JSON on the REST API - FOR DEBUGGING ONLY! | | | From c5dc28984a83a968660c2478c2a6b3301fa7a6d4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 12:14:00 +0100 Subject: [PATCH 105/356] Apply review feedback --- .../MapView/GeometryPropertyPopup.tsx | 27 ++++++++++++ .../src/components/MapView/MapView.tsx | 43 +++++++++---------- 2 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 client-next/src/components/MapView/GeometryPropertyPopup.tsx diff --git a/client-next/src/components/MapView/GeometryPropertyPopup.tsx b/client-next/src/components/MapView/GeometryPropertyPopup.tsx new file mode 100644 index 00000000000..d2b55689270 --- /dev/null +++ b/client-next/src/components/MapView/GeometryPropertyPopup.tsx @@ -0,0 +1,27 @@ +import { LngLat, Popup } from 'react-map-gl'; +import { Table } from 'react-bootstrap'; + +export function GeometryPropertyPopup({ + coordinates, + properties, + onClose, +}: { + coordinates: LngLat; + properties: { [s: string]: string }; + onClose: () => void; +}) { + return ( + onClose()}> + + + {Object.entries(properties).map(([key, value]) => ( + + + + + ))} + +
      {key}{value}
      +
      + ); +} diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index e401b1756e6..1b17e31cb88 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -1,4 +1,4 @@ -import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl, Popup } from 'react-map-gl'; +import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl } from 'react-map-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts'; import { NavigationMarkers } from './NavigationMarkers.tsx'; @@ -6,7 +6,7 @@ import { LegLines } from './LegLines.tsx'; import { useMapDoubleClick } from './useMapDoubleClick.ts'; import { useState } from 'react'; import { ContextMenuPopup } from './ContextMenuPopup.tsx'; -import { Table } from 'react-bootstrap'; +import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx'; // TODO: this should be configurable const initialViewState = { @@ -35,6 +35,20 @@ export function MapView({ const onMapDoubleClick = useMapDoubleClick({ tripQueryVariables, setTripQueryVariables }); const [showContextPopup, setShowContextPopup] = useState(null); const [showPropsPopup, setShowPropsPopup] = useState(null); + const showFeaturePropPopup = ( + e: mapboxgl.MapMouseEvent & { + features?: mapboxgl.MapboxGeoJSONFeature[] | undefined; + }, + setShowPropsPopup: (value: ((prevState: PopupData | null) => PopupData | null) | PopupData | null) => void, + ) => { + if (e.features) { + // if you click on a cluster of map features it's possible that there are multiple + // to select from. we are using the first one instead of presenting a selection UI. + // you can always zoom in closer if you want to make a more specific click. + const feature = e.features[0]; + setShowPropsPopup({ coordinates: e.lngLat, feature: feature }); + } + }; return (

      @@ -50,10 +64,7 @@ export function MapView({ }} interactiveLayerIds={['regular-stop']} onClick={(e) => { - if (e.features) { - const props = e.features[0]; - setShowPropsPopup({ coordinates: e.lngLat, feature: props }); - } + showFeaturePropPopup(e, setShowPropsPopup); }} // put lat/long in URL and pan to it on page reload hash={true} @@ -79,23 +90,11 @@ export function MapView({ /> )} {showPropsPopup?.feature?.properties && ( - setShowPropsPopup(null)} - > - - - {Object.entries(showPropsPopup.feature.properties).map(([key, value]) => ( - - - - - ))} - -
      {key}{value}
      -
      + /> )}
      From 92c12e99554ae13777edc8178e9a15052864de3e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 16:16:41 +0100 Subject: [PATCH 106/356] Remove FareComponent --- ...CombinedInterlinedLegsFareServiceTest.java | 8 +- .../fares/impl/DefaultFareServiceTest.java | 46 ++++++------ .../ext/fares/impl/FaresIntegrationTest.java | 5 +- .../ext/fares/impl/HSLFareServiceTest.java | 6 +- ...reInFreeTransferWindowFareServiceTest.java | 4 +- .../ext/fares/FaresToItineraryMapper.java | 1 - .../ext/fares/impl/DefaultFareService.java | 23 +++--- .../ext/restapi/mapping/FareMapper.java | 14 +--- .../apis/gtfs/GtfsGraphQLIndex.java | 2 - .../apis/gtfs/datafetchers/ItineraryImpl.java | 3 +- .../gtfs/datafetchers/fareComponentImpl.java | 48 ------------ .../apis/gtfs/datafetchers/fareImpl.java | 6 +- .../gtfs/generated/GraphQLDataFetchers.java | 3 +- .../apis/gtfs/generated/graphql-codegen.yml | 1 - .../model/fare/ItineraryFares.java | 75 ++----------------- .../routing/core/FareComponent.java | 21 ------ .../apis/gtfs/GraphQLIntegrationTest.java | 5 -- 17 files changed, 61 insertions(+), 210 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareComponentImpl.java delete mode 100644 src/main/java/org/opentripplanner/routing/core/FareComponent.java diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java index c5901a0269e..dde40e06cef 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java @@ -69,11 +69,11 @@ void modes(CombinationMode mode, Itinerary itinerary, Money totalPrice, String h assertEquals(totalPrice, price); var firstLeg = itinerary.getTransitLeg(0); - var uses = fare.legProductsFromComponents().get(firstLeg); + var uses = fare.getLegProducts().get(firstLeg); assertEquals(1, uses.size()); var secondLeg = itinerary.getTransitLeg(1); - uses = fare.legProductsFromComponents().get(secondLeg); + uses = fare.getLegProducts().get(secondLeg); assertEquals(1, uses.size()); } @@ -89,14 +89,14 @@ void legFares() { var fare = service.calculateFares(itinerary); var firstLeg = itinerary.getTransitLeg(0); - var uses = List.copyOf(fare.legProductsFromComponents().get(firstLeg)); + var uses = List.copyOf(fare.getLegProducts().get(firstLeg)); assertEquals(1, uses.size()); var firstLegUse = uses.get(0); assertEquals(tenDollars, firstLegUse.product().price()); var secondLeg = itinerary.getTransitLeg(1); - uses = List.copyOf(fare.legProductsFromComponents().get(secondLeg)); + uses = List.copyOf(fare.getLegProducts().get(secondLeg)); assertEquals(1, uses.size()); var secondLegUse = uses.get(0); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 768e586da31..c0daa7bd3c0 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_STOP; import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_TO_CITY_CENTER_SET; import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_A_STOP; @@ -56,13 +55,10 @@ void simpleZoneBasedFare() { assertEquals(TEN_DOLLARS, fp.price()); assertEquals("F:regular", fp.id().toString()); - var lp = fare.legProductsFromComponents(); + var lp = fare.getLegProducts(); assertEquals(1, lp.size()); var product = lp.values().iterator().next().product(); assertEquals(TEN_DOLLARS, product.price()); - - // the leg products from the components and the "true" leg products are different collections - assertTrue(fare.getLegProducts().isEmpty()); } @Test @@ -91,9 +87,7 @@ void shouldNotCombineInterlinedLegs() { assertEquals(TWENTY_DOLLARS, price); - assertTrue(fare.getLegProducts().isEmpty()); - - var legProductsFromComponents = fare.legProductsFromComponents(); + var legProductsFromComponents = fare.getLegProducts(); var firstLeg = itin.getLegs().get(0); var products = List.copyOf(legProductsFromComponents.get(firstLeg)); @@ -124,18 +118,18 @@ void unknownLeg() { var price = fare.getFare(FareType.regular); assertEquals(Money.usDollars(-0.01f), price); - var components = fare.getComponents(FareType.regular); - assertEquals(1, components.size()); + var fareProducts = List.copyOf(fare.getLegProducts().values()); + assertEquals(1, fareProducts.size()); - var component = components.get(0); - assertEquals(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), component.fareId()); - assertEquals(TEN_DOLLARS, component.price()); + var fp = fareProducts.get(0).product(); + assertEquals(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), fp.id()); + assertEquals(TEN_DOLLARS, fp.price()); var firstBusLeg = itin.firstTransitLeg().get(); - assertEquals(List.of(firstBusLeg), component.legs()); + //assertEquals(List.of(firstBusLeg), fp.legs()); - var legProductsFromComponent = fare.legProductsFromComponents(); - assertEquals(1, legProductsFromComponent.size()); + var legProducts = fare.getLegProducts(); + assertEquals(1, legProducts.size()); } @Test @@ -150,18 +144,18 @@ void multipleFeeds() { var result = service.calculateFares(itin); var resultComponents = result - .getComponents(FareType.regular) + .getLegProducts() + .values() .stream() - .map(r -> r.fareId()) + .map(r -> r.product().id()) .toList(); - var resultPrice = result.getFare(FareType.regular); - assertEquals( List.of(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()), resultComponents ); + var resultPrice = result.getFare(FareType.regular); assertEquals(TWENTY_DOLLARS, resultPrice); } @@ -179,17 +173,18 @@ void multipleFeedsWithTransfersWithinFeed() { var result = service.calculateFares(itin); var resultComponents = result - .getComponents(FareType.regular) + .getLegProducts() + .values() .stream() - .map(r -> r.fareId()) + .map(r -> r.product().id()) .toList(); - var resultPrice = result.getFare(FareType.regular); assertEquals( List.of(INSIDE_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()), resultComponents ); + var resultPrice = result.getFare(FareType.regular); assertEquals(TWENTY_DOLLARS, resultPrice); } @@ -204,9 +199,10 @@ void multipleFeedsWithUnknownFareLegs() { .build(); var result = service.calculateFares(itin); var resultComponents = result - .getComponents(FareType.regular) + .getLegProducts() + .values() .stream() - .map(r -> r.fareId()) + .map(r -> r.product().id()) .toList(); var resultPrice = result.getFare(FareType.regular); assertEquals(List.of(OTHER_FEED_ATTRIBUTE.getId()), resultComponents); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 939d05cb2c2..ecf06c6b7df 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -24,7 +24,6 @@ import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.test.support.ResourceLoader; import org.opentripplanner.transit.model.basic.Money; -import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.service.TransitModel; public class FaresIntegrationTest { @@ -130,7 +129,7 @@ public void testFareComponent() { var to = GenericLocation.fromStopId("Destination", feedId, "B"); var fare = getFare(from, to, dateTime, serverContext); - + /* var fareComponents = fare.getComponents(FareType.regular); assertEquals(fareComponents.size(), 1); assertEquals(fareComponents.get(0).price(), tenUSD); @@ -220,6 +219,8 @@ public void testFareComponent() { assertEquals(fareComponents.get(1).fareId(), new FeedScopedId(feedId, "BD")); assertEquals(fareComponents.get(1).routes().get(0), new FeedScopedId(feedId, "2")); assertEquals(fareComponents.get(1).routes().get(1), new FeedScopedId(feedId, "3")); + + */ } private static ItineraryFares getFare( diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java index 14fbe18f792..a094a01412b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java @@ -18,7 +18,6 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.fares.FareService; import org.opentripplanner.transit.model._data.TransitModelForTest; @@ -43,9 +42,10 @@ public void canCalculateHSLFares( expectedFareIds.toArray(), fareService .calculateFares(i) - .getComponents(FareType.regular) + .getLegProducts() + .values() .stream() - .map(FareComponent::fareId) + .map(u -> u.product().id()) .toArray() ); } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java index 57621c9ab0f..48dd6b520c5 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java @@ -1,7 +1,7 @@ package org.opentripplanner.ext.fares.impl; -import static graphql.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; import static org.opentripplanner.transit.model._data.TransitModelForTest.id; @@ -46,7 +46,7 @@ public void canCalculateFare( assertEquals(expectedFare, fares.getFare(FareType.regular)); for (var type : fares.getFareTypes()) { - assertTrue(fares.getComponents(type).isEmpty()); + assertFalse(fares.getLegProducts().isEmpty()); var prices = fares .getItineraryProducts() diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java b/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java index a2b0984e4a3..f4a871b3ceb 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java +++ b/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.fares; -import com.google.common.collect.Multimap; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index 6b7081de5ec..a39ccebe0e7 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -1,5 +1,7 @@ package org.opentripplanner.ext.fares.impl; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; import java.time.Duration; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -18,11 +20,11 @@ import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.ext.flex.FlexibleTransitLeg; import org.opentripplanner.model.fare.FareProduct; +import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.ScheduledTransitLeg; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.fares.FareService; import org.opentripplanner.transit.model.basic.Money; @@ -119,7 +121,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { ItineraryFares fare = ItineraryFares.empty(); boolean hasFare = false; for (FareType fareType : fareRulesPerType.keySet()) { - List components = new ArrayList<>(); + final Multimap fareProducts = LinkedHashMultimap.create(); List fares = new ArrayList<>(); boolean legWithoutRulesFound = false; boolean legsWithoutMatchingRulesFound = false; @@ -143,7 +145,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { } hasFare = feedHasFare || hasFare; // Other feeds might still have fare for some legs - components.addAll(currentFare.getComponents(fareType)); + fareProducts.putAll(currentFare.getLegProducts()); fare.addFare(fareType, currentFare.getFare(fareType)); currentFare @@ -170,7 +172,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { } } - fare.addFareComponent(fareType, components); + fare.addFareProductUses(fareProducts); // No fares will be discovered after this point if (!hasFare) { @@ -244,7 +246,7 @@ protected boolean populateFare( ) { FareSearch r = performSearch(fareType, legs, fareRules); - List components = new ArrayList<>(); + Multimap legProducts = LinkedHashMultimap.create(); int count = 0; int start = 0; int end = legs.size() - 1; @@ -276,16 +278,19 @@ protected boolean populateFare( componentLegs.add(leg); } } - components.add( - new FareComponent(fareId, Money.ofFractionalAmount(currency, cost), componentLegs) - ); + + var product = FareProduct + .of(fareId, fareId.toString(), Money.ofFractionalAmount(currency, cost)) + .build(); + componentLegs.forEach(l -> legProducts.put(l, product)); + ++count; start = via + 1; } var amount = r.resultTable[0][legs.size() - 1]; fare.addFare(fareType, Money.ofFractionalAmount(currency, amount)); - fare.addFareComponent(fareType, components); + fare.addFareProducts(legProducts); return count > 0; } diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java index a6020c6bf37..7eb0d26339e 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java @@ -24,7 +24,6 @@ import org.opentripplanner.model.fare.RiderCategory; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.transit.model.basic.Money; public class FareMapper { @@ -106,14 +105,7 @@ private List toApiFareProducts(Collection product) } private Map> toApiFareComponents(ItineraryFares fare) { - return fare - .getFareTypes() - .stream() - .map(key -> { - var money = fare.getComponents(key).stream().map(this::toApiFareComponent).toList(); - return new SimpleEntry<>(key, money); - }) - .collect(Collectors.toMap(e -> e.getKey().name(), Entry::getValue)); + return Map.of(); } private Map toApiMoneys(ItineraryFares fare) { @@ -139,8 +131,4 @@ private ApiMoney toApiMoney(Money m) { ) ); } - - private ApiFareComponent toApiFareComponent(FareComponent m) { - return new ApiFareComponent(m.fareId(), null, toApiMoney(m.price()), m.routes()); - } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index b50bbaa9b9e..7101d132834 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -77,7 +77,6 @@ import org.opentripplanner.apis.gtfs.datafetchers.VehicleRentalStationImpl; import org.opentripplanner.apis.gtfs.datafetchers.debugOutputImpl; import org.opentripplanner.apis.gtfs.datafetchers.elevationProfileComponentImpl; -import org.opentripplanner.apis.gtfs.datafetchers.fareComponentImpl; import org.opentripplanner.apis.gtfs.datafetchers.fareImpl; import org.opentripplanner.apis.gtfs.datafetchers.placeAtDistanceImpl; import org.opentripplanner.apis.gtfs.datafetchers.serviceTimeRangeImpl; @@ -129,7 +128,6 @@ protected static GraphQLSchema buildSchema() { .type(typeWiring.build(debugOutputImpl.class)) .type(typeWiring.build(DepartureRowImpl.class)) .type(typeWiring.build(elevationProfileComponentImpl.class)) - .type(typeWiring.build(fareComponentImpl.class)) .type(typeWiring.build(fareImpl.class)) .type(typeWiring.build(FeedImpl.class)) .type(typeWiring.build(FeedImpl.class)) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java index 5e0ee6285a8..5399783bee0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java @@ -3,6 +3,7 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; @@ -54,7 +55,7 @@ public DataFetcher>> fares() { Map result = new HashMap<>(); result.put("name", fareKey); result.put("fare", fare.getFare(fareKey)); - result.put("details", fare.getComponents(fareKey)); + result.put("details", List.of()); return result; }) .collect(Collectors.toList()); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareComponentImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareComponentImpl.java deleted file mode 100644 index a8c1b4d38f5..00000000000 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareComponentImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.opentripplanner.apis.gtfs.datafetchers; - -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; -import java.util.stream.Collectors; -import org.opentripplanner.apis.gtfs.GraphQLRequestContext; -import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; -import org.opentripplanner.routing.core.FareComponent; -import org.opentripplanner.transit.model.network.Route; -import org.opentripplanner.transit.service.TransitService; - -public class fareComponentImpl implements GraphQLDataFetchers.GraphQLFareComponent { - - @Override - public DataFetcher cents() { - return environment -> getSource(environment).price().minorUnitAmount(); - } - - @Override - public DataFetcher currency() { - return environment -> getSource(environment).price().currency().getCurrencyCode(); - } - - @Override - public DataFetcher fareId() { - return environment -> getSource(environment).fareId().toString(); - } - - @Override - public DataFetcher> routes() { - return environment -> { - TransitService transitService = getTransitService(environment); - return getSource(environment) - .routes() - .stream() - .map(transitService::getRouteForId) - .collect(Collectors.toList()); - }; - } - - private TransitService getTransitService(DataFetchingEnvironment environment) { - return environment.getContext().transitService(); - } - - private FareComponent getSource(DataFetchingEnvironment environment) { - return environment.getSource(); - } -} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java index e1986d215be..fb2c6ee184c 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java @@ -2,9 +2,9 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; +import java.util.List; import java.util.Map; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.transit.model.basic.Money; public class fareImpl implements GraphQLDataFetchers.GraphQLFare { @@ -15,8 +15,8 @@ public DataFetcher cents() { } @Override - public DataFetcher> components() { - return environment -> (Iterable) getSource(environment).get("details"); + public DataFetcher> components() { + return environment -> List.of(); } @Override diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index d89453be056..cd002ec187b 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -40,7 +40,6 @@ import org.opentripplanner.model.plan.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.api.response.RoutingError; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.routing.graphfinder.PatternAtStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; @@ -1239,7 +1238,7 @@ public interface GraphQLElevationProfileComponent { public interface GraphQLFare { public DataFetcher cents(); - public DataFetcher> components(); + public DataFetcher> components(); public DataFetcher currency(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml b/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml index 68901bdccef..c720fc5a119 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml @@ -55,7 +55,6 @@ config: elevationProfileComponent: org.opentripplanner.model.plan.ElevationProfile.Step Emissions: org.opentripplanner.model.plan.Emissions#Emissions fare: java.util.Map#Map - fareComponent: org.opentripplanner.routing.core.FareComponent#FareComponent Feed: String Geometry: org.locationtech.jts.geom.Geometry#Geometry InputField: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLInputField#GraphQLInputField diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 0f9f815efe6..3443c01a062 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -1,6 +1,5 @@ package org.opentripplanner.model.fare; -import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; @@ -11,12 +10,10 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.routing.core.FareType; import org.opentripplanner.transit.model.basic.Money; @@ -41,19 +38,6 @@ public class ItineraryFares { */ private final Multimap legProducts = LinkedHashMultimap.create(); - /** - * The fares V1 fare "components" that apply to individual legs (not the entire price of the - * itinerary). - *

      - * This is an ill-thought-out concept that was bolted onto the existing implementation in 2016 and - * is going to be removed once HSL has migrated off it. - *

      - * Note: LinkedHashMultimap keeps the insertion order - * @deprecated Exists only for backwards compatibility and will be removed in the future. - */ - @Deprecated - private final Multimap components = LinkedHashMultimap.create(); - /** * Holds the "fares" for the entire itinerary. The definition of a fare is not clear so * this is deprecated. @@ -93,19 +77,6 @@ public void addFare(FareType fareType, Money money) { fares.put(fareType, money); } - /** - * Add a collection of "fare components" for a type. These concepts are ill-defined and will be - * removed in the future. - *

      - * @deprecated Only exitst for backwards compatibility. - * Use @{link {@link ItineraryFares#addItineraryProducts(Collection)}}, - * {@link ItineraryFares#addFareProduct(Leg, FareProduct)} or - */ - @Deprecated - public void addFareComponent(FareType fareType, List components) { - this.components.replaceValues(fareType, components); - } - /** * Add fare products that cover the entire itinerary, i.e. are valid for all legs. */ @@ -127,17 +98,6 @@ public Money getFare(FareType type) { return fares.get(type); } - /** - * Get the "components" of a fare for a specific type. - *

      - * Use {@link ItineraryFares#getItineraryProducts()} or {@link ItineraryFares#getLegProducts()} - * instead. - */ - @Deprecated - public List getComponents(FareType type) { - return List.copyOf(components.get(type)); - } - /** * Return the set of {@link FareType}s that are contained in this instance. */ @@ -148,7 +108,7 @@ public Set getFareTypes() { @Override public int hashCode() { - return Objects.hash(itineraryProducts, legProducts, components); + return Objects.hash(itineraryProducts, legProducts); } @Override @@ -188,32 +148,11 @@ public void addFareProduct(Leg leg, Collection fareProduct) { fareProduct.forEach(fp -> addFareProduct(leg, fp)); } - /** - * Convert the fare received via the deprecated {@link FareComponent} to leg products. This - * inverts the relationship: - * - fare component has several legs - * - leg product is a mapping from leg to a list of fare products - */ - @Nonnull - public Multimap legProductsFromComponents() { - Multimap legProductsFromComponents = HashMultimap.create(); - for (var type : getFareTypes()) { - var components = getComponents(type); - - for (var c : components) { - var firstLegStartTime = c.legs().get(0).getStartTime(); - for (var leg : c.legs()) { - final FareProduct fareProduct = FareProduct - .of(c.fareId(), type.name(), c.price()) - .build(); - - legProductsFromComponents.put( - leg, - new FareProductUse(fareProduct.uniqueInstanceId(firstLegStartTime), fareProduct) - ); - } - } - } - return legProductsFromComponents; + public void addFareProducts(Multimap fareProducts) { + fareProducts.forEach((leg, fp) -> addFareProduct(leg, fp)); + } + + public void addFareProductUses(Multimap fareProducts) { + legProducts.putAll(fareProducts); } } diff --git a/src/main/java/org/opentripplanner/routing/core/FareComponent.java b/src/main/java/org/opentripplanner/routing/core/FareComponent.java deleted file mode 100644 index 4c609a80f19..00000000000 --- a/src/main/java/org/opentripplanner/routing/core/FareComponent.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.opentripplanner.routing.core; - -import java.util.List; -import org.opentripplanner.model.fare.FareProduct; -import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.transit.model.basic.Money; -import org.opentripplanner.transit.model.framework.FeedScopedId; - -/** - *

      - * FareComponent is a sequence of routes for a particular fare. - *

      - * @deprecated Because it exists only for backwards compatibility, and you should use the Fares V2 - * type, namely {@link FareProduct}. - */ -@Deprecated -public record FareComponent(FeedScopedId fareId, Money price, List legs) { - public List routes() { - return legs.stream().map(l -> l.getRoute().getId()).toList(); - } -} diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index a65c46b12fe..6e99e096c2c 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -61,7 +61,6 @@ import org.opentripplanner.routing.alertpatch.TimePeriod; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.core.FareComponent; import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.GraphFinder; @@ -185,10 +184,6 @@ static void setup() { var fares = new ItineraryFares(); fares.addFare(FareType.regular, Money.euros(3.1f)); - fares.addFareComponent( - FareType.regular, - List.of(new FareComponent(id("AB"), Money.euros(3.1f), List.of(busLeg))) - ); var dayPass = fareProduct("day-pass"); fares.addItineraryProducts(List.of(dayPass)); From 673415cbae447b24503e2a65de099b4ada1efe32 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 16:33:01 +0100 Subject: [PATCH 107/356] Update test assertion --- .../ext/fares/FaresToItineraryMapper.java | 9 +- .../__snapshots__/BikeRentalSnapshotTest.snap | 600 +++++++++--------- .../__snapshots__/ElevationSnapshotTest.snap | 300 +++++---- .../__snapshots__/TransitSnapshotTest.snap | 572 +++++++++-------- 4 files changed, 734 insertions(+), 747 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java b/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java index f4a871b3ceb..c545cbbb858 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java +++ b/src/ext/java/org/opentripplanner/ext/fares/FaresToItineraryMapper.java @@ -4,7 +4,6 @@ import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; /** * Takes fares and applies them to the legs of an itinerary. @@ -21,13 +20,9 @@ public static void addFaresToLegs(ItineraryFares fares, Itinerary i) { }) .toList(); - final Multimap legProductsFromComponents = fares.legProductsFromComponents(); - i.transformTransitLegs(leg -> { - var legInstances = fares.getLegProducts().get(leg); - leg.setFareProducts( - ListUtils.combine(itineraryFareUses, legProductsFromComponents.get(leg), legInstances) - ); + var legUses = fares.getLegProducts().get(leg); + leg.setFareProducts(ListUtils.combine(itineraryFareUses, legUses)); return leg; }); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap index d99f479ac16..36c56471be1 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap @@ -22,31 +22,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -57,7 +33,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 3 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2209, "legs" : [ @@ -510,31 +508,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -545,7 +519,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2539, "legs" : [ @@ -956,31 +952,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -991,7 +963,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 1805, "legs" : [ @@ -1298,31 +1292,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -1333,7 +1303,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 3 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2209, "legs" : [ @@ -1786,31 +1778,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -1821,7 +1789,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 3 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2209, "legs" : [ @@ -2274,31 +2264,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -2309,7 +2275,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 1805, "legs" : [ @@ -3291,31 +3279,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -3326,7 +3290,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2119, "legs" : [ @@ -3831,31 +3817,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -3866,7 +3828,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2503, "legs" : [ @@ -4251,31 +4235,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -4286,7 +4246,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2351, "legs" : [ @@ -4645,31 +4627,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -4680,7 +4638,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2119, "legs" : [ @@ -5185,31 +5165,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -5220,7 +5176,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2563, "legs" : [ @@ -5605,31 +5583,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -5640,7 +5594,29 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2351, "legs" : [ diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap index b5e40b383e4..5baa72515ec 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap @@ -550,31 +550,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -585,7 +561,29 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2305, "legs" : [ @@ -946,31 +944,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -981,7 +955,29 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2465, "legs" : [ @@ -1368,31 +1364,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -1403,7 +1375,29 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2396, "legs" : [ @@ -1764,31 +1758,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "15" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -1799,7 +1769,29 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2787, "legs" : [ @@ -2238,31 +2230,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "17" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -2273,7 +2241,29 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2305, "legs" : [ @@ -2634,31 +2624,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -2669,7 +2635,29 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2525, "legs" : [ diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap index f67c75f44ec..8c36afa32e6 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap @@ -250,31 +250,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -285,7 +261,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 4281, "legs" : [ @@ -735,31 +733,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "15" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -770,7 +744,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2315, "legs" : [ @@ -1285,31 +1281,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -1320,7 +1292,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 4295, "legs" : [ @@ -1770,31 +1764,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "15" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -1805,7 +1775,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2385, "legs" : [ @@ -2320,35 +2312,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "70" - }, - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -2359,7 +2323,49 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + }, + { + "legIndices" : [ + 2 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 3375, "legs" : [ @@ -3053,31 +3059,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -3088,7 +3070,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2895, "legs" : [ @@ -3541,31 +3545,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -3576,7 +3556,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2925, "legs" : [ @@ -4029,31 +4031,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -4064,7 +4042,29 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2895, "legs" : [ @@ -4517,35 +4517,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "70" - }, - { - "feedId" : "prt", - "id" : "77" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -4556,7 +4528,49 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + }, + { + "legIndices" : [ + 2 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 2957, "legs" : [ @@ -5029,35 +5043,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "name" : "regular" } ], - "details" : { - "regular" : [ - { - "fareId" : { - "feedId" : "prt", - "id" : "8" - }, - "price" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "routes" : [ - { - "feedId" : "prt", - "id" : "20" - }, - { - "feedId" : "prt", - "id" : "15" - } - ] - } - ] - }, + "details" : { }, "fare" : { "regular" : { "cents" : 200, @@ -5068,7 +5054,49 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "symbol" : "$" } } - } + }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + }, + { + "legIndices" : [ + 2 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "prt:8" + } + ] + } + ] }, "generalizedCost" : 3015, "legs" : [ From f5b95975e82e6e5868438249f75a8728b4ce5dbb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 17:26:53 +0100 Subject: [PATCH 108/356] Remove fare component tests --- .../ext/fares/impl/FaresIntegrationTest.java | 119 ------------------ .../ext/restapi/mapping/FareMapperTest.java | 2 - .../ext/fares/impl/farecomponents.gtfs.zip | Bin 2266 -> 0 bytes .../apis/gtfs/expectations/plan-fares.json | 30 +---- 4 files changed, 1 insertion(+), 150 deletions(-) delete mode 100644 src/ext-test/resources/org/opentripplanner/ext/fares/impl/farecomponents.gtfs.zip diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index ecf06c6b7df..d6a1432a75b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -22,7 +22,6 @@ import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.test.support.ResourceLoader; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.service.TransitModel; @@ -105,124 +104,6 @@ public void testPortland() { // assertEquals(cost.getFare(FareType.regular), new Money(new WrappedCurrency("USD"), 430)); } - @Test - public void testFareComponent() { - TestOtpModel model = ConstantsForTests.buildGtfsGraph( - ResourceLoader.of(this).file("farecomponents.gtfs.zip") - ); - Graph graph = model.graph(); - TransitModel transitModel = model.transitModel(); - String feedId = transitModel.getFeedIds().iterator().next(); - - var serverContext = TestServerContext.createServerContext(graph, transitModel); - - Money tenUSD = Money.usDollars(10); - - var dateTime = LocalDateTime - .of(2009, 8, 7, 0, 0, 0) - .atZone(ZoneId.of("America/Los_Angeles")) - .toInstant(); - - // A -> B, base case - - var from = GenericLocation.fromStopId("Origin", feedId, "A"); - var to = GenericLocation.fromStopId("Destination", feedId, "B"); - - var fare = getFare(from, to, dateTime, serverContext); - /* - var fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 1); - assertEquals(fareComponents.get(0).price(), tenUSD); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "AB")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "1")); - - // D -> E, null case - - from = GenericLocation.fromStopId("Origin", feedId, "D"); - to = GenericLocation.fromStopId("Destination", feedId, "E"); - fare = getFare(from, to, dateTime, serverContext); - assertEquals(ItineraryFares.empty(), fare); - - // A -> C, 2 components in a path - - from = GenericLocation.fromStopId("Origin", feedId, "A"); - to = GenericLocation.fromStopId("Destination", feedId, "C"); - fare = getFare(from, to, dateTime, serverContext); - - fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 2); - assertEquals(fareComponents.get(0).price(), tenUSD); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "AB")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "1")); - assertEquals(fareComponents.get(1).price(), tenUSD); - assertEquals(fareComponents.get(1).fareId(), new FeedScopedId(feedId, "BC")); - assertEquals(fareComponents.get(1).routes().get(0), new FeedScopedId(feedId, "2")); - - // B -> D, 2 fully connected components - from = GenericLocation.fromStopId("Origin", feedId, "B"); - to = GenericLocation.fromStopId("Destination", feedId, "D"); - fare = getFare(from, to, dateTime, serverContext); - - fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 1); - assertEquals(fareComponents.get(0).price(), tenUSD); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "BD")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "2")); - assertEquals(fareComponents.get(0).routes().get(1), new FeedScopedId(feedId, "3")); - - // E -> G, missing in between fare - from = GenericLocation.fromStopId("Origin", feedId, "E"); - to = GenericLocation.fromStopId("Destination", feedId, "G"); - fare = getFare(from, to, dateTime, serverContext); - - fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 1); - assertEquals(tenUSD, fareComponents.get(0).price()); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "EG")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "5")); - assertEquals(fareComponents.get(0).routes().get(1), new FeedScopedId(feedId, "6")); - - // C -> E, missing fare after - from = GenericLocation.fromStopId("Origin", feedId, "C"); - to = GenericLocation.fromStopId("Destination", feedId, "E"); - fare = getFare(from, to, dateTime, serverContext); - - fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 1); - assertEquals(fareComponents.get(0).price(), tenUSD); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "CD")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "3")); - - // D -> G, missing fare before - from = GenericLocation.fromStopId("Origin", feedId, "D"); - to = GenericLocation.fromStopId("Destination", feedId, "G"); - fare = getFare(from, to, dateTime, serverContext); - - fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 1); - assertEquals(fareComponents.get(0).price(), tenUSD); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "EG")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "5")); - assertEquals(fareComponents.get(0).routes().get(1), new FeedScopedId(feedId, "6")); - - // A -> D, use individual component parts - from = GenericLocation.fromStopId("Origin", feedId, "A"); - to = GenericLocation.fromStopId("Destination", feedId, "D"); - fare = getFare(from, to, dateTime, serverContext); - - fareComponents = fare.getComponents(FareType.regular); - assertEquals(fareComponents.size(), 2); - assertEquals(fareComponents.get(0).price(), tenUSD); - assertEquals(fareComponents.get(0).fareId(), new FeedScopedId(feedId, "AB")); - assertEquals(fareComponents.get(0).routes().get(0), new FeedScopedId(feedId, "1")); - assertEquals(fareComponents.get(1).price(), tenUSD); - assertEquals(fareComponents.get(1).fareId(), new FeedScopedId(feedId, "BD")); - assertEquals(fareComponents.get(1).routes().get(0), new FeedScopedId(feedId, "2")); - assertEquals(fareComponents.get(1).routes().get(1), new FeedScopedId(feedId, "3")); - - */ - } - private static ItineraryFares getFare( GenericLocation from, GenericLocation to, diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java index bd1bd07aa43..4b455cce0f7 100644 --- a/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; -import java.util.List; import java.util.Locale; import org.junit.jupiter.api.Test; import org.opentripplanner.model.fare.ItineraryFares; @@ -29,6 +28,5 @@ public void emptyDetails() { var apiMoney = apiFare.fare().get(FareType.regular.name()); assertEquals(500, apiMoney.cents()); assertEquals("USD", apiMoney.currency().currency()); - assertEquals(List.of(), apiFare.details().get(FareType.regular.name())); } } diff --git a/src/ext-test/resources/org/opentripplanner/ext/fares/impl/farecomponents.gtfs.zip b/src/ext-test/resources/org/opentripplanner/ext/fares/impl/farecomponents.gtfs.zip deleted file mode 100644 index 4f7625f55c5c4ec6cbacf603709360eb6f4d0a7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2266 zcmWIWW@Zs#-~d8~m@sPwD98oUTnq{fiRr0%$(4E~6(yk|ybSCU)E;=1+V>`Ys540_ zt>9*0WO>2NzyKz^ef-aQuj@JQbJ4S9!zZEQ;KVnV7Rg9#Rxvi;s%5V~mHW{3Lhmzv zp#?1)jJ>?L)_nPTxxuMwrD*3)R?C%DCx7m=>f5=}b>_*=Uv(>=ew_Hz^=1r1fHylw zLh|aHAwbuFToeFz>yL=lZcwK(GyoYqK({6*=A`DOBo@J4n^G7Mio>;`r#Esn81S%M z*n9tyqNvQDSwcQXn!-GSj_$vH#WQaQ`*F?Fk!j~zAJv5%vW`mrx^KoS_2}6pIzf9x z)_S_X<~J2N-EwTAb}7r9ZRM9{)JZa^c|4FfC@2SV@D_{PvEe``ft-bKa9h4Feew4<{-JYpc1ERWse^Ox|YY`Vs-jY z?;Fz$+7uam^(QF2%m480UTB*2Vx!}`>v|;1zpTAAPjv4ZiQPpSGAmXzCMEH;b^qGu zeQLsqPmCbv_44IOI0GF3asthhkYXHiCl50^uN<>JqncJ1Uj|2B)PIIubp8r|jGhy37wxn%a7%wj0?#h2!ChZ5`=JL4YnH%Td zy=449%=fSTj)z;H#4J~xs@peb+s-ZQTK+4=^EU3k-owAWX3vDCL%9c@)*UTynbD5M@T%k0_=hyVMGzFl%3Ds&~I|Wc{s>cp_6i%|CO_p%eK(=Djezyt(_WuXWHdKS$Q};!-C#(s%!U z6H>AJM`!=~ Date: Tue, 9 Jan 2024 18:02:37 +0100 Subject: [PATCH 109/356] Update more tests --- .../impl/CombinedInterlinedLegsFareServiceTest.java | 4 ++-- .../ext/fares/impl/DefaultFareServiceTest.java | 9 ++------- .../ext/fares/impl/HSLFareServiceTest.java | 4 ++-- .../HighestFareInFreeTransferWindowFareServiceTest.java | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java index dde40e06cef..350bae04dce 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java @@ -92,14 +92,14 @@ void legFares() { var uses = List.copyOf(fare.getLegProducts().get(firstLeg)); assertEquals(1, uses.size()); - var firstLegUse = uses.get(0); + var firstLegUse = uses.getFirst(); assertEquals(tenDollars, firstLegUse.product().price()); var secondLeg = itinerary.getTransitLeg(1); uses = List.copyOf(fare.getLegProducts().get(secondLeg)); assertEquals(1, uses.size()); - var secondLegUse = uses.get(0); + var secondLegUse = uses.getFirst(); assertEquals(tenDollars, secondLegUse.product().price()); // the same far product is used for both legs as you only need to buy one diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index c0daa7bd3c0..04836ea2b52 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -172,16 +172,11 @@ void multipleFeedsWithTransfersWithinFeed() { .build(); var result = service.calculateFares(itin); - var resultComponents = result - .getLegProducts() - .values() - .stream() - .map(r -> r.product().id()) - .toList(); + var legProducts = result.getLegProducts().values().stream().map(r -> r.product().id()).toList(); assertEquals( List.of(INSIDE_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()), - resultComponents + legProducts ); var resultPrice = result.getFare(FareType.regular); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java index a094a01412b..ae78a820661 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.ext.fares.impl; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; @@ -7,7 +8,6 @@ import java.util.LinkedList; import java.util.List; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -38,7 +38,7 @@ public void canCalculateHSLFares( Itinerary i, List expectedFareIds ) { - Assertions.assertArrayEquals( + assertArrayEquals( expectedFareIds.toArray(), fareService .calculateFares(i) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java index 48dd6b520c5..0e667f1b986 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java @@ -46,7 +46,7 @@ public void canCalculateFare( assertEquals(expectedFare, fares.getFare(FareType.regular)); for (var type : fares.getFareTypes()) { - assertFalse(fares.getLegProducts().isEmpty()); + assertFalse(fares.getItineraryProducts().isEmpty()); var prices = fares .getItineraryProducts() From f2bcbb4b258e07fa71bc5a4d5b165ec1d81c39c9 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 10:53:14 +0100 Subject: [PATCH 110/356] Fix price calculation of combined interlined legs --- .../ext/fares/impl/DefaultFareService.java | 23 +++++++------------ .../model/fare/ItineraryFares.java | 2 +- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index a39ccebe0e7..f0d957bf4ff 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -148,11 +148,6 @@ public ItineraryFares calculateFares(Itinerary itinerary) { fareProducts.putAll(currentFare.getLegProducts()); fare.addFare(fareType, currentFare.getFare(fareType)); - currentFare - .getLegProducts() - .entries() - .forEach(entry -> fare.addFareProduct(entry.getKey(), entry.getValue().product())); - fares.add(currentFare.getFare(fareType)); // If all the legs are from one feed, consider itinerary products @@ -246,7 +241,7 @@ protected boolean populateFare( ) { FareSearch r = performSearch(fareType, legs, fareRules); - Multimap legProducts = LinkedHashMultimap.create(); + Multimap fareProductUses = LinkedHashMultimap.create(); int count = 0; int start = 0; int end = legs.size() - 1; @@ -263,34 +258,32 @@ protected boolean populateFare( int via = r.next[start][r.endOfComponent[start]]; float cost = r.resultTable[start][via]; FeedScopedId fareId = r.fareIds[start][via]; + var product = FareProduct + .of(fareId, fareId.toString(), Money.ofFractionalAmount(currency, cost)) + .build(); - var componentLegs = new ArrayList(); for (int i = start; i <= via; ++i) { final var leg = legs.get(i); + final var use = new FareProductUse(product.uniqueInstanceId(leg.getStartTime()), product); // if we have a leg that is combined for the purpose of fare calculation we need to // retrieve the original legs so that the fare products are assigned back to the original // legs that the combined one originally consisted of. // (remember that the combined leg only exists during fare calculation and is thrown away // afterwards to associating fare products with it will result in the API not showing any.) if (leg instanceof CombinedInterlinedTransitLeg combinedLeg) { - componentLegs.addAll(combinedLeg.originalLegs()); + combinedLeg.originalLegs().forEach(l -> fareProductUses.put(l, use)); } else { - componentLegs.add(leg); + fareProductUses.put(leg, use); } } - var product = FareProduct - .of(fareId, fareId.toString(), Money.ofFractionalAmount(currency, cost)) - .build(); - componentLegs.forEach(l -> legProducts.put(l, product)); - ++count; start = via + 1; } var amount = r.resultTable[0][legs.size() - 1]; fare.addFare(fareType, Money.ofFractionalAmount(currency, amount)); - fare.addFareProducts(legProducts); + fare.addFareProductUses(fareProductUses); return count > 0; } diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 3443c01a062..8bb3e349b60 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -149,7 +149,7 @@ public void addFareProduct(Leg leg, Collection fareProduct) { } public void addFareProducts(Multimap fareProducts) { - fareProducts.forEach((leg, fp) -> addFareProduct(leg, fp)); + fareProducts.forEach(this::addFareProduct); } public void addFareProductUses(Multimap fareProducts) { From 55ee6fff8f0b27347b99fcc0e226548f4e15f149 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 11:38:19 +0100 Subject: [PATCH 111/356] Update expecations for mulitple feed fares --- .../ext/fares/impl/DefaultFareServiceTest.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 04836ea2b52..3111b584ec8 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -172,11 +172,23 @@ void multipleFeedsWithTransfersWithinFeed() { .build(); var result = service.calculateFares(itin); - var legProducts = result.getLegProducts().values().stream().map(r -> r.product().id()).toList(); + var legProducts = result.getLegProducts(); + var firstBusLeg = itin.getTransitLeg(0); + var secondBusLeg = itin.getTransitLeg(2); + var finalBusLeg = itin.getTransitLeg(4); + + assertEquals( + "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + legProducts.get(firstBusLeg).toString() + ); + assertEquals( + "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + legProducts.get(secondBusLeg).toString() + ); assertEquals( - List.of(INSIDE_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()), - legProducts + "[FareProductUse[id=678d201c-e839-35c3-ae7b-1bc3834da5e5, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + legProducts.get(finalBusLeg).toString() ); var resultPrice = result.getFare(FareType.regular); From af5d0497752cc622f2511d750427647b5ad13675 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 12:09:11 +0100 Subject: [PATCH 112/356] Update assertions for HSL fares --- .../org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java | 2 +- .../impl/HighestFareInFreeTransferWindowFareServiceTest.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java index ae78a820661..4e1347cae16 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java @@ -382,7 +382,7 @@ private static List createTestCases() { "Bus ride within zone A, then another one outside of HSL's area", hslFareService, A1_A2_F, - List.of(fareAttributeAB.getId()) + List.of(fareAttributeAB.getId(), fareAttributeAB.getId()) ) ); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java index 0e667f1b986..5664dcc765d 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java @@ -44,10 +44,9 @@ public void canCalculateFare( ) { var fares = fareService.calculateFares(i); assertEquals(expectedFare, fares.getFare(FareType.regular)); + assertFalse(fares.getItineraryProducts().isEmpty()); for (var type : fares.getFareTypes()) { - assertFalse(fares.getItineraryProducts().isEmpty()); - var prices = fares .getItineraryProducts() .stream() From 6527828515b7902dfe4cfcb6840796abdc351795 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 12:33:31 +0100 Subject: [PATCH 113/356] Remove 'component' from variable names --- .../ext/fares/impl/DefaultFareServiceTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 3111b584ec8..f306b61ee50 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -87,15 +87,15 @@ void shouldNotCombineInterlinedLegs() { assertEquals(TWENTY_DOLLARS, price); - var legProductsFromComponents = fare.getLegProducts(); + var legProducts = fare.getLegProducts(); var firstLeg = itin.getLegs().get(0); - var products = List.copyOf(legProductsFromComponents.get(firstLeg)); + var products = List.copyOf(legProducts.get(firstLeg)); assertEquals(TEN_DOLLARS, products.get(0).product().price()); var secondLeg = itin.getLegs().get(1); - products = List.copyOf(legProductsFromComponents.get(secondLeg)); + products = List.copyOf(legProducts.get(secondLeg)); assertEquals(TEN_DOLLARS, products.get(0).product().price()); assertEquals(1, fare.getItineraryProducts().size()); @@ -143,7 +143,7 @@ void multipleFeeds() { .build(); var result = service.calculateFares(itin); - var resultComponents = result + var fareProductIds = result .getLegProducts() .values() .stream() @@ -152,7 +152,7 @@ void multipleFeeds() { assertEquals( List.of(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()), - resultComponents + fareProductIds ); var resultPrice = result.getFare(FareType.regular); @@ -205,14 +205,14 @@ void multipleFeedsWithUnknownFareLegs() { .bus(OTHER_FEED_ROUTE, 2, T11_20, T11_32, Place.forStop(OTHER_FEED_STOP)) .build(); var result = service.calculateFares(itin); - var resultComponents = result + var resultProductIds = result .getLegProducts() .values() .stream() .map(r -> r.product().id()) .toList(); var resultPrice = result.getFare(FareType.regular); - assertEquals(List.of(OTHER_FEED_ATTRIBUTE.getId()), resultComponents); + assertEquals(List.of(OTHER_FEED_ATTRIBUTE.getId()), resultProductIds); assertEquals(Money.usDollars(-0.01f), resultPrice); } } From cc317540655a8d930698a01cad6810912b6a5991 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 12:47:50 +0100 Subject: [PATCH 114/356] Simplify mapping code --- .../opentripplanner/ext/restapi/mapping/FareMapper.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java index 7eb0d26339e..e8582607ce5 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java @@ -11,7 +11,6 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import org.opentripplanner.ext.restapi.model.ApiCurrency; -import org.opentripplanner.ext.restapi.model.ApiFareComponent; import org.opentripplanner.ext.restapi.model.ApiFareProduct; import org.opentripplanner.ext.restapi.model.ApiFareQualifier; import org.opentripplanner.ext.restapi.model.ApiItineraryFares; @@ -37,11 +36,10 @@ public FareMapper(Locale locale) { public ApiItineraryFares mapFare(Itinerary itinerary) { var fares = itinerary.getFares(); Map apiFare = toApiMoneys(fares); - Map> apiComponent = toApiFareComponents(fares); return new ApiItineraryFares( apiFare, - apiComponent, + Map.of(), toApiFareProducts(fares.getItineraryProducts()), toApiLegProducts(itinerary, fares.getLegProducts()) ); @@ -104,10 +102,6 @@ private List toApiFareProducts(Collection product) } } - private Map> toApiFareComponents(ItineraryFares fare) { - return Map.of(); - } - private Map toApiMoneys(ItineraryFares fare) { return fare .getFareTypes() From 8c14a6fd6cbf4939be58f41dc61dbd426a84caca Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 10 Jan 2024 14:35:10 +0100 Subject: [PATCH 115/356] Clean up --- .../org/opentripplanner/ext/fares/impl/OrcaFareService.java | 4 ---- .../org/opentripplanner/ext/fares/impl/OrcaFaresData.java | 2 -- .../java/org/opentripplanner/model/fare/ItineraryFares.java | 4 ---- 3 files changed, 10 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java index 42736472767..4879d858e86 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java @@ -23,13 +23,9 @@ import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class OrcaFareService extends DefaultFareService { - private static final Logger LOG = LoggerFactory.getLogger(OrcaFareService.class); - private static final Duration MAX_TRANSFER_DISCOUNT_DURATION = Duration.ofHours(2); public static final String COMM_TRANS_AGENCY_ID = "29"; diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java index e970cb51718..acef59a7c03 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFaresData.java @@ -1,7 +1,5 @@ package org.opentripplanner.ext.fares.impl; -import static org.opentripplanner.transit.model.basic.Money.USD; - import java.util.Map; import org.opentripplanner.routing.core.FareType; import org.opentripplanner.transit.model.basic.Money; diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 8bb3e349b60..80af574636a 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -148,10 +148,6 @@ public void addFareProduct(Leg leg, Collection fareProduct) { fareProduct.forEach(fp -> addFareProduct(leg, fp)); } - public void addFareProducts(Multimap fareProducts) { - fareProducts.forEach(this::addFareProduct); - } - public void addFareProductUses(Multimap fareProducts) { legProducts.putAll(fareProducts); } From 060e210ec8a7609721f3b07f19388cb6a0af77b0 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 11 Jan 2024 14:01:27 +0100 Subject: [PATCH 116/356] refactor: Convert RemoveItinerariesWithShortStreetLeg to RemoveItineraryFlagger. This also fixes a minor bug. The filter did not plug into framework, hence would not show up when using the filter chain debug freature. --- .../ItineraryListFilterChainBuilder.java | 4 ++-- .../RemoveItinerariesWithShortStreetLeg.java | 23 +++++++++++------- ...moveItinerariesWithShortStreetLegTest.java | 24 +++++++++---------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index ec14286e6ca..e8b8ed43c1c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -382,8 +382,8 @@ public ItineraryListFilterChain build() { } if (minBikeParkingDistance > 0) { - // TODO: use addRmFilter() here - filters.add( + addRemoveFilter( + filters, new RemoveItinerariesWithShortStreetLeg(minBikeParkingDistance, TraverseMode.BICYCLE) ); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java index 3f587840690..0014d8925a9 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java @@ -1,9 +1,9 @@ package org.opentripplanner.routing.algorithm.filterchain.filters.transit; -import java.util.List; +import java.util.function.Predicate; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.street.search.TraverseMode; /** @@ -18,10 +18,10 @@ * to reach a train station. A user would not expect to see a bike+transit shorted than 200m leg when it's * presented right next to a walk+transit leg of the same length. *

      - * In other words, this offloads the comparison part of the filter chain to a system outside of OTP and + * In other words, this offloads the comparison part of the filter chain to a system outside of OTP and * that is the reason for this non-standard approach. */ -public class RemoveItinerariesWithShortStreetLeg implements ItineraryListFilter { +public class RemoveItinerariesWithShortStreetLeg implements RemoveItineraryFlagger { private final double minDistance; private final TraverseMode traverseMode; @@ -32,11 +32,16 @@ public RemoveItinerariesWithShortStreetLeg(double minDistance, TraverseMode trav } @Override - public List filter(List itineraries) { - return itineraries.stream().filter(this::filterItinerariesWithShortStreetLeg).toList(); + public String name() { + return "remove-itineraries-with-short-street-leg"; } - private boolean filterItinerariesWithShortStreetLeg(Itinerary itinerary) { + @Override + public Predicate shouldBeFlaggedForRemoval() { + return this::removeItineraryWithShortStreetLeg; + } + + private boolean removeItineraryWithShortStreetLeg(Itinerary itinerary) { var hasLegsOfMode = itinerary.getStreetLegs().anyMatch(l -> l.getMode().equals(traverseMode)); if (hasLegsOfMode && itinerary.hasTransit()) { var distance = itinerary @@ -45,9 +50,9 @@ private boolean filterItinerariesWithShortStreetLeg(Itinerary itinerary) { .mapToDouble(Leg::getDistanceMeters) .sum(); - return distance > minDistance; + return distance <= minDistance; } else { - return true; + return false; } } } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java index 7949b6ab086..92a11485055 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLegTest.java @@ -1,16 +1,17 @@ package org.opentripplanner.routing.algorithm.filterchain.filters.transit; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import static org.opentripplanner.street.search.TraverseMode.BICYCLE; -import java.util.List; import org.junit.jupiter.api.Test; import org.opentripplanner.model.plan.PlanTestConstants; class RemoveItinerariesWithShortStreetLegTest implements PlanTestConstants { - RemoveItinerariesWithShortStreetLeg filter = new RemoveItinerariesWithShortStreetLeg( + private final RemoveItinerariesWithShortStreetLeg subject = new RemoveItinerariesWithShortStreetLeg( 500, BICYCLE ); @@ -19,16 +20,15 @@ class RemoveItinerariesWithShortStreetLegTest implements PlanTestConstants { void noBikeDoesNothing() { var regularTransit = newItinerary(A).bus(30, T11_16, T11_20, C).build(); - var result = filter.filter(List.of(regularTransit, regularTransit, regularTransit)); - assertEquals(List.of(regularTransit, regularTransit, regularTransit), result); + assertFalse(subject.shouldBeFlaggedForRemoval().test(regularTransit), regularTransit.toStr()); } @Test void justBikeDoesNothing() { var itin = newItinerary(A).bicycle(T11_05, T11_06, B).build(); assertEquals(300, itin.getLegs().get(0).getDistanceMeters()); - var result = filter.filter(List.of(itin)); - assertEquals(List.of(itin), result); + + assertFalse(subject.shouldBeFlaggedForRemoval().test(itin), itin.toStr()); } @Test @@ -36,23 +36,23 @@ void zeroMinDoesNothing() { var filter = new RemoveItinerariesWithShortStreetLeg(0, BICYCLE); var itin = newItinerary(A).bicycle(T11_05, T11_06, B).rail(30, T11_16, T11_20, C).build(); assertEquals(300, itin.getLegs().get(0).getDistanceMeters()); - var result = filter.filter(List.of(itin)); - assertEquals(List.of(itin), result); + + assertFalse(filter.shouldBeFlaggedForRemoval().test(itin), itin.toStr()); } @Test void shortBike() { var itin = newItinerary(A).bicycle(T11_05, T11_06, B).rail(30, T11_16, T11_20, C).build(); assertEquals(300, itin.getLegs().get(0).getDistanceMeters()); - var result = filter.filter(List.of(itin, itin, itin)); - assertEquals(List.of(), result); + + assertTrue(subject.shouldBeFlaggedForRemoval().test(itin), itin.toStr()); } @Test void longBike() { var itin = newItinerary(A).bicycle(T11_05, T11_30, B).rail(30, T11_33, T11_50, C).build(); assertEquals(7500, itin.getLegs().get(0).getDistanceMeters()); - var result = filter.filter(List.of(itin, itin)); - assertEquals(List.of(itin, itin), result); + + assertFalse(subject.shouldBeFlaggedForRemoval().test(itin), itin.toStr()); } } From c4eb78c44f87c5668e9d26cbe91e0ce95a7851c2 Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 11 Jan 2024 13:07:49 +0000 Subject: [PATCH 117/356] Upgrade debug client to version 2024/01/2024-01-11T13:07 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index dfb4915efcc..d9bf3a2af16 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +

      From 24d5929747795ab39bb820683ceb3d51a6fabeea Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 14:33:38 +0100 Subject: [PATCH 118/356] Remove extra function definition --- client-next/src/components/MapView/MapView.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 1b17e31cb88..57e718ff187 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -39,7 +39,6 @@ export function MapView({ e: mapboxgl.MapMouseEvent & { features?: mapboxgl.MapboxGeoJSONFeature[] | undefined; }, - setShowPropsPopup: (value: ((prevState: PopupData | null) => PopupData | null) | PopupData | null) => void, ) => { if (e.features) { // if you click on a cluster of map features it's possible that there are multiple @@ -64,7 +63,7 @@ export function MapView({ }} interactiveLayerIds={['regular-stop']} onClick={(e) => { - showFeaturePropPopup(e, setShowPropsPopup); + showFeaturePropPopup(e); }} // put lat/long in URL and pan to it on page reload hash={true} From b59ca33166f0ded3acabcebd43e84c401c48ca9e Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 11 Jan 2024 15:18:16 +0100 Subject: [PATCH 119/356] doc: Update package documentation for the itinerary filter chain --- .../ItineraryListFilterChain.excalidraw | 721 +++++++++++++----- .../images/ItineraryListFilterChain.svg | 11 +- .../routing/algorithm/filterchain/package.md | 41 +- 3 files changed, 564 insertions(+), 209 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw index 3c1701f2dba..76c71874be5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw @@ -5,8 +5,8 @@ "elements": [ { "type": "arrow", - "version": 2390, - "versionNonce": 369632805, + "version": 2479, + "versionNonce": 2086276447, "isDeleted": false, "id": "uTKhXBXl80XXPjGsftdJa", "fillStyle": "hachure", @@ -15,16 +15,22 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 566.848335090324, + "x": 564.2990304950548, "y": 564.1295357290845, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 3.2043051907536437, - "height": 74.45005932341121, + "width": 0.35168042093721397, + "height": 74.3498281379907, "seed": 1822339590, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982418479, + "link": null, + "locked": false, "startBinding": { "elementId": "M76RD0PeJrkYP9LuS_Kxu", "gap": 6.688129479084512, @@ -44,15 +50,15 @@ 0 ], [ - 3.2043051907536437, - 74.45005932341121 + -0.35168042093721397, + 74.3498281379907 ] ] }, { "type": "ellipse", - "version": 919, - "versionNonce": 1250982571, + "version": 964, + "versionNonce": 465602847, "isDeleted": false, "id": "oV4YIjz-w-0HS_dvr7ZoB", "fillStyle": "hachure", @@ -61,23 +67,30 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 438.08984375, + "x": 411.91796875, "y": 643.015625, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 274.64453125, - "height": 282.50781250000006, + "width": 300.81640625000006, + "height": 317.625, "seed": 1296092422, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "uTKhXBXl80XXPjGsftdJa" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "uTKhXBXl80XXPjGsftdJa" + } + ], + "updated": 1704982418479, + "link": null, + "locked": false }, { "type": "ellipse", - "version": 138, - "versionNonce": 1712254071, + "version": 139, + "versionNonce": 297704337, "isDeleted": false, "id": "iXHhu1-MD9tXNfoZZ8Rcq", "fillStyle": "hachure", @@ -94,15 +107,22 @@ "height": 170.08984375, "seed": 1752922886, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "i6hMn3CPVbRxyPcniV7yb" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "i6hMn3CPVbRxyPcniV7yb" + } + ], + "updated": 1704982135037, + "link": null, + "locked": false }, { "type": "arrow", - "version": 362, - "versionNonce": 1362745241, + "version": 363, + "versionNonce": 1672962559, "isDeleted": false, "id": "i6hMn3CPVbRxyPcniV7yb", "fillStyle": "hachure", @@ -119,8 +139,14 @@ "height": 79.85129297487731, "seed": 398792602, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "startBinding": { "elementId": "NLnBzR8OLk5gbeRQGwI9f", "focus": -0.18252063102968885, @@ -147,8 +173,8 @@ }, { "type": "text", - "version": 91, - "versionNonce": 839585881, + "version": 108, + "versionNonce": 2108178065, "isDeleted": false, "id": "nJRU39yv_4LYhT-kVxv_t", "fillStyle": "hachure", @@ -157,27 +183,34 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 760.2421875, - "y": 705.248046875, + "x": 754.1171875, + "y": 708.740234375, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 113, + "width": 112.73989868164062, "height": 50, "seed": 1641529222, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982458252, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Comparator\n", - "baseline": 43, "textAlign": "center", - "verticalAlign": "middle" + "verticalAlign": "middle", + "containerId": null, + "originalText": "Comparator\n", + "lineHeight": 1.25, + "baseline": 43 }, { "type": "text", - "version": 259, - "versionNonce": 505668230, + "version": 260, + "versionNonce": 1872284191, "isDeleted": false, "id": "D8AYLA3h4ksepFAEqkC7G", "fillStyle": "hachure", @@ -194,19 +227,26 @@ "height": 50, "seed": 1478178009, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "ItineraryList\nFilterChain", - "baseline": 43, "textAlign": "center", - "verticalAlign": "top" + "verticalAlign": "top", + "containerId": null, + "originalText": "ItineraryList\nFilterChain", + "lineHeight": 1.25, + "baseline": 43 }, { "type": "arrow", - "version": 589, - "versionNonce": 1147854854, + "version": 590, + "versionNonce": 180857681, "isDeleted": false, "id": "abNnvFw7GnSsRXaqnRUYs", "fillStyle": "hachure", @@ -223,8 +263,14 @@ "height": 6.933497082758379, "seed": 273649111, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "startBinding": { "elementId": "bA4uoIjQQ5b7VTjNXnYCH", "focus": 0.083136294577077, @@ -251,8 +297,8 @@ }, { "type": "rectangle", - "version": 179, - "versionNonce": 1070362266, + "version": 180, + "versionNonce": 660090431, "isDeleted": false, "id": "bA4uoIjQQ5b7VTjNXnYCH", "fillStyle": "hachure", @@ -269,15 +315,22 @@ "height": 88.37109375, "seed": 1943497081, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "abNnvFw7GnSsRXaqnRUYs" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "abNnvFw7GnSsRXaqnRUYs" + } + ], + "updated": 1704982135037, + "link": null, + "locked": false }, { "type": "text", - "version": 138, - "versionNonce": 463485399, + "version": 139, + "versionNonce": 1010309425, "isDeleted": false, "id": "A4ZjgRaXH3lARCAtxxyGH", "fillStyle": "hachure", @@ -294,19 +347,26 @@ "height": 25, "seed": 770881047, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "*", - "baseline": 18, "textAlign": "left", - "verticalAlign": "top" + "verticalAlign": "top", + "containerId": null, + "originalText": "*", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "line", - "version": 130, - "versionNonce": 1350932407, + "version": 131, + "versionNonce": 1440091743, "isDeleted": false, "id": "xPF7fs9PPAG3FCbgCedlx", "fillStyle": "hachure", @@ -323,8 +383,14 @@ "height": 54.202357687428616, "seed": 1466164567, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "startBinding": null, "endBinding": null, "lastCommittedPoint": null, @@ -343,8 +409,8 @@ }, { "type": "freedraw", - "version": 165, - "versionNonce": 164708486, + "version": 166, + "versionNonce": 622840593, "isDeleted": false, "id": "v7Du5WLNb590wL5Uam6Ta", "fillStyle": "hachure", @@ -361,8 +427,14 @@ "height": 19.62890625, "seed": 571266967, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "points": [ [ 0, @@ -608,8 +680,8 @@ }, { "type": "rectangle", - "version": 213, - "versionNonce": 363355223, + "version": 214, + "versionNonce": 367192703, "isDeleted": false, "id": "bXMUStvEb709SPfYF07CW", "fillStyle": "hachure", @@ -626,21 +698,26 @@ "height": 136.52343750000003, "seed": 1747224151, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "abNnvFw7GnSsRXaqnRUYs", - "DNUdRQjUxwIlQOGRroKjy", - "pRACykcqHnF03bgQc5Tc7", - "sBj3XDz6N2sSDfDg1hlEA", - "5o3WS1bjYB_SRMLHGEwV1", - "Qt7CHy0OYZwkEloLT2tU-", - "hhODwDUSnKDNHxeWgdBRh" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "abNnvFw7GnSsRXaqnRUYs" + }, + { + "type": "arrow", + "id": "hhODwDUSnKDNHxeWgdBRh" + } + ], + "updated": 1704982135037, + "link": null, + "locked": false }, { "type": "arrow", - "version": 638, - "versionNonce": 1491667819, + "version": 639, + "versionNonce": 1576419569, "isDeleted": false, "id": "hhODwDUSnKDNHxeWgdBRh", "fillStyle": "hachure", @@ -657,8 +734,14 @@ "height": 236.4110879594133, "seed": 413129015, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "startBinding": { "elementId": "gL_hDnXZ2lRjaViYaG2rV", "gap": 4.0451591623761765, @@ -693,8 +776,8 @@ }, { "type": "text", - "version": 119, - "versionNonce": 992742379, + "version": 120, + "versionNonce": 1413431967, "isDeleted": false, "id": "svSoLS4U9UhcZVccLd8Kz", "fillStyle": "hachure", @@ -711,22 +794,31 @@ "height": 75, "seed": 736680902, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "PigWa1tRUEcK9ZGLifHF3", - "hhODwDUSnKDNHxeWgdBRh" + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "hhODwDUSnKDNHxeWgdBRh" + } ], + "updated": 1704982135037, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "GroupByFilter\n\n", - "baseline": 68, "textAlign": "center", - "verticalAlign": "top" + "verticalAlign": "top", + "containerId": null, + "originalText": "GroupByFilter\n\n", + "lineHeight": 1.25, + "baseline": 68 }, { "type": "ellipse", - "version": 233, - "versionNonce": 461103578, + "version": 234, + "versionNonce": 71498449, "isDeleted": false, "id": "1H3J1TVatGqsTmeb03PzM", "fillStyle": "hachure", @@ -743,13 +835,17 @@ "height": 21.5234375, "seed": 145370007, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [] + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false }, { "type": "text", - "version": 541, - "versionNonce": 1246878711, + "version": 542, + "versionNonce": 295409343, "isDeleted": false, "id": "eMUtrGSf4_tdjT-SgVl6r", "fillStyle": "hachure", @@ -766,19 +862,26 @@ "height": 25, "seed": 276931526, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "nestedFilters", - "baseline": 18, "textAlign": "left", - "verticalAlign": "top" + "verticalAlign": "top", + "containerId": null, + "originalText": "nestedFilters", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "text", - "version": 199, - "versionNonce": 1740659001, + "version": 200, + "versionNonce": 412973233, "isDeleted": false, "id": "I00FPxjJzkybs748xvxYQ", "fillStyle": "hachure", @@ -795,21 +898,26 @@ "height": 25, "seed": 654279366, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "Qt7CHy0OYZwkEloLT2tU-" - ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135037, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "*", - "baseline": 18, "textAlign": "left", - "verticalAlign": "top" + "verticalAlign": "top", + "containerId": null, + "originalText": "*", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "text", - "version": 115, - "versionNonce": 1382233690, + "version": 116, + "versionNonce": 1687709407, "isDeleted": false, "id": "MNcWXxi6VbZaulu3K670q", "fillStyle": "hachure", @@ -826,19 +934,26 @@ "height": 75, "seed": 1687297177, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Itinarary\nList\nFilter", - "baseline": 68, "textAlign": "center", - "verticalAlign": "middle" + "verticalAlign": "middle", + "containerId": null, + "originalText": "Itinarary\nList\nFilter", + "lineHeight": 1.25, + "baseline": 68 }, { "type": "rectangle", - "version": 495, - "versionNonce": 1318057157, + "version": 496, + "versionNonce": 481114769, "isDeleted": false, "id": "gL_hDnXZ2lRjaViYaG2rV", "fillStyle": "hachure", @@ -855,19 +970,22 @@ "height": 98.89843749999999, "seed": 1515944921, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "pRACykcqHnF03bgQc5Tc7", - "sBj3XDz6N2sSDfDg1hlEA", - "5o3WS1bjYB_SRMLHGEwV1", - "Qt7CHy0OYZwkEloLT2tU-", - "hhODwDUSnKDNHxeWgdBRh" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "hhODwDUSnKDNHxeWgdBRh" + } + ], + "updated": 1704982135038, + "link": null, + "locked": false }, { "type": "line", - "version": 119, - "versionNonce": 311957830, + "version": 120, + "versionNonce": 1002844927, "isDeleted": false, "id": "gF_BvGrwKBQV_s0LLt7II", "fillStyle": "hachure", @@ -884,8 +1002,14 @@ "height": 65.39966988721864, "seed": 810609625, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "startBinding": null, "endBinding": null, "lastCommittedPoint": null, @@ -904,8 +1028,8 @@ }, { "type": "line", - "version": 89, - "versionNonce": 9693367, + "version": 90, + "versionNonce": 1898561649, "isDeleted": false, "id": "6V31n7Wzh9bRD4MWf72QE", "fillStyle": "hachure", @@ -922,8 +1046,14 @@ "height": 79.91170934028924, "seed": 641892473, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "startBinding": null, "endBinding": null, "lastCommittedPoint": null, @@ -942,8 +1072,8 @@ }, { "type": "line", - "version": 151, - "versionNonce": 651803289, + "version": 152, + "versionNonce": 1604680479, "isDeleted": false, "id": "jItuiRV-cqbnZuN1BUg5k", "fillStyle": "hachure", @@ -960,8 +1090,14 @@ "height": 66.58413111448289, "seed": 583293079, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "startBinding": null, "endBinding": null, "lastCommittedPoint": null, @@ -980,8 +1116,8 @@ }, { "type": "line", - "version": 122, - "versionNonce": 312292279, + "version": 123, + "versionNonce": 1943702097, "isDeleted": false, "id": "YXFr7rhGIICmJAWKZ5eUK", "fillStyle": "hachure", @@ -998,8 +1134,14 @@ "height": 60.49037211317568, "seed": 2016803833, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "startBinding": null, "endBinding": null, "lastCommittedPoint": null, @@ -1018,8 +1160,8 @@ }, { "type": "rectangle", - "version": 355, - "versionNonce": 2063763525, + "version": 356, + "versionNonce": 883343167, "isDeleted": false, "id": "M76RD0PeJrkYP9LuS_Kxu", "fillStyle": "hachure", @@ -1036,16 +1178,22 @@ "height": 95.359375, "seed": 1486134679, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "DNUdRQjUxwIlQOGRroKjy", - "uTKhXBXl80XXPjGsftdJa" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "uTKhXBXl80XXPjGsftdJa" + } + ], + "updated": 1704982135038, + "link": null, + "locked": false }, { "type": "rectangle", - "version": 132, - "versionNonce": 662378169, + "version": 133, + "versionNonce": 1570183217, "isDeleted": false, "id": "NLnBzR8OLk5gbeRQGwI9f", "fillStyle": "hachure", @@ -1062,16 +1210,22 @@ "height": 95.359375, "seed": 1267074617, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [ - "ZiK53Ibs5EcfnOH3MWUmX", - "i6hMn3CPVbRxyPcniV7yb" - ] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "i6hMn3CPVbRxyPcniV7yb" + } + ], + "updated": 1704982135038, + "link": null, + "locked": false }, { "type": "text", - "version": 76, - "versionNonce": 206050586, + "version": 80, + "versionNonce": 448341841, "isDeleted": false, "id": "QxjDVUdnC9uReskEwKjsd", "fillStyle": "hachure", @@ -1080,27 +1234,39 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1183.578125, + "x": 1189.9781188964844, "y": 506.0703125, "strokeColor": "#000000", "backgroundColor": "#868e96", - "width": 157, + "width": 143.79986572265625, "height": 25, "seed": 2048669126, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "3FvznihDEqVpPp0WjjZ26", + "type": "arrow" + } + ], + "updated": 1704982138417, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, - "text": "DecoratingFilter", - "baseline": 18, + "text": "DecorateFilter", "textAlign": "center", - "verticalAlign": "middle" + "verticalAlign": "middle", + "containerId": null, + "originalText": "DecorateFilter", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "text", - "version": 77, - "versionNonce": 1299176613, + "version": 80, + "versionNonce": 1615260177, "isDeleted": false, "id": "zcbS0wgQbYVDRmrAUTDaV", "fillStyle": "hachure", @@ -1109,27 +1275,34 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 467.625, + "x": 509.32505798339844, "y": 500.16796875, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 205, + "width": 121.59988403320312, "height": 25, "seed": 1535284294, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, - "text": "DeletionFlaggingFilter", - "baseline": 18, + "text": "RemoveFilter", "textAlign": "center", - "verticalAlign": "top" + "verticalAlign": "top", + "containerId": null, + "originalText": "RemoveFilter", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 224, - "versionNonce": 1434841862, + "version": 226, + "versionNonce": 832812785, "isDeleted": false, "id": "sVoxOi_goA0Vz9JvN_EuG", "fillStyle": "hachure", @@ -1146,13 +1319,22 @@ "height": 95.359375, "seed": 1742969881, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [] + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "3FvznihDEqVpPp0WjjZ26", + "type": "arrow" + } + ], + "updated": 1704982142587, + "link": null, + "locked": false }, { "type": "text", - "version": 71, - "versionNonce": 617977913, + "version": 72, + "versionNonce": 81887217, "isDeleted": false, "id": "5bXiMRSAbkBVDNzuMHYjg", "fillStyle": "hachure", @@ -1169,19 +1351,26 @@ "height": 25, "seed": 926646726, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, "text": "SortingFilter", - "baseline": 18, "textAlign": "center", - "verticalAlign": "middle" + "verticalAlign": "middle", + "containerId": null, + "originalText": "SortingFilter", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "line", - "version": 154, - "versionNonce": 182849495, + "version": 155, + "versionNonce": 1407939487, "isDeleted": false, "id": "Ugnzj7K6hXFkke4frMlUY", "fillStyle": "hachure", @@ -1198,8 +1387,14 @@ "height": 3.082508331146073, "seed": 787790041, "groupIds": [], - "strokeSharpness": "round", - "boundElementIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982135038, + "link": null, + "locked": false, "startBinding": null, "endBinding": null, "lastCommittedPoint": null, @@ -1218,8 +1413,8 @@ }, { "type": "text", - "version": 451, - "versionNonce": 768155173, + "version": 681, + "versionNonce": 1609777361, "isDeleted": false, "id": "5pmOYWhziuLQ_DZANfOzI", "fillStyle": "hachure", @@ -1228,26 +1423,154 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 487.65625, - "y": 677.744140625, + "x": 418.52866278754334, + "y": 718.146484375, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 179, - "height": 225, + "width": 289.0015563964844, + "height": 145.5729166666666, "seed": 2016628486, "groupIds": [], - "strokeSharpness": "sharp", - "boundElementIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982452010, + "link": null, + "locked": false, + "fontSize": 19.409722222222214, + "fontFamily": 1, + "text": "RemoveItineraryFlagger\n---\nname()\nshouldBeFlaggedForRemoval()\nskipAlreadyFlaggedItineraries()\n", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "RemoveItineraryFlagger\n---\nname()\nshouldBeFlaggedForRemoval()\nskipAlreadyFlaggedItineraries()\n", + "lineHeight": 1.25, + "baseline": 138 + }, + { + "type": "ellipse", + "version": 377, + "versionNonce": 1136001105, + "isDeleted": false, + "id": "-Wb1113k5o16q_0IwIAB8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1156.7592311487206, + "y": 671.1135670590127, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 208.52734375, + "height": 199.65234375000003, + "seed": 1166357119, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "arrow", + "id": "3FvznihDEqVpPp0WjjZ26" + } + ], + "updated": 1704982236097, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 907, + "versionNonce": 1010622481, + "isDeleted": false, + "id": "3FvznihDEqVpPp0WjjZ26", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1258.7430659828142, + "y": 573.1253432215196, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 1.9333557957434095, + "height": 93.76169170168737, + "seed": 1750633119, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1704982236097, + "link": null, + "locked": false, + "startBinding": { + "elementId": "sVoxOi_goA0Vz9JvN_EuG", + "gap": 4.390968221519643, + "focus": 0.06426443161706548 + }, + "endBinding": { + "elementId": "-Wb1113k5o16q_0IwIAB8", + "gap": 4.227062776875528, + "focus": 0.017251680890168403 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 1.9333557957434095, + 93.76169170168737 + ] + ] + }, + { + "type": "text", + "version": 396, + "versionNonce": 8009937, + "isDeleted": false, + "id": "mO-wquP1JTkteitq9b6D4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1165.4773936853417, + "y": 728.7756764340127, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 189.45982360839844, + "height": 75, + "seed": 1665916607, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1704982474848, + "link": null, + "locked": false, "fontSize": 20, "fontFamily": 1, - "text": "Itinerary\nDeletionFlagger\n-------\npredicate()\ngetFlagged\nItineraries(List)\nskipAlreadyFlagged\nItineraries()\n", - "baseline": 218, + "text": "ItineraryDecorator\n---\ndecorate(Itinerary)", "textAlign": "center", - "verticalAlign": "top" + "verticalAlign": "middle", + "containerId": null, + "originalText": "ItineraryDecorator\n---\ndecorate(Itinerary)", + "lineHeight": 1.25, + "baseline": 68 } ], "appState": { "gridSize": null, "viewBackgroundColor": "#ffffff" - } + }, + "files": {} } \ No newline at end of file diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg index 06f65809fab..087866ea971 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg @@ -1,8 +1,8 @@ - + - - Comparator<Itinerary>ItineraryListFilterChain*GroupByFilter<GroupId>nestedFilters*ItinararyListFilterDecoratingFilterDeletionFlaggingFilterSortingFilterItineraryDeletionFlagger-------predicate()getFlaggedItineraries(List)skipAlreadyFlaggedItineraries() \ No newline at end of file + Comparator<Itinerary>ItineraryListFilterChain*GroupByFilter<GroupId>nestedFilters*ItinararyListFilterDecorateFilterRemoveFilterSortingFilterRemoveItineraryFlagger---name()shouldBeFlaggedForRemoval()skipAlreadyFlaggedItineraries()ItineraryDecorator---decorate(Itinerary) \ No newline at end of file diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md index 7441e5f0849..ed8ca0d4d7b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md @@ -1,17 +1,17 @@ # ItineraryListFilterChain -ItineraryListFilterChain is a mechanism for post-processing itinerary results. It contains a list of -Each of which contains different business logic for a different operation. They not only remove -itineraries, but can be also used for sorting, decorating or even adding new itineraries. The filter -chain is also responsible for creating routing errors, if no itineraries remain after filtering. -Itineraries are flagged for deletion, but not actually deleted when debugging is turned on. When -debugging is off, the chain actually removes those itineraries that were flagged for deletion. +ItineraryListFilterChain is a mechanism for post-processing itinerary results. There are filters +for removing itineraries, sorting them and for decorating itineraries with more information like +fares. The filter chain is also responsible for creating routing errors, if no itineraries remain +after filtering. Itineraries are flagged for deletion, but not deleted when debugging is turned on. +When debugging is off, the chain removes those itineraries after all filters are complete. ![Architecture diagram](images/ItineraryListFilterChain.svg) There are four types of filters, which can be included in the filter chain. The same type of filter can appear multiple times. + ## DeletionFlaggingFilter DeletionFlaggingFilter is responsible for flagging itineraries for deletion. It does not remove any @@ -22,19 +22,46 @@ selecting if the filter should skip already flagged itineraries to the flagger. disable, in case already removed itineraries are useful in comparing whether other itineraries should be flagged for removal. + ## SortingFilter SortingFilter is responsible for sorting the itineraries. It does this by having a Comparator, which is used for sorting. + ## GroupByFilter GroupByFilter is used to group itineraries together using a `GroupId`, and running a set of filters on that subset of itineraries. This is used eg. to remove almost similar search results and to sort them, so that only the best are shown to the user. + ## DecoratingFilter DecorationgFilter can be used to decorate the itineraries. This can be used eg to add information about ticketing and fares for each itinerary, and refining the routing cost of the itinerary, which -might affect the sorting order of the itineraries, depending on the order of the filters. \ No newline at end of file +might affect the sorting order of the itineraries, depending on the order of the filters. + + +## Package structure + +We try to separate use-case specific code (`filters`) and the generic filter chain implementation. +Here is an overview of the packages and their responsibilities. + +``` +filterchain +├── api Request parameters passed into the filter chain +├── filters Concreate filter implementations +│ ├── street For decorating/filtering street itineraries +│ ├── system Mainly support for otp features like paging and search-window crop +│ └── transit For decorating/filtering itineraries with transit +│ └── group Transit group filters +├── framework Generic filter chain implementation +│ ├── filter Filter implementation +│ ├── filterchain Domain logic used by the `FilterChain` (agreagate root). +│ ├── groupids Generic groupId implementations. These can be used to as lego to build specific group-by filters. +│ ├── sort Sorting implementation +│ └── spi The interfaces to extend to plug into the filter-chain +└── images Images used in the doc + +``` From bdffc557f115126147506c8f793d2797abe2891c Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 11 Jan 2024 14:43:21 +0000 Subject: [PATCH 120/356] Add changelog entry for #5604 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 7458295b9ba..fa3615b90b3 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -72,6 +72,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Adding situation-version to TransmodelGraphQL API [#5592](https://github.com/opentripplanner/OpenTripPlanner/pull/5592) - Move REST API into sandbox [#5580](https://github.com/opentripplanner/OpenTripPlanner/pull/5580) - Fix high walk reluctance leading to zero egress results for rental searches [#5605](https://github.com/opentripplanner/OpenTripPlanner/pull/5605) +- Remove GTFS-RT websocket updater [#5604](https://github.com/opentripplanner/OpenTripPlanner/pull/5604) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From b554800ebf90b66628590e79b7ce2702a6325a5f Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Thu, 11 Jan 2024 14:43:37 +0000 Subject: [PATCH 121/356] Bump serialization version id for #5604 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6567356b392..abd70a60749 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 135 + 136 30.1 2.50 From cf5d875fbf4dd003023e4a506ac8a84d0175d8a7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 15:50:30 +0100 Subject: [PATCH 122/356] Remove extra method call indirection --- client-next/src/components/MapView/MapView.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 57e718ff187..5b6223a5dee 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -62,9 +62,7 @@ export function MapView({ setShowContextPopup(e.lngLat); }} interactiveLayerIds={['regular-stop']} - onClick={(e) => { - showFeaturePropPopup(e); - }} + onClick={showFeaturePropPopup} // put lat/long in URL and pan to it on page reload hash={true} // disable pitching and rotating the map From 6ab81142e4a17029e3a86a5b41e7cbab96af69f2 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 11 Jan 2024 16:03:16 +0000 Subject: [PATCH 123/356] Add changelog entry for #5602 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index fa3615b90b3..50846c3fce7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -73,6 +73,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Move REST API into sandbox [#5580](https://github.com/opentripplanner/OpenTripPlanner/pull/5580) - Fix high walk reluctance leading to zero egress results for rental searches [#5605](https://github.com/opentripplanner/OpenTripPlanner/pull/5605) - Remove GTFS-RT websocket updater [#5604](https://github.com/opentripplanner/OpenTripPlanner/pull/5604) +- Add stop layer to new Debug UI [#5602](https://github.com/opentripplanner/OpenTripPlanner/pull/5602) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From ab694b8efb80bf856a1fb468ef03a9d97c514cfe Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 11 Jan 2024 16:04:27 +0000 Subject: [PATCH 124/356] Upgrade debug client to version 2024/01/2024-01-11T16:03 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index d9bf3a2af16..5f77418dbe6 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
      From c39c366b27d50602e5507c9206cd18696e3f6d48 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 16:19:11 +0100 Subject: [PATCH 125/356] Add documentation about MQTT updater --- doc-templates/UpdaterConfig.md | 13 ++- docs/RouterConfiguration.md | 7 ++ docs/UpdaterConfig.md | 82 +++++++++++++++++-- docs/sandbox/SiriUpdater.md | 30 +++---- .../standalone/config/router-config.json | 8 ++ 5 files changed, 115 insertions(+), 25 deletions(-) diff --git a/doc-templates/UpdaterConfig.md b/doc-templates/UpdaterConfig.md index a239317f244..57152671ec7 100644 --- a/doc-templates/UpdaterConfig.md +++ b/doc-templates/UpdaterConfig.md @@ -8,8 +8,8 @@ # Updater configuration -This section covers all options that can be set in the *router-config.json* in the -[updaters](RouterConfiguration.md) section. +This section covers options that can be set in the updaters section of `router-config.json`. +See the parameter summary and examples in the router configuration documentation Real-time data are those that are not added to OTP during the graph build phase but during runtime. @@ -44,6 +44,15 @@ The information is downloaded in a single HTTP request and polled regularly. +### Streaming TripUpdates via MQTT + +This updater connects to an MQTT broker and processes TripUpdates in a streaming fashion. This means +that they will be applied individually in near-realtime rather than in batches at a certain interval. + +This system powers the realtime updates in Helsinki and more information can be found +[on Github](https://github.com/HSLdevcom/transitdata). + + ### Vehicle Positions diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 30e423f29b1..5ca87a2aefa 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -727,6 +727,13 @@ Used to group requests when monitoring OTP. "Authorization" : "A-Token" } }, + { + "type" : "mqtt-gtfs-rt-updater", + "url" : "tcp://pred.rt.hsl.fi", + "topic" : "gtfsrt/v2/fi/hsl/tu", + "feedId" : "HSL", + "fuzzyTripMatching" : true + }, { "type" : "vehicle-positions", "url" : "https://s3.amazonaws.com/kcm-alerts-realtime-prod/vehiclepositions.pb", diff --git a/docs/UpdaterConfig.md b/docs/UpdaterConfig.md index 6c219d07ddf..212a2d55370 100644 --- a/docs/UpdaterConfig.md +++ b/docs/UpdaterConfig.md @@ -8,8 +8,8 @@ # Updater configuration -This section covers all options that can be set in the *router-config.json* in the -[updaters](RouterConfiguration.md) section. +This section covers options that can be set in the updaters section of `router-config.json`. +See the parameter summary and examples in the router configuration documentation Real-time data are those that are not added to OTP during the graph build phase but during runtime. @@ -164,6 +164,72 @@ HTTP headers to add to the request. Any header key, value can be inserted. +### Streaming TripUpdates via MQTT + +This updater connects to an MQTT broker and processes TripUpdates in a streaming fashion. This means +that they will be applied individually in near-realtime rather than in batches at a certain interval. + +This system powers the realtime updates in Helsinki and more information can be found +[on Github](https://github.com/HSLdevcom/transitdata). + + + + +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|-----------------------------------------------------------------------|:---------:|----------------------------------------------|:----------:|----------------------|:-----:| +| type = "mqtt-gtfs-rt-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | +| [backwardsDelayPropagationType](#u__6__backwardsDelayPropagationType) | `enum` | How backwards propagation should be handled. | *Optional* | `"required-no-data"` | 2.2 | +| feedId | `string` | The feed id to apply the updates to. | *Required* | | na | +| fuzzyTripMatching | `boolean` | Whether to match trips fuzzily. | *Optional* | `false` | na | +| qos | `integer` | QOS level. | *Optional* | `0` | na | +| topic | `string` | The topic to subscribe to. | *Required* | | na | +| url | `string` | URL of the MQTT broker. | *Required* | | na | + + +##### Parameter details + +

      backwardsDelayPropagationType

      + +**Since version:** `2.2` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"required-no-data"` +**Path:** /updaters/[6] +**Enum values:** `required-no-data` | `required` | `always` + +How backwards propagation should be handled. + + REQUIRED_NO_DATA: + Default value. Only propagates delays backwards when it is required to ensure that the times + are increasing, and it sets the NO_DATA flag on the stops so these automatically updated times + are not exposed through APIs. + + REQUIRED: + Only propagates delays backwards when it is required to ensure that the times are increasing. + The updated times are exposed through APIs. + + ALWAYS: + Propagates delays backwards on stops with no estimates regardless if it's required or not. + The updated times are exposed through APIs. + + + + +##### Example configuration + +```JSON +// router-config.json +{ + "updaters" : [ + { + "type" : "mqtt-gtfs-rt-updater", + "url" : "tcp://pred.rt.hsl.fi", + "topic" : "gtfsrt/v2/fi/hsl/tu", + "feedId" : "HSL", + "fuzzyTripMatching" : true + } + ] +} +``` + + ### Vehicle Positions @@ -181,24 +247,24 @@ The information is downloaded in a single HTTP request and polled regularly. | frequency | `duration` | How often the positions should be updated. | *Optional* | `"PT1M"` | 2.2 | | fuzzyTripMatching | `boolean` | Whether to match trips fuzzily. | *Optional* | `false` | 2.5 | | url | `uri` | The URL of GTFS-RT protobuf HTTP resource to download the positions from. | *Required* | | 2.2 | -| [features](#u__6__features) | `enum set` | Which features of GTFS RT vehicle positions should be loaded into OTP. | *Optional* | | 2.5 | -| [headers](#u__6__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [features](#u__7__features) | `enum set` | Which features of GTFS RT vehicle positions should be loaded into OTP. | *Optional* | | 2.5 | +| [headers](#u__7__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

      features

      +

      features

      **Since version:** `2.5` ∙ **Type:** `enum set` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[6] +**Path:** /updaters/[7] **Enum values:** `position` | `stop-position` | `occupancy` Which features of GTFS RT vehicle positions should be loaded into OTP. -

      headers

      +

      headers

      **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[6] +**Path:** /updaters/[7] HTTP headers to add to the request. Any header key, value can be inserted. diff --git a/docs/sandbox/SiriUpdater.md b/docs/sandbox/SiriUpdater.md index 7730df67d12..f6c4c3f999f 100644 --- a/docs/sandbox/SiriUpdater.md +++ b/docs/sandbox/SiriUpdater.md @@ -37,16 +37,16 @@ To enable the SIRI updater you need to add it to the updaters section of the `ro | previewInterval | `duration` | TODO | *Optional* | | 2.0 | | requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | | timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | -| [url](#u__7__url) | `string` | The URL to send the HTTP requests to. | *Required* | | 2.0 | -| [headers](#u__7__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [url](#u__8__url) | `string` | The URL to send the HTTP requests to. | *Required* | | 2.0 | +| [headers](#u__8__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

      url

      +

      url

      **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[7] +**Path:** /updaters/[8] The URL to send the HTTP requests to. @@ -58,10 +58,10 @@ renamed by the loader when processed: -

      headers

      +

      headers

      **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[7] +**Path:** /updaters/[8] HTTP headers to add to the request. Any header key, value can be inserted. @@ -97,21 +97,21 @@ HTTP headers to add to the request. Any header key, value can be inserted. |---------------------------------|:---------------:|--------------------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| | type = "siri-sx-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | | blockReadinessUntilInitialized | `boolean` | Whether catching up with the updates should block the readiness check from returning a 'ready' result. | *Optional* | `false` | 2.0 | -| [earlyStart](#u__8__earlyStart) | `duration` | This value is subtracted from the actual validity defined in the message. | *Optional* | `"PT0S"` | 2.0 | +| [earlyStart](#u__9__earlyStart) | `duration` | This value is subtracted from the actual validity defined in the message. | *Optional* | `"PT0S"` | 2.0 | | feedId | `string` | The ID of the feed to apply the updates to. | *Required* | | 2.0 | | frequency | `duration` | How often the updates should be retrieved. | *Optional* | `"PT1M"` | 2.0 | | requestorRef | `string` | The requester reference. | *Optional* | | 2.0 | | timeout | `duration` | The HTTP timeout to download the updates. | *Optional* | `"PT15S"` | 2.0 | -| [url](#u__8__url) | `string` | The URL to send the HTTP requests to. Supports http/https and file protocol. | *Required* | | 2.0 | -| [headers](#u__8__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | +| [url](#u__9__url) | `string` | The URL to send the HTTP requests to. Supports http/https and file protocol. | *Required* | | 2.0 | +| [headers](#u__9__headers) | `map of string` | HTTP headers to add to the request. Any header key, value can be inserted. | *Optional* | | 2.3 | ##### Parameter details -

      earlyStart

      +

      earlyStart

      **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` -**Path:** /updaters/[8] +**Path:** /updaters/[9] This value is subtracted from the actual validity defined in the message. @@ -119,10 +119,10 @@ Normally the planned departure time is used, so setting this to 10s will cause t SX-message to be included in trip-results 10 seconds before the the planned departure time. -

      url

      +

      url

      **Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /updaters/[8] +**Path:** /updaters/[9] The URL to send the HTTP requests to. Supports http/https and file protocol. @@ -135,10 +135,10 @@ renamed by the loader when processed: -

      headers

      +

      headers

      **Since version:** `2.3` ∙ **Type:** `map of string` ∙ **Cardinality:** `Optional` -**Path:** /updaters/[8] +**Path:** /updaters/[9] HTTP headers to add to the request. Any header key, value can be inserted. diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 1a5eec22a28..5abb5ef87a6 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -283,6 +283,14 @@ "Authorization": "A-Token" } }, + // Streaming GTFS-RT TripUpdates through an MQTT broker + { + "type": "mqtt-gtfs-rt-updater", + "url": "tcp://pred.rt.hsl.fi", + "topic": "gtfsrt/v2/fi/hsl/tu", + "feedId": "HSL", + "fuzzyTripMatching": true + }, // Polling for GTFS-RT Vehicle Positions - output can be fetched via trip pattern GraphQL API { "type": "vehicle-positions", From 31896ea58e69190f6520fc39e268f9c9509f7501 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 02:09:23 +0000 Subject: [PATCH 126/356] Update dependency org.mockito:mockito-core to v5.9.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index abd70a60749..e5f86fe5b66 100644 --- a/pom.xml +++ b/pom.xml @@ -713,7 +713,7 @@ org.mockito mockito-core - 5.8.0 + 5.9.0 test From 28a46b4898828145b00e53ee8d9d8da28c578bda Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jan 2024 23:16:02 +0100 Subject: [PATCH 127/356] Add debug vector layer for displaying edges --- .../src/components/MapView/MapView.tsx | 18 +++--- .../apis/vectortiles/DebugStyleSpec.java | 61 ++++++++++++++++--- .../GraphInspectorVectorTileResource.java | 22 ++++--- .../vectortiles/model/LayerStyleBuilder.java | 33 ++++++++++ .../apis/vectortiles/model/LayerType.java | 1 + .../vector/edges/EdgeLayerBuilder.java | 34 +++++++++++ .../vector/edges/EdgePropertyMapper.java | 30 +++++++++ .../apis/vectortiles/DebugStyleSpecTest.java | 3 +- 8 files changed, 178 insertions(+), 24 deletions(-) create mode 100644 src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java create mode 100644 src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 5b6223a5dee..87c8a61e256 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -1,12 +1,12 @@ -import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl } from 'react-map-gl'; +import {LngLat, Map, MapboxGeoJSONFeature, NavigationControl} from 'react-map-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; -import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts'; -import { NavigationMarkers } from './NavigationMarkers.tsx'; -import { LegLines } from './LegLines.tsx'; -import { useMapDoubleClick } from './useMapDoubleClick.ts'; -import { useState } from 'react'; -import { ContextMenuPopup } from './ContextMenuPopup.tsx'; -import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx'; +import {TripPattern, TripQuery, TripQueryVariables} from '../../gql/graphql.ts'; +import {NavigationMarkers} from './NavigationMarkers.tsx'; +import {LegLines} from './LegLines.tsx'; +import {useMapDoubleClick} from './useMapDoubleClick.ts'; +import {useState} from 'react'; +import {ContextMenuPopup} from './ContextMenuPopup.tsx'; +import {GeometryPropertyPopup} from './GeometryPropertyPopup.tsx'; // TODO: this should be configurable const initialViewState = { @@ -61,7 +61,7 @@ export function MapView({ onContextMenu={(e) => { setShowContextPopup(e.lngLat); }} - interactiveLayerIds={['regular-stop']} + interactiveLayerIds={['regular-stop', 'edge-fallback', 'edge', 'link']} onClick={showFeaturePropPopup} // put lat/long in URL and pan to it on page reload hash={true} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index ff933901cf8..47ad5d5be36 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -6,6 +6,14 @@ import org.opentripplanner.apis.vectortiles.model.TileSource; import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; +import org.opentripplanner.street.model.edge.AreaEdge; +import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; +import org.opentripplanner.street.model.edge.EscalatorEdge; +import org.opentripplanner.street.model.edge.StreetEdge; +import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; +import org.opentripplanner.street.model.edge.StreetTransitStopLink; +import org.opentripplanner.street.model.edge.TemporaryFreeEdge; +import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge; /** * A Mapbox/Mapblibre style specification for rendering debug information about transit and @@ -19,21 +27,60 @@ public class DebugStyleSpec { 256, "© OpenStreetMap Contributors" ); + private static final String MAGENTA = "#f21d52"; + private static final String YELLOW = "#e2d40d"; + private static final String GREY = "#8e8e89"; + private static final int MAX_ZOOM = 23; public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} - static StyleSpec build(VectorSource debugSource, VectorSourceLayer regularStops) { + static StyleSpec build( + VectorSource debugSource, + VectorSourceLayer regularStops, + VectorSourceLayer edges + ) { List sources = List.of(BACKGROUND_SOURCE, debugSource); return new StyleSpec( "OTP Debug Tiles", sources, List.of( + LayerStyleBuilder.ofId("background").typeRaster().source(BACKGROUND_SOURCE).minZoom(0), LayerStyleBuilder - .ofId("background") - .typeRaster() - .source(BACKGROUND_SOURCE) - .minZoom(0) - .maxZoom(22), + .ofId("edge-fallback") + .typeLine() + .vectorSourceLayer(edges) + .lineColor(GREY) + .lineWidth(3) + .minZoom(15) + .maxZoom(MAX_ZOOM), + LayerStyleBuilder + .ofId("edge") + .typeLine() + .vectorSourceLayer(edges) + .lineColor(MAGENTA) + .edgeFilter( + StreetEdge.class, + AreaEdge.class, + EscalatorEdge.class, + TemporaryPartialStreetEdge.class, + TemporaryFreeEdge.class + ) + .lineWidth(3) + .minZoom(13) + .maxZoom(MAX_ZOOM), + LayerStyleBuilder + .ofId("link") + .typeLine() + .vectorSourceLayer(edges) + .lineColor(YELLOW) + .edgeFilter( + StreetTransitStopLink.class, + StreetTransitEntranceLink.class, + BoardingLocationToStopLink.class + ) + .lineWidth(3) + .minZoom(13) + .maxZoom(MAX_ZOOM), LayerStyleBuilder .ofId("regular-stop") .typeCircle() @@ -41,7 +88,7 @@ static StyleSpec build(VectorSource debugSource, VectorSourceLayer regularStops) .circleStroke("#140d0e", 2) .circleColor("#fcf9fa") .minZoom(13) - .maxZoom(22) + .maxZoom(MAX_ZOOM) ) ); } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 67f92f01ee3..e2008eaea29 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -1,5 +1,8 @@ package org.opentripplanner.apis.vectortiles; +import static org.opentripplanner.apis.vectortiles.model.LayerType.Edges; +import static org.opentripplanner.apis.vectortiles.model.LayerType.GeofencingZones; +import static org.opentripplanner.apis.vectortiles.model.LayerType.RegularStop; import static org.opentripplanner.framework.io.HttpUtils.APPLICATION_X_PROTOBUF; import jakarta.ws.rs.GET; @@ -28,6 +31,7 @@ import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.inspector.vector.VectorTileResponseFactory; +import org.opentripplanner.inspector.vector.edges.EdgeLayerBuilder; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; import org.opentripplanner.inspector.vector.stop.StopLayerBuilder; import org.opentripplanner.model.FeedInfo; @@ -40,19 +44,18 @@ @Path("/routers/{ignoreRouterId}/inspector/vectortile") public class GraphInspectorVectorTileResource { - private static final LayerParams REGULAR_STOPS = new LayerParams( - "regularStops", - LayerType.RegularStop - ); + private static final LayerParams REGULAR_STOPS = new LayerParams("regularStops", RegularStop); private static final LayerParams AREA_STOPS = new LayerParams("areaStops", LayerType.AreaStop); private static final LayerParams GEOFENCING_ZONES = new LayerParams( "geofencingZones", - LayerType.GeofencingZones + GeofencingZones ); + private static final LayerParams EDGES = new LayerParams("edges", Edges); private static final List> DEBUG_LAYERS = List.of( REGULAR_STOPS, AREA_STOPS, - GEOFENCING_ZONES + GEOFENCING_ZONES, + EDGES ); private final OtpServerRequestContext serverContext; @@ -131,7 +134,11 @@ public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) ); var vectorSource = new VectorSource("debug", url); - return DebugStyleSpec.build(vectorSource, REGULAR_STOPS.toVectorSourceLayer(vectorSource)); + return DebugStyleSpec.build( + vectorSource, + REGULAR_STOPS.toVectorSourceLayer(vectorSource), + EDGES.toVectorSourceLayer(vectorSource) + ); } @Nonnull @@ -162,6 +169,7 @@ private static LayerBuilder createLayerBuilder( e -> context.transitService().findAreaStops(e) ); case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); + case Edges -> new EdgeLayerBuilder(context.graph(), layerParameters); }; } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index 41144611f92..52455102ccd 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -2,12 +2,16 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Stream; import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; +import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.json.ObjectMappers; +import org.opentripplanner.street.model.edge.Edge; /** * Builds a Maplibre/Mapbox vector tile @@ -20,6 +24,7 @@ public class LayerStyleBuilder { private static final String SOURCE_LAYER = "source-layer"; private final Map props = new HashMap<>(); private final Map paint = new HashMap<>(); + private List filter = List.of(); public static LayerStyleBuilder ofId(String id) { return new LayerStyleBuilder(id); @@ -32,6 +37,7 @@ public LayerStyleBuilder vectorSourceLayer(VectorSourceLayer source) { public enum LayerType { Circle, + Line, Raster, } @@ -75,6 +81,10 @@ public LayerStyleBuilder typeCircle() { return type(LayerType.Circle); } + public LayerStyleBuilder typeLine() { + return type(LayerType.Line); + } + private LayerStyleBuilder type(LayerType type) { props.put(TYPE, type.name().toLowerCase()); return this; @@ -91,6 +101,26 @@ public LayerStyleBuilder circleStroke(String color, int width) { return this; } + // Line styling + + public LayerStyleBuilder lineColor(String color) { + paint.put("line-color", validateColor(color)); + return this; + } + + public LayerStyleBuilder lineWidth(float width) { + paint.put("line-width", width); + return this; + } + + // filtering edge + @SafeVarargs + public final LayerStyleBuilder edgeFilter(Class... classToFilter) { + var clazzes = Arrays.stream(classToFilter).map(Class::getSimpleName).toList(); + filter = ListUtils.combine(List.of("in", "class"), clazzes); + return this; + } + public JsonNode toJson() { validate(); @@ -98,6 +128,9 @@ public JsonNode toJson() { if (!paint.isEmpty()) { copy.put("paint", paint); } + if (!filter.isEmpty()) { + copy.put("filter", filter); + } return OBJECT_MAPPER.valueToTree(copy); } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java index f4cb7a636fa..4324a511a6b 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java @@ -4,4 +4,5 @@ public enum LayerType { RegularStop, AreaStop, GeofencingZones, + Edges, } diff --git a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java new file mode 100644 index 00000000000..60e65f7b35a --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java @@ -0,0 +1,34 @@ +package org.opentripplanner.inspector.vector.edges; + +import java.util.List; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.inspector.vector.LayerBuilder; +import org.opentripplanner.inspector.vector.LayerParameters; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.routing.graph.index.StreetIndex; +import org.opentripplanner.street.model.edge.Edge; + +public class EdgeLayerBuilder extends LayerBuilder { + + private final StreetIndex streetIndex; + + public EdgeLayerBuilder(Graph graph, LayerParameters layerParameters) { + super(new EdgePropertyMapper(), layerParameters.name(), layerParameters.expansionFactor()); + this.streetIndex = graph.getStreetIndex(); + } + + @Override + protected List getGeometries(Envelope query) { + return streetIndex + .getEdgesForEnvelope(query) + .stream() + .filter(e -> e.getGeometry() != null) + .map(edge -> { + Geometry geometry = edge.getGeometry(); + geometry.setUserData(edge); + return geometry; + }) + .toList(); + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java new file mode 100644 index 00000000000..393f7132798 --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java @@ -0,0 +1,30 @@ +package org.opentripplanner.inspector.vector.edges; + +import static org.opentripplanner.inspector.vector.KeyValue.kv; + +import java.util.Collection; +import java.util.List; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.collection.ListUtils; +import org.opentripplanner.inspector.vector.KeyValue; +import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.edge.EscalatorEdge; +import org.opentripplanner.street.model.edge.StreetEdge; + +public class EdgePropertyMapper extends PropertyMapper { + + @Override + protected Collection map(Edge input) { + List baseProps = List.of(kv("class", input.getClass().getSimpleName())); + List properties = + switch (input) { + case StreetEdge e -> List.of( + kv("permission", e.getPermission().toString()), + kv("bicycleSafetyFactor", e.getBicycleSafetyFactor()) + ); + case EscalatorEdge e -> List.of(kv("distance", e.getDistanceMeters())); + default -> List.of(); + }; + return ListUtils.combine(baseProps, properties); + } +} diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index d685e07a2f2..5cca178550a 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -16,7 +16,8 @@ class DebugStyleSpecTest { void spec() { var vectorSource = new VectorSource("vectorSource", "https://example.com"); var regularStops = new VectorSourceLayer(vectorSource, "regularStops"); - var spec = DebugStyleSpec.build(vectorSource, regularStops); + var edges = new VectorSourceLayer(vectorSource, "edges"); + var spec = DebugStyleSpec.build(vectorSource, regularStops, edges); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RES.fileToString("style.json"); From a74d878b70426f3c8a46ef075729978b8020b35f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 12 Jan 2024 00:00:43 +0100 Subject: [PATCH 128/356] Finetune edge styling --- .../apis/vectortiles/DebugStyleSpec.java | 20 ++- .../vectortiles/model/LayerStyleBuilder.java | 29 +++- .../vector/edges/EdgePropertyMapper.java | 3 +- .../apis/vectortiles/DebugStyleSpecTest.java | 4 +- .../apis/vectortiles/style.json | 145 ++++++++++++++---- 5 files changed, 161 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 47ad5d5be36..1508575d336 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -2,16 +2,20 @@ import java.util.List; import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder; +import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder.ZoomDependentNumber; +import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder.ZoomStop; import org.opentripplanner.apis.vectortiles.model.StyleSpec; import org.opentripplanner.apis.vectortiles.model.TileSource; import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; +import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; import org.opentripplanner.street.model.edge.EscalatorEdge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; import org.opentripplanner.street.model.edge.StreetTransitStopLink; +import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.TemporaryFreeEdge; import org.opentripplanner.street.model.edge.TemporaryPartialStreetEdge; @@ -31,6 +35,10 @@ public class DebugStyleSpec { private static final String YELLOW = "#e2d40d"; private static final String GREY = "#8e8e89"; private static final int MAX_ZOOM = 23; + private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( + 1.3f, + List.of(new ZoomStop(13, 1), new ZoomStop(MAX_ZOOM, 10)) + ); public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} @@ -50,7 +58,7 @@ static StyleSpec build( .typeLine() .vectorSourceLayer(edges) .lineColor(GREY) - .lineWidth(3) + .lineWidth(LINE_WIDTH) .minZoom(15) .maxZoom(MAX_ZOOM), LayerStyleBuilder @@ -65,7 +73,7 @@ static StyleSpec build( TemporaryPartialStreetEdge.class, TemporaryFreeEdge.class ) - .lineWidth(3) + .lineWidth(LINE_WIDTH) .minZoom(13) .maxZoom(MAX_ZOOM), LayerStyleBuilder @@ -76,9 +84,11 @@ static StyleSpec build( .edgeFilter( StreetTransitStopLink.class, StreetTransitEntranceLink.class, - BoardingLocationToStopLink.class + BoardingLocationToStopLink.class, + StreetVehicleRentalLink.class, + StreetVehicleParkingLink.class ) - .lineWidth(3) + .lineWidth(LINE_WIDTH) .minZoom(13) .maxZoom(MAX_ZOOM), LayerStyleBuilder @@ -87,7 +97,7 @@ static StyleSpec build( .vectorSourceLayer(regularStops) .circleStroke("#140d0e", 2) .circleColor("#fcf9fa") - .minZoom(13) + .minZoom(11) .maxZoom(MAX_ZOOM) ) ); diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index 52455102ccd..ea93bdde6a2 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Arrays; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -22,8 +22,8 @@ public class LayerStyleBuilder { private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); private static final String TYPE = "type"; private static final String SOURCE_LAYER = "source-layer"; - private final Map props = new HashMap<>(); - private final Map paint = new HashMap<>(); + private final Map props = new LinkedHashMap<>(); + private final Map paint = new LinkedHashMap<>(); private List filter = List.of(); public static LayerStyleBuilder ofId(String id) { @@ -113,6 +113,11 @@ public LayerStyleBuilder lineWidth(float width) { return this; } + public LayerStyleBuilder lineWidth(ZoomDependentNumber zoomStops) { + paint.put("line-width", zoomStops.toJson()); + return this; + } + // filtering edge @SafeVarargs public final LayerStyleBuilder edgeFilter(Class... classToFilter) { @@ -124,7 +129,7 @@ public final LayerStyleBuilder edgeFilter(Class... classToFilter public JsonNode toJson() { validate(); - var copy = new HashMap<>(props); + var copy = new LinkedHashMap<>(props); if (!paint.isEmpty()) { copy.put("paint", paint); } @@ -146,4 +151,20 @@ private void validate() { .of(TYPE) .forEach(p -> Objects.requireNonNull(props.get(p), "%s must be set".formatted(p))); } + + public record ZoomStop(int zoom, float value) { + public List toList() { + return List.of(zoom, value); + } + } + + public record ZoomDependentNumber(float base, List stops) { + public JsonNode toJson() { + var props = new LinkedHashMap<>(); + props.put("base", base); + var vals = stops.stream().map(ZoomStop::toList).toList(); + props.put("stops", vals); + return OBJECT_MAPPER.valueToTree(props); + } + } } diff --git a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java index 393f7132798..5bfc2dc6df7 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java @@ -1,5 +1,6 @@ package org.opentripplanner.inspector.vector.edges; +import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; import static org.opentripplanner.inspector.vector.KeyValue.kv; import java.util.Collection; @@ -20,7 +21,7 @@ protected Collection map(Edge input) { switch (input) { case StreetEdge e -> List.of( kv("permission", e.getPermission().toString()), - kv("bicycleSafetyFactor", e.getBicycleSafetyFactor()) + kv("bicycleSafetyFactor", roundTo2Decimals(e.getBicycleSafetyFactor())) ); case EscalatorEdge e -> List.of(kv("distance", e.getDistanceMeters())); default -> List.of(); diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index 5cca178550a..9a18da3e5c9 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -10,7 +10,7 @@ class DebugStyleSpecTest { - private final ResourceLoader RES = ResourceLoader.of(this); + private final ResourceLoader RESOURCES = ResourceLoader.of(this); @Test void spec() { @@ -20,7 +20,7 @@ void spec() { var spec = DebugStyleSpec.build(vectorSource, regularStops, edges); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); - var expectation = RES.fileToString("style.json"); + var expectation = RESOURCES.fileToString("style.json"); assertEqualJson(expectation, json); } } diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index f5bb18f6f6a..df9f73c3f26 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -1,42 +1,131 @@ { - "name": "OTP Debug Tiles", - "sources": { - "background": { - "id": "background", - "tiles": [ + "name" : "OTP Debug Tiles", + "sources" : { + "background" : { + "id" : "background", + "tiles" : [ "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" ], - "tileSize": 256, + "tileSize" : 256, "attribution" : "© OpenStreetMap Contributors", - "type": "raster" + "type" : "raster" }, - "vectorSource": { - "id": "vectorSource", - "url": "https://example.com", - "type": "vector" + "vectorSource" : { + "id" : "vectorSource", + "url" : "https://example.com", + "type" : "vector" } }, - "layers": [ + "layers" : [ { - "id": "background", - "source": "background", - "type": "raster", - "maxzoom": 22, - "minzoom": 0 + "id" : "background", + "type" : "raster", + "source" : "background", + "minzoom" : 0 }, { - "maxzoom": 22, - "paint": { - "circle-stroke-width": 2, - "circle-color": "#fcf9fa", - "circle-stroke-color": "#140d0e" + "id" : "edge-fallback", + "type" : "line", + "source" : "vectorSource", + "source-layer" : "edges", + "minzoom" : 15, + "maxzoom" : 23, + "paint" : { + "line-color" : "#8e8e89", + "line-width" : { + "base" : 1.3, + "stops" : [ + [ + 13, + 2.0 + ], + [ + 23, + 10.0 + ] + ] + } + } + }, + { + "id" : "edge", + "type" : "line", + "source" : "vectorSource", + "source-layer" : "edges", + "minzoom" : 13, + "maxzoom" : 23, + "paint" : { + "line-color" : "#f21d52", + "line-width" : { + "base" : 1.3, + "stops" : [ + [ + 13, + 2.0 + ], + [ + 23, + 10.0 + ] + ] + } }, - "id": "regular-stop", - "source": "vectorSource", - "source-layer": "regularStops", - "type": "circle", - "minzoom": 13 + "filter" : [ + "in", + "class", + "StreetEdge", + "AreaEdge", + "EscalatorEdge", + "TemporaryPartialStreetEdge", + "TemporaryFreeEdge" + ] + }, + { + "id" : "link", + "type" : "line", + "source" : "vectorSource", + "source-layer" : "edges", + "minzoom" : 13, + "maxzoom" : 23, + "paint" : { + "line-color" : "#e2d40d", + "line-width" : { + "base" : 1.3, + "stops" : [ + [ + 13, + 2.0 + ], + [ + 23, + 10.0 + ] + ] + } + }, + "filter" : [ + "in", + "class", + "StreetTransitStopLink", + "StreetTransitEntranceLink", + "BoardingLocationToStopLink", + "StreetVehicleRentalLink", + "StreetVehicleParkingLink" + ] + }, + { + "id" : "regular-stop", + "type" : "circle", + "source" : "vectorSource", + "source-layer" : "regularStops", + "minzoom" : 11, + "maxzoom" : 23, + "paint" : { + "circle-stroke-color" : "#140d0e", + "circle-stroke-width" : 2, + "circle-color" : "#fcf9fa" + } } ], - "version": 8 + "version" : 8 } From b6fde751915e5178040f79da64d073935205ad11 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 12 Jan 2024 13:20:52 +0100 Subject: [PATCH 129/356] Add more styles --- .../MapView/GeometryPropertyPopup.tsx | 8 ++++++- .../src/components/MapView/MapView.tsx | 16 ++++++------- .../apis/vectortiles/DebugStyleSpec.java | 3 ++- .../vectortiles/model/LayerStyleBuilder.java | 24 ++++++++++++++++++- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/client-next/src/components/MapView/GeometryPropertyPopup.tsx b/client-next/src/components/MapView/GeometryPropertyPopup.tsx index d2b55689270..5492d15d472 100644 --- a/client-next/src/components/MapView/GeometryPropertyPopup.tsx +++ b/client-next/src/components/MapView/GeometryPropertyPopup.tsx @@ -11,7 +11,13 @@ export function GeometryPropertyPopup({ onClose: () => void; }) { return ( - onClose()}> + onClose()} + maxWidth="350px" + > {Object.entries(properties).map(([key, value]) => ( diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 87c8a61e256..47193658bb0 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -1,12 +1,12 @@ -import {LngLat, Map, MapboxGeoJSONFeature, NavigationControl} from 'react-map-gl'; +import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl } from 'react-map-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; -import {TripPattern, TripQuery, TripQueryVariables} from '../../gql/graphql.ts'; -import {NavigationMarkers} from './NavigationMarkers.tsx'; -import {LegLines} from './LegLines.tsx'; -import {useMapDoubleClick} from './useMapDoubleClick.ts'; -import {useState} from 'react'; -import {ContextMenuPopup} from './ContextMenuPopup.tsx'; -import {GeometryPropertyPopup} from './GeometryPropertyPopup.tsx'; +import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts'; +import { NavigationMarkers } from './NavigationMarkers.tsx'; +import { LegLines } from './LegLines.tsx'; +import { useMapDoubleClick } from './useMapDoubleClick.ts'; +import { useState } from 'react'; +import { ContextMenuPopup } from './ContextMenuPopup.tsx'; +import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx'; // TODO: this should be configurable const initialViewState = { diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 1508575d336..b3470ed579e 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -37,7 +37,7 @@ public class DebugStyleSpec { private static final int MAX_ZOOM = 23; private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( 1.3f, - List.of(new ZoomStop(13, 1), new ZoomStop(MAX_ZOOM, 10)) + List.of(new ZoomStop(13, 0.5f), new ZoomStop(MAX_ZOOM, 10)) ); public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} @@ -96,6 +96,7 @@ static StyleSpec build( .typeCircle() .vectorSourceLayer(regularStops) .circleStroke("#140d0e", 2) + .circleRadius(new ZoomDependentNumber(1, List.of(new ZoomStop(11,1), new ZoomStop(MAX_ZOOM, 10)))) .circleColor("#fcf9fa") .minZoom(11) .maxZoom(MAX_ZOOM) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index ea93bdde6a2..96ad10a644c 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -24,6 +24,8 @@ public class LayerStyleBuilder { private static final String SOURCE_LAYER = "source-layer"; private final Map props = new LinkedHashMap<>(); private final Map paint = new LinkedHashMap<>(); + private final Map layout = new LinkedHashMap<>(); + private final Map line = new LinkedHashMap<>(); private List filter = List.of(); public static LayerStyleBuilder ofId(String id) { @@ -35,6 +37,8 @@ public LayerStyleBuilder vectorSourceLayer(VectorSourceLayer source) { return sourceLayer(source.vectorLayer()); } + + public enum LayerType { Circle, Line, @@ -82,7 +86,9 @@ public LayerStyleBuilder typeCircle() { } public LayerStyleBuilder typeLine() { - return type(LayerType.Line); + type(LayerType.Line); + line.put("line-cap", "round"); + return this; } private LayerStyleBuilder type(LayerType type) { @@ -101,6 +107,11 @@ public LayerStyleBuilder circleStroke(String color, int width) { return this; } + public LayerStyleBuilder circleRadius(ZoomDependentNumber radius) { + paint.put("circle-radius", radius.toJson()); + return this; + } + // Line styling public LayerStyleBuilder lineColor(String color) { @@ -118,6 +129,11 @@ public LayerStyleBuilder lineWidth(ZoomDependentNumber zoomStops) { return this; } + public LayerStyleBuilder intiallyHidden() { + layout.put("visibility", "none"); + return this; + } + // filtering edge @SafeVarargs public final LayerStyleBuilder edgeFilter(Class... classToFilter) { @@ -136,6 +152,12 @@ public JsonNode toJson() { if (!filter.isEmpty()) { copy.put("filter", filter); } + if (!layout.isEmpty()) { + copy.put("layout", layout); + } + if (!line.isEmpty()) { + copy.put("line", line); + } return OBJECT_MAPPER.valueToTree(copy); } From f49b2160f2fe070629cdf2e17fbe8c01317a8dc4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 13 Jan 2024 21:23:42 +0100 Subject: [PATCH 130/356] Finetune layer selector --- client-next/package-lock.json | 56 ++++++------- client-next/package.json | 2 +- .../components/MapView/ContextMenuPopup.tsx | 2 +- .../MapView/GeometryPropertyPopup.tsx | 2 +- .../src/components/MapView/LayerControl.tsx | 78 +++++++++++++++++++ .../src/components/MapView/MapView.tsx | 10 ++- .../components/MapView/useMapDoubleClick.ts | 2 +- client-next/src/style.css | 9 +++ .../apis/vectortiles/DebugStyleSpec.java | 11 ++- 9 files changed, 133 insertions(+), 39 deletions(-) create mode 100644 client-next/src/components/MapView/LayerControl.tsx diff --git a/client-next/package-lock.json b/client-next/package-lock.json index 19909ba109d..11894b5b246 100644 --- a/client-next/package-lock.json +++ b/client-next/package-lock.json @@ -12,7 +12,7 @@ "bootstrap": "5.3.1", "graphql": "16.8.0", "graphql-request": "6.1.0", - "maplibre-gl": "3.3.0", + "maplibre-gl": "3.6.2", "react": "18.2.0", "react-bootstrap": "2.8.0", "react-dom": "18.2.0", @@ -2864,9 +2864,9 @@ } }, "node_modules/@maplibre/maplibre-gl-style-spec": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.0.tgz", - "integrity": "sha512-ZbhX9CTV+Z7vHwkRIasDOwTSzr76e8Q6a55RMsAibjyX6+P0ZNL1qAKNzOjjBDP3+aEfNMl7hHo5knuY6pTAUQ==", + "version": "19.3.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", + "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", @@ -3306,9 +3306,9 @@ } }, "node_modules/@types/geojson": { - "version": "7946.0.10", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", - "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==" + "version": "7946.0.13", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz", + "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==" }, "node_modules/@types/js-yaml": { "version": "4.0.5", @@ -3335,14 +3335,14 @@ "dev": true }, "node_modules/@types/mapbox__point-geometry": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz", - "integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA==" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==" }, "node_modules/@types/mapbox__vector-tile": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz", - "integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", @@ -3364,9 +3364,9 @@ "dev": true }, "node_modules/@types/pbf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz", - "integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -3412,9 +3412,9 @@ "dev": true }, "node_modules/@types/supercluster": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.0.tgz", - "integrity": "sha512-6JapQ2GmEkH66r23BK49I+u6zczVDGTtiJEVvKDYZVSm/vepWaJuTq6BXzJ6I4agG5s8vA1KM7m/gXWDg03O4Q==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", "dependencies": { "@types/geojson": "*" } @@ -7379,9 +7379,9 @@ } }, "node_modules/maplibre-gl": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.3.0.tgz", - "integrity": "sha512-LDia3b8u2S8qtl50n8TYJM0IPLzfc01KDc71LNuydvDiEXAGBI5togty+juVtUipRZZjs4dAW6xhgrabc6lIgw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.6.2.tgz", + "integrity": "sha512-krg2KFIdOpLPngONDhP6ixCoWl5kbdMINP0moMSJFVX7wX1Clm2M9hlNKXS8vBGlVWwR5R3ZfI6IPrYz7c+aCQ==", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", "@mapbox/jsonlint-lines-primitives": "^2.0.2", @@ -7390,12 +7390,12 @@ "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^19.3.0", - "@types/geojson": "^7946.0.10", - "@types/mapbox__point-geometry": "^0.1.2", - "@types/mapbox__vector-tile": "^1.3.0", - "@types/pbf": "^3.0.2", - "@types/supercluster": "^7.1.0", + "@maplibre/maplibre-gl-style-spec": "^19.3.3", + "@types/geojson": "^7946.0.13", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", "earcut": "^2.2.4", "geojson-vt": "^3.2.1", "gl-matrix": "^3.4.3", diff --git a/client-next/package.json b/client-next/package.json index 79d2c7942f1..6388122befc 100644 --- a/client-next/package.json +++ b/client-next/package.json @@ -19,7 +19,7 @@ "bootstrap": "5.3.1", "graphql": "16.8.0", "graphql-request": "6.1.0", - "maplibre-gl": "3.3.0", + "maplibre-gl": "3.6.2", "react": "18.2.0", "react-bootstrap": "2.8.0", "react-dom": "18.2.0", diff --git a/client-next/src/components/MapView/ContextMenuPopup.tsx b/client-next/src/components/MapView/ContextMenuPopup.tsx index 52dd3858298..7d51a4c21ad 100644 --- a/client-next/src/components/MapView/ContextMenuPopup.tsx +++ b/client-next/src/components/MapView/ContextMenuPopup.tsx @@ -1,5 +1,5 @@ import { TripQueryVariables } from '../../gql/graphql.ts'; -import { LngLat, Popup } from 'react-map-gl'; +import { LngLat, Popup } from 'react-map-gl/maplibre'; import { Button, ButtonGroup } from 'react-bootstrap'; export function ContextMenuPopup({ diff --git a/client-next/src/components/MapView/GeometryPropertyPopup.tsx b/client-next/src/components/MapView/GeometryPropertyPopup.tsx index 5492d15d472..3ecedb2c67d 100644 --- a/client-next/src/components/MapView/GeometryPropertyPopup.tsx +++ b/client-next/src/components/MapView/GeometryPropertyPopup.tsx @@ -1,4 +1,4 @@ -import { LngLat, Popup } from 'react-map-gl'; +import { LngLat, Popup } from 'react-map-gl/maplibre'; import { Table } from 'react-bootstrap'; export function GeometryPropertyPopup({ diff --git a/client-next/src/components/MapView/LayerControl.tsx b/client-next/src/components/MapView/LayerControl.tsx new file mode 100644 index 00000000000..783d0411673 --- /dev/null +++ b/client-next/src/components/MapView/LayerControl.tsx @@ -0,0 +1,78 @@ +import type { ControlPosition } from 'react-map-gl'; +import { useControl } from 'react-map-gl'; +import { Map } from 'maplibre-gl'; + +type LayerControlProps = { + position?: ControlPosition; +}; + +class LayerList { + private map: Map | null = null; + private _container: HTMLDivElement; + + onAdd(map: Map) { + this.map = map; + this._container = document.createElement('div'); + this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group layer-select'; + + map?.on('load', () => { + while (this._container.firstChild) { + this._container.removeChild(this._container.firstChild); + } + + const h3 = document.createElement('h6'); + h3.textContent = 'Debug layers'; + this._container.appendChild(h3); + + map + ?.getLayersOrder() + .map((l) => map.getLayer(l)) + .filter((s) => s?.type !== 'raster') + .reverse() + .forEach((layer) => { + const div = document.createElement('div'); + const input = document.createElement('input'); + input.type = 'checkbox'; + input.value = layer?.id; + input.onchange = (e) => { + e.preventDefault(); + e.stopPropagation(); + + if (this.layerVisible(layer)) { + map.setLayoutProperty(layer.id, 'visibility', 'none'); + } else { + map.setLayoutProperty(layer.id, 'visibility', 'visible'); + } + }; + const visible = map.getLayoutProperty(layer.id, 'visibility') !== 'none'; + input.checked = visible; + const label = document.createElement('label'); + label.textContent = layer.id; + div.appendChild(input); + div.appendChild(label); + this._container.appendChild(div); + }); + }); + + return this._container; + } + + private layerVisible(layer: { id: string }) { + return this.map?.getLayoutProperty(layer.id, 'visibility') !== 'none'; + } + + onCreate() {} + + onRemove() { + this._container.parentNode.removeChild(this._container); + this.map = undefined; + } +} + +export default function LayerListControl(props: LayerControlProps) { + useControl(() => new LayerList(), { + position: props.position, + }); + + return null; +} diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 47193658bb0..b192fb6fdad 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -1,4 +1,4 @@ -import { LngLat, Map, MapboxGeoJSONFeature, NavigationControl } from 'react-map-gl'; +import { LngLat, Map, MapGeoJSONFeature, MapMouseEvent, NavigationControl } from 'react-map-gl/maplibre'; import 'maplibre-gl/dist/maplibre-gl.css'; import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts'; import { NavigationMarkers } from './NavigationMarkers.tsx'; @@ -7,6 +7,7 @@ import { useMapDoubleClick } from './useMapDoubleClick.ts'; import { useState } from 'react'; import { ContextMenuPopup } from './ContextMenuPopup.tsx'; import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx'; +import LayerListControl from './LayerControl.tsx'; // TODO: this should be configurable const initialViewState = { @@ -17,7 +18,7 @@ const initialViewState = { const styleUrl = import.meta.env.VITE_DEBUG_STYLE_URL; -type PopupData = { coordinates: LngLat; feature: MapboxGeoJSONFeature }; +type PopupData = { coordinates: LngLat; feature: MapGeoJSONFeature }; export function MapView({ tripQueryVariables, @@ -36,8 +37,8 @@ export function MapView({ const [showContextPopup, setShowContextPopup] = useState(null); const [showPropsPopup, setShowPropsPopup] = useState(null); const showFeaturePropPopup = ( - e: mapboxgl.MapMouseEvent & { - features?: mapboxgl.MapboxGeoJSONFeature[] | undefined; + e: MapMouseEvent & { + features?: MapGeoJSONFeature[] | undefined; }, ) => { if (e.features) { @@ -75,6 +76,7 @@ export function MapView({ setTripQueryVariables={setTripQueryVariables} loading={loading} /> + {tripQueryResult?.trip.tripPatterns.length && ( )} diff --git a/client-next/src/components/MapView/useMapDoubleClick.ts b/client-next/src/components/MapView/useMapDoubleClick.ts index 35cb1d76a62..eb9217aa167 100644 --- a/client-next/src/components/MapView/useMapDoubleClick.ts +++ b/client-next/src/components/MapView/useMapDoubleClick.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import { TripQueryVariables } from '../../gql/graphql.ts'; -import { LngLat, MapLayerMouseEvent } from 'react-map-gl'; +import { LngLat, MapLayerMouseEvent } from 'react-map-gl/maplibre'; const setCoordinates = (tripQueryVariables: TripQueryVariables, lngLat: LngLat, key: 'from' | 'to') => ({ ...tripQueryVariables, diff --git a/client-next/src/style.css b/client-next/src/style.css index b7661779991..9a538686043 100644 --- a/client-next/src/style.css +++ b/client-next/src/style.css @@ -119,3 +119,12 @@ font-size: 14px; padding-left: 2px; } + +/* debug layer selector */ + +.maplibregl-ctrl-group.layer-select { + padding: 10px; +} +.maplibregl-ctrl-group.layer-select label { + margin-left: 6px; +} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index b3470ed579e..e9dc771932d 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -11,7 +11,9 @@ import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; +import org.opentripplanner.street.model.edge.ElevatorHopEdge; import org.opentripplanner.street.model.edge.EscalatorEdge; +import org.opentripplanner.street.model.edge.PathwayEdge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; import org.opentripplanner.street.model.edge.StreetTransitStopLink; @@ -60,7 +62,8 @@ static StyleSpec build( .lineColor(GREY) .lineWidth(LINE_WIDTH) .minZoom(15) - .maxZoom(MAX_ZOOM), + .maxZoom(MAX_ZOOM) + .intiallyHidden(), LayerStyleBuilder .ofId("edge") .typeLine() @@ -70,12 +73,14 @@ static StyleSpec build( StreetEdge.class, AreaEdge.class, EscalatorEdge.class, + PathwayEdge.class, + ElevatorHopEdge.class, TemporaryPartialStreetEdge.class, TemporaryFreeEdge.class ) .lineWidth(LINE_WIDTH) .minZoom(13) - .maxZoom(MAX_ZOOM), + .maxZoom(MAX_ZOOM).intiallyHidden(), LayerStyleBuilder .ofId("link") .typeLine() @@ -90,7 +95,7 @@ static StyleSpec build( ) .lineWidth(LINE_WIDTH) .minZoom(13) - .maxZoom(MAX_ZOOM), + .maxZoom(MAX_ZOOM).intiallyHidden(), LayerStyleBuilder .ofId("regular-stop") .typeCircle() From 32d070d01634f5c7c87810046ee5ce5567ba11ff Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 13 Jan 2024 23:48:16 +0100 Subject: [PATCH 131/356] Finetune layer selector --- .../apis/vectortiles/DebugStyleSpec.java | 10 +++++++--- .../apis/vectortiles/model/LayerStyleBuilder.java | 2 -- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index e9dc771932d..7c14e66d475 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -80,7 +80,8 @@ static StyleSpec build( ) .lineWidth(LINE_WIDTH) .minZoom(13) - .maxZoom(MAX_ZOOM).intiallyHidden(), + .maxZoom(MAX_ZOOM) + .intiallyHidden(), LayerStyleBuilder .ofId("link") .typeLine() @@ -95,13 +96,16 @@ static StyleSpec build( ) .lineWidth(LINE_WIDTH) .minZoom(13) - .maxZoom(MAX_ZOOM).intiallyHidden(), + .maxZoom(MAX_ZOOM) + .intiallyHidden(), LayerStyleBuilder .ofId("regular-stop") .typeCircle() .vectorSourceLayer(regularStops) .circleStroke("#140d0e", 2) - .circleRadius(new ZoomDependentNumber(1, List.of(new ZoomStop(11,1), new ZoomStop(MAX_ZOOM, 10)))) + .circleRadius( + new ZoomDependentNumber(1, List.of(new ZoomStop(11, 1), new ZoomStop(MAX_ZOOM, 10))) + ) .circleColor("#fcf9fa") .minZoom(11) .maxZoom(MAX_ZOOM) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java index 96ad10a644c..585e3bce2e1 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java @@ -37,8 +37,6 @@ public LayerStyleBuilder vectorSourceLayer(VectorSourceLayer source) { return sourceLayer(source.vectorLayer()); } - - public enum LayerType { Circle, Line, From 73ec23ebf42aa4225963e680af080cabe488b5ed Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 14 Jan 2024 11:24:09 +0100 Subject: [PATCH 132/356] Improve TypeScript --- .../src/components/MapView/LayerControl.tsx | 69 ++++++++++--------- .../src/components/MapView/MapView.tsx | 2 +- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/client-next/src/components/MapView/LayerControl.tsx b/client-next/src/components/MapView/LayerControl.tsx index 783d0411673..4d9974f66e2 100644 --- a/client-next/src/components/MapView/LayerControl.tsx +++ b/client-next/src/components/MapView/LayerControl.tsx @@ -3,58 +3,59 @@ import { useControl } from 'react-map-gl'; import { Map } from 'maplibre-gl'; type LayerControlProps = { - position?: ControlPosition; + position: ControlPosition; }; class LayerList { private map: Map | null = null; - private _container: HTMLDivElement; + private readonly container: HTMLDivElement = document.createElement('div'); onAdd(map: Map) { this.map = map; - this._container = document.createElement('div'); - this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group layer-select'; + this.container.className = 'maplibregl-ctrl maplibregl-ctrl-group layer-select'; - map?.on('load', () => { - while (this._container.firstChild) { - this._container.removeChild(this._container.firstChild); + map.on('load', () => { + // clean on + while (this.container.firstChild) { + this.container.removeChild(this.container.firstChild); } - const h3 = document.createElement('h6'); - h3.textContent = 'Debug layers'; - this._container.appendChild(h3); + const title = document.createElement('h6'); + title.textContent = 'Debug layers'; + this.container.appendChild(title); map - ?.getLayersOrder() + .getLayersOrder() .map((l) => map.getLayer(l)) .filter((s) => s?.type !== 'raster') .reverse() .forEach((layer) => { - const div = document.createElement('div'); - const input = document.createElement('input'); - input.type = 'checkbox'; - input.value = layer?.id; - input.onchange = (e) => { - e.preventDefault(); - e.stopPropagation(); + if (layer) { + const div = document.createElement('div'); + const input = document.createElement('input'); + input.type = 'checkbox'; + input.value = layer?.id; + input.onchange = (e) => { + e.preventDefault(); + e.stopPropagation(); - if (this.layerVisible(layer)) { - map.setLayoutProperty(layer.id, 'visibility', 'none'); - } else { - map.setLayoutProperty(layer.id, 'visibility', 'visible'); - } - }; - const visible = map.getLayoutProperty(layer.id, 'visibility') !== 'none'; - input.checked = visible; - const label = document.createElement('label'); - label.textContent = layer.id; - div.appendChild(input); - div.appendChild(label); - this._container.appendChild(div); + if (this.layerVisible(layer)) { + map.setLayoutProperty(layer.id, 'visibility', 'none'); + } else { + map.setLayoutProperty(layer.id, 'visibility', 'visible'); + } + }; + input.checked = this.layerVisible(layer); + const label = document.createElement('label'); + label.textContent = layer.id; + div.appendChild(input); + div.appendChild(label); + this.container.appendChild(div); + } }); }); - return this._container; + return this.container; } private layerVisible(layer: { id: string }) { @@ -64,8 +65,8 @@ class LayerList { onCreate() {} onRemove() { - this._container.parentNode.removeChild(this._container); - this.map = undefined; + this.container.parentNode?.removeChild(this.container); + this.map = null; } } diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index b192fb6fdad..a3c925a2519 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -76,7 +76,7 @@ export function MapView({ setTripQueryVariables={setTripQueryVariables} loading={loading} /> - + {tripQueryResult?.trip.tripPatterns.length && ( )} From 95e4d1559f2645ef9957bea2f7361504743a3074 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 14 Jan 2024 23:23:38 +0100 Subject: [PATCH 133/356] Finetune map layers --- .../src/components/MapView/LayerControl.tsx | 21 ++++++++----------- .../apis/vectortiles/DebugStyleSpec.java | 11 +--------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/client-next/src/components/MapView/LayerControl.tsx b/client-next/src/components/MapView/LayerControl.tsx index 4d9974f66e2..4566c3679fc 100644 --- a/client-next/src/components/MapView/LayerControl.tsx +++ b/client-next/src/components/MapView/LayerControl.tsx @@ -1,17 +1,15 @@ import type { ControlPosition } from 'react-map-gl'; import { useControl } from 'react-map-gl'; -import { Map } from 'maplibre-gl'; +import { IControl, Map} from 'maplibre-gl'; type LayerControlProps = { position: ControlPosition; }; -class LayerList { - private map: Map | null = null; +class LayerList implements IControl { private readonly container: HTMLDivElement = document.createElement('div'); onAdd(map: Map) { - this.map = map; this.container.className = 'maplibregl-ctrl maplibregl-ctrl-group layer-select'; map.on('load', () => { @@ -34,20 +32,22 @@ class LayerList { const div = document.createElement('div'); const input = document.createElement('input'); input.type = 'checkbox'; - input.value = layer?.id; + input.value = layer.id; + input.id = layer.id; input.onchange = (e) => { e.preventDefault(); e.stopPropagation(); - if (this.layerVisible(layer)) { + if (this.layerVisible(map, layer)) { map.setLayoutProperty(layer.id, 'visibility', 'none'); } else { map.setLayoutProperty(layer.id, 'visibility', 'visible'); } }; - input.checked = this.layerVisible(layer); + input.checked = this.layerVisible(map, layer); const label = document.createElement('label'); label.textContent = layer.id; + label.htmlFor = layer.id; div.appendChild(input); div.appendChild(label); this.container.appendChild(div); @@ -58,15 +58,12 @@ class LayerList { return this.container; } - private layerVisible(layer: { id: string }) { - return this.map?.getLayoutProperty(layer.id, 'visibility') !== 'none'; + private layerVisible(map: Map, layer: { id: string }) { + return map.getLayoutProperty(layer.id, 'visibility') !== 'none'; } - onCreate() {} - onRemove() { this.container.parentNode?.removeChild(this.container); - this.map = null; } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 7c14e66d475..05e91d9e6b7 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -55,15 +55,6 @@ static StyleSpec build( sources, List.of( LayerStyleBuilder.ofId("background").typeRaster().source(BACKGROUND_SOURCE).minZoom(0), - LayerStyleBuilder - .ofId("edge-fallback") - .typeLine() - .vectorSourceLayer(edges) - .lineColor(GREY) - .lineWidth(LINE_WIDTH) - .minZoom(15) - .maxZoom(MAX_ZOOM) - .intiallyHidden(), LayerStyleBuilder .ofId("edge") .typeLine() @@ -107,7 +98,7 @@ static StyleSpec build( new ZoomDependentNumber(1, List.of(new ZoomStop(11, 1), new ZoomStop(MAX_ZOOM, 10))) ) .circleColor("#fcf9fa") - .minZoom(11) + .minZoom(10) .maxZoom(MAX_ZOOM) ) ); From 58781d940adaf3526e699342344d2d93dd89d6be Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 15 Jan 2024 10:24:50 +0100 Subject: [PATCH 134/356] Rename to StyleBuilder --- .../apis/vectortiles/DebugStyleSpec.java | 41 ++++++----- .../GraphInspectorVectorTileResource.java | 39 +++++++---- .../apis/vectortiles/model/LayerParams.java | 1 - ...yerStyleBuilder.java => StyleBuilder.java} | 68 ++++++++----------- .../apis/vectortiles/model/StyleSpec.java | 7 +- .../apis/vectortiles/model/TileSource.java | 2 +- .../vectortiles/model/VectorSourceLayer.java | 8 +++ .../model/ZoomDependentNumber.java | 31 +++++++++ .../apis/vectortiles/DebugStyleSpecTest.java | 6 +- .../apis/vectortiles/style.json | 65 +++++++++--------- 10 files changed, 153 insertions(+), 115 deletions(-) rename src/main/java/org/opentripplanner/apis/vectortiles/model/{LayerStyleBuilder.java => StyleBuilder.java} (67%) create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java create mode 100644 src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 05e91d9e6b7..2393125f780 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -1,13 +1,15 @@ package org.opentripplanner.apis.vectortiles; import java.util.List; -import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder; -import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder.ZoomDependentNumber; -import org.opentripplanner.apis.vectortiles.model.LayerStyleBuilder.ZoomStop; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.opentripplanner.apis.vectortiles.model.StyleBuilder; import org.opentripplanner.apis.vectortiles.model.StyleSpec; import org.opentripplanner.apis.vectortiles.model.TileSource; import org.opentripplanner.apis.vectortiles.model.TileSource.RasterSource; -import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; +import org.opentripplanner.apis.vectortiles.model.VectorSourceLayer; +import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber; +import org.opentripplanner.apis.vectortiles.model.ZoomDependentNumber.ZoomStop; import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; import org.opentripplanner.street.model.edge.AreaEdge; import org.opentripplanner.street.model.edge.BoardingLocationToStopLink; @@ -27,35 +29,32 @@ */ public class DebugStyleSpec { - private static final RasterSource BACKGROUND_SOURCE = new RasterSource( + private static final TileSource BACKGROUND_SOURCE = new RasterSource( "background", List.of("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"), + 19, 256, "© OpenStreetMap Contributors" ); private static final String MAGENTA = "#f21d52"; - private static final String YELLOW = "#e2d40d"; - private static final String GREY = "#8e8e89"; + private static final String GREEN = "#22DD9E"; private static final int MAX_ZOOM = 23; private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( 1.3f, List.of(new ZoomStop(13, 0.5f), new ZoomStop(MAX_ZOOM, 10)) ); - public record VectorSourceLayer(VectorSource vectorSource, String vectorLayer) {} - - static StyleSpec build( - VectorSource debugSource, - VectorSourceLayer regularStops, - VectorSourceLayer edges - ) { - List sources = List.of(BACKGROUND_SOURCE, debugSource); + static StyleSpec build(VectorSourceLayer regularStops, VectorSourceLayer edges) { + var vectorSources = Stream.of(regularStops, edges).map(VectorSourceLayer::vectorSource); + var allSources = Stream + .concat(Stream.of(BACKGROUND_SOURCE), vectorSources) + .collect(Collectors.toSet()); return new StyleSpec( "OTP Debug Tiles", - sources, + allSources, List.of( - LayerStyleBuilder.ofId("background").typeRaster().source(BACKGROUND_SOURCE).minZoom(0), - LayerStyleBuilder + StyleBuilder.ofId("background").typeRaster().source(BACKGROUND_SOURCE).minZoom(0), + StyleBuilder .ofId("edge") .typeLine() .vectorSourceLayer(edges) @@ -73,11 +72,11 @@ static StyleSpec build( .minZoom(13) .maxZoom(MAX_ZOOM) .intiallyHidden(), - LayerStyleBuilder + StyleBuilder .ofId("link") .typeLine() .vectorSourceLayer(edges) - .lineColor(YELLOW) + .lineColor(GREEN) .edgeFilter( StreetTransitStopLink.class, StreetTransitEntranceLink.class, @@ -89,7 +88,7 @@ static StyleSpec build( .minZoom(13) .maxZoom(MAX_ZOOM) .intiallyHidden(), - LayerStyleBuilder + StyleBuilder .ofId("regular-stop") .typeCircle() .vectorSourceLayer(regularStops) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index e2008eaea29..b43cd5c109f 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -122,25 +122,36 @@ public TileJson getTileJson( @Produces(MediaType.APPLICATION_JSON) public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) { var base = HttpUtils.getBaseAddress(uri, headers); - final String allLayers = DEBUG_LAYERS - .stream() - .map(LayerParameters::name) - .collect(Collectors.joining(",")); - var url = - "%s/otp/routers/%s/inspector/vectortile/%s/tilejson.json".formatted( - base, - ignoreRouterId, - allLayers - ); - var vectorSource = new VectorSource("debug", url); + // these two could also be loaded together but are put into separate sources because + // the stops are fast and the edges are relatively slow + var stopsSource = new VectorSource( + "stops", + tileJsonUrl(base, List.of(REGULAR_STOPS, AREA_STOPS)) + ); + var streetSource = new VectorSource( + "street", + tileJsonUrl(base, List.of(EDGES, GEOFENCING_ZONES)) + ); + return DebugStyleSpec.build( - vectorSource, - REGULAR_STOPS.toVectorSourceLayer(vectorSource), - EDGES.toVectorSourceLayer(vectorSource) + REGULAR_STOPS.toVectorSourceLayer(stopsSource), + EDGES.toVectorSourceLayer(streetSource) ); } + private String tileJsonUrl(String base, List> layers) { + final String allLayers = layers + .stream() + .map(LayerParameters::name) + .collect(Collectors.joining(",")); + return "%s/otp/routers/%s/inspector/vectortile/%s/tilejson.json".formatted( + base, + ignoreRouterId, + allLayers + ); + } + @Nonnull private List feedInfos() { return serverContext diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java index 7365e8972da..4ae7691db23 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerParams.java @@ -1,6 +1,5 @@ package org.opentripplanner.apis.vectortiles.model; -import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; import org.opentripplanner.inspector.vector.LayerParameters; diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java similarity index 67% rename from src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java rename to src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java index 585e3bce2e1..f60531b461a 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerStyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java @@ -8,7 +8,6 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Stream; -import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.street.model.edge.Edge; @@ -17,7 +16,7 @@ * Builds a Maplibre/Mapbox vector tile * layer style. */ -public class LayerStyleBuilder { +public class StyleBuilder { private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); private static final String TYPE = "type"; @@ -28,11 +27,11 @@ public class LayerStyleBuilder { private final Map line = new LinkedHashMap<>(); private List filter = List.of(); - public static LayerStyleBuilder ofId(String id) { - return new LayerStyleBuilder(id); + public static StyleBuilder ofId(String id) { + return new StyleBuilder(id); } - public LayerStyleBuilder vectorSourceLayer(VectorSourceLayer source) { + public StyleBuilder vectorSourceLayer(VectorSourceLayer source) { source(source.vectorSource()); return sourceLayer(source.vectorLayer()); } @@ -43,16 +42,16 @@ public enum LayerType { Raster, } - private LayerStyleBuilder(String id) { + private StyleBuilder(String id) { props.put("id", id); } - public LayerStyleBuilder minZoom(int i) { + public StyleBuilder minZoom(int i) { props.put("minzoom", i); return this; } - public LayerStyleBuilder maxZoom(int i) { + public StyleBuilder maxZoom(int i) { props.put("maxzoom", i); return this; } @@ -60,7 +59,7 @@ public LayerStyleBuilder maxZoom(int i) { /** * Which vector tile source this should apply to. */ - public LayerStyleBuilder source(TileSource source) { + public StyleBuilder source(TileSource source) { props.put("source", source.id()); return this; } @@ -70,71 +69,76 @@ public LayerStyleBuilder source(TileSource source) { * There is an unfortunate collision in the name "layer" as it can both refer to a styling layer * and the layer inside the vector tile. */ - public LayerStyleBuilder sourceLayer(String source) { + public StyleBuilder sourceLayer(String source) { props.put(SOURCE_LAYER, source); return this; } - public LayerStyleBuilder typeRaster() { + public StyleBuilder typeRaster() { return type(LayerType.Raster); } - public LayerStyleBuilder typeCircle() { + public StyleBuilder typeCircle() { return type(LayerType.Circle); } - public LayerStyleBuilder typeLine() { + public StyleBuilder typeLine() { type(LayerType.Line); - line.put("line-cap", "round"); + layout.put("line-cap", "round"); return this; } - private LayerStyleBuilder type(LayerType type) { + private StyleBuilder type(LayerType type) { props.put(TYPE, type.name().toLowerCase()); return this; } - public LayerStyleBuilder circleColor(String color) { + public StyleBuilder circleColor(String color) { paint.put("circle-color", validateColor(color)); return this; } - public LayerStyleBuilder circleStroke(String color, int width) { + public StyleBuilder circleStroke(String color, int width) { paint.put("circle-stroke-color", validateColor(color)); paint.put("circle-stroke-width", width); return this; } - public LayerStyleBuilder circleRadius(ZoomDependentNumber radius) { + public StyleBuilder circleRadius(ZoomDependentNumber radius) { paint.put("circle-radius", radius.toJson()); return this; } // Line styling - public LayerStyleBuilder lineColor(String color) { + public StyleBuilder lineColor(String color) { paint.put("line-color", validateColor(color)); return this; } - public LayerStyleBuilder lineWidth(float width) { + public StyleBuilder lineWidth(float width) { paint.put("line-width", width); return this; } - public LayerStyleBuilder lineWidth(ZoomDependentNumber zoomStops) { + public StyleBuilder lineWidth(ZoomDependentNumber zoomStops) { paint.put("line-width", zoomStops.toJson()); return this; } - public LayerStyleBuilder intiallyHidden() { + /** + * Hide this layer when the debug client starts. It can be made visible in the UI later. + */ + public StyleBuilder intiallyHidden() { layout.put("visibility", "none"); return this; } - // filtering edge + /** + * Only apply the style to the given edges. + */ @SafeVarargs - public final LayerStyleBuilder edgeFilter(Class... classToFilter) { + public final StyleBuilder edgeFilter(Class... classToFilter) { var clazzes = Arrays.stream(classToFilter).map(Class::getSimpleName).toList(); filter = ListUtils.combine(List.of("in", "class"), clazzes); return this; @@ -171,20 +175,4 @@ private void validate() { .of(TYPE) .forEach(p -> Objects.requireNonNull(props.get(p), "%s must be set".formatted(p))); } - - public record ZoomStop(int zoom, float value) { - public List toList() { - return List.of(zoom, value); - } - } - - public record ZoomDependentNumber(float base, List stops) { - public JsonNode toJson() { - var props = new LinkedHashMap<>(); - props.put("base", base); - var vals = stops.stream().map(ZoomStop::toList).toList(); - props.put("stops", vals); - return OBJECT_MAPPER.valueToTree(props); - } - } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java index 84e19f25364..64f680ed202 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleSpec.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,13 +16,13 @@ public final class StyleSpec { private final String name; - private final List sources; + private final Collection sources; private final List layers; - public StyleSpec(String name, List sources, List layers) { + public StyleSpec(String name, Collection sources, List layers) { this.name = name; this.sources = sources; - this.layers = layers.stream().map(LayerStyleBuilder::toJson).toList(); + this.layers = layers.stream().map(StyleBuilder::toJson).toList(); } @JsonSerialize diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java index 06af294a4f0..088ce63d10a 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/TileSource.java @@ -26,7 +26,7 @@ public String type() { * Represents a raster-based source for map tiles. These are used mainly for background * map layers with vector data being rendered on top of it. */ - record RasterSource(String id, List tiles, int tileSize, String attribution) + record RasterSource(String id, List tiles, int maxzoom, int tileSize, String attribution) implements TileSource { @Override public String type() { diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java new file mode 100644 index 00000000000..61f1b852d5a --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/VectorSourceLayer.java @@ -0,0 +1,8 @@ +package org.opentripplanner.apis.vectortiles.model; + +/** + * A vector source layer for use in a Maplibre style spec. It contains both the name of the layer + * inside the tile and a reference to the source (which in turn has the URL where to fetch the + * data). + */ +public record VectorSourceLayer(TileSource.VectorSource vectorSource, String vectorLayer) {} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java new file mode 100644 index 00000000000..d83c4b63495 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/ZoomDependentNumber.java @@ -0,0 +1,31 @@ +package org.opentripplanner.apis.vectortiles.model; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.LinkedHashMap; +import java.util.List; +import org.opentripplanner.framework.json.ObjectMappers; + +/** + * A style parameter that allows you to specify a number that changes dependent on the zoom level. + */ +public record ZoomDependentNumber(float base, List stops) { + private static final ObjectMapper OBJECT_MAPPER = ObjectMappers.ignoringExtraFields(); + public JsonNode toJson() { + var props = new LinkedHashMap<>(); + props.put("base", base); + var vals = stops.stream().map(ZoomStop::toList).toList(); + props.put("stops", vals); + return OBJECT_MAPPER.valueToTree(props); + } + + /** + * @param zoom The zoom level. + * @param value What the value should be at the specified zoom. + */ + public record ZoomStop(int zoom, float value) { + public List toList() { + return List.of(zoom, value); + } + } +} diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index 9a18da3e5c9..693ddbc2d79 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -3,8 +3,8 @@ import static org.opentripplanner.test.support.JsonAssertions.assertEqualJson; import org.junit.jupiter.api.Test; -import org.opentripplanner.apis.vectortiles.DebugStyleSpec.VectorSourceLayer; import org.opentripplanner.apis.vectortiles.model.TileSource.VectorSource; +import org.opentripplanner.apis.vectortiles.model.VectorSourceLayer; import org.opentripplanner.framework.json.ObjectMappers; import org.opentripplanner.test.support.ResourceLoader; @@ -15,9 +15,9 @@ class DebugStyleSpecTest { @Test void spec() { var vectorSource = new VectorSource("vectorSource", "https://example.com"); - var regularStops = new VectorSourceLayer(vectorSource, "regularStops"); + var stops = new VectorSourceLayer(vectorSource, "stops"); var edges = new VectorSourceLayer(vectorSource, "edges"); - var spec = DebugStyleSpec.build(vectorSource, regularStops, edges); + var spec = DebugStyleSpec.build(stops, edges); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RESOURCES.fileToString("style.json"); diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index df9f73c3f26..06a602a8cd3 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -1,4 +1,5 @@ { + "name" : "OTP Debug Tiles", "sources" : { "background" : { @@ -6,6 +7,7 @@ "tiles" : [ "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png" ], + "maxzoom" : 19, "tileSize" : 256, "attribution" : "© OpenStreetMap Contributors", "type" : "raster" @@ -23,30 +25,6 @@ "source" : "background", "minzoom" : 0 }, - { - "id" : "edge-fallback", - "type" : "line", - "source" : "vectorSource", - "source-layer" : "edges", - "minzoom" : 15, - "maxzoom" : 23, - "paint" : { - "line-color" : "#8e8e89", - "line-width" : { - "base" : 1.3, - "stops" : [ - [ - 13, - 2.0 - ], - [ - 23, - 10.0 - ] - ] - } - } - }, { "id" : "edge", "type" : "line", @@ -61,7 +39,7 @@ "stops" : [ [ 13, - 2.0 + 0.5 ], [ 23, @@ -76,9 +54,15 @@ "StreetEdge", "AreaEdge", "EscalatorEdge", + "PathwayEdge", + "ElevatorHopEdge", "TemporaryPartialStreetEdge", "TemporaryFreeEdge" - ] + ], + "layout" : { + "line-cap" : "round", + "visibility" : "none" + } }, { "id" : "link", @@ -88,13 +72,13 @@ "minzoom" : 13, "maxzoom" : 23, "paint" : { - "line-color" : "#e2d40d", + "line-color" : "#22DD9E", "line-width" : { "base" : 1.3, "stops" : [ [ 13, - 2.0 + 0.5 ], [ 23, @@ -111,21 +95,38 @@ "BoardingLocationToStopLink", "StreetVehicleRentalLink", "StreetVehicleParkingLink" - ] + ], + "layout" : { + "line-cap" : "round", + "visibility" : "none" + } }, { "id" : "regular-stop", "type" : "circle", "source" : "vectorSource", - "source-layer" : "regularStops", - "minzoom" : 11, + "source-layer" : "stops", + "minzoom" : 10, "maxzoom" : 23, "paint" : { "circle-stroke-color" : "#140d0e", "circle-stroke-width" : 2, + "circle-radius" : { + "base" : 1.0, + "stops" : [ + [ + 11, + 1.0 + ], + [ + 23, + 10.0 + ] + ] + }, "circle-color" : "#fcf9fa" } } ], "version" : 8 -} +} \ No newline at end of file From 760f939fb8a2febb6a5f19c3450444b1cdec5c30 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 15 Jan 2024 11:15:56 +0100 Subject: [PATCH 135/356] Rename class, document --- .../src/components/MapView/LayerControl.tsx | 14 ++++++++++---- client-next/src/components/MapView/MapView.tsx | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/client-next/src/components/MapView/LayerControl.tsx b/client-next/src/components/MapView/LayerControl.tsx index 4566c3679fc..237ea8ab150 100644 --- a/client-next/src/components/MapView/LayerControl.tsx +++ b/client-next/src/components/MapView/LayerControl.tsx @@ -1,12 +1,18 @@ import type { ControlPosition } from 'react-map-gl'; import { useControl } from 'react-map-gl'; -import { IControl, Map} from 'maplibre-gl'; +import { IControl, Map } from 'maplibre-gl'; type LayerControlProps = { position: ControlPosition; }; -class LayerList implements IControl { +/** + * A maplibre control that allows you to switch vector tile layers on and off. + * + * It appears that you cannot use React elements but have to drop down to raw DOM. Please correct + * me if I'm wrong. + */ +class LayerControl implements IControl { private readonly container: HTMLDivElement = document.createElement('div'); onAdd(map: Map) { @@ -67,8 +73,8 @@ class LayerList implements IControl { } } -export default function LayerListControl(props: LayerControlProps) { - useControl(() => new LayerList(), { +export default function DebugLayerControl(props: LayerControlProps) { + useControl(() => new LayerControl(), { position: props.position, }); diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index a3c925a2519..930c9ff9a58 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -7,7 +7,7 @@ import { useMapDoubleClick } from './useMapDoubleClick.ts'; import { useState } from 'react'; import { ContextMenuPopup } from './ContextMenuPopup.tsx'; import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx'; -import LayerListControl from './LayerControl.tsx'; +import DebugLayerControl from './LayerControl.tsx'; // TODO: this should be configurable const initialViewState = { @@ -76,7 +76,7 @@ export function MapView({ setTripQueryVariables={setTripQueryVariables} loading={loading} /> - + {tripQueryResult?.trip.tripPatterns.length && ( )} From 92a4b0c4f7f47cef3c3e5d84f2c6906a85270b34 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 15 Jan 2024 11:27:51 +0100 Subject: [PATCH 136/356] Automatically pan to correct world envelope --- .../src/components/MapView/MapView.tsx | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 930c9ff9a58..074c699ad0c 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -1,4 +1,12 @@ -import { LngLat, Map, MapGeoJSONFeature, MapMouseEvent, NavigationControl } from 'react-map-gl/maplibre'; +import { + LngLat, + Map, + MapEvent, + MapGeoJSONFeature, + MapMouseEvent, + NavigationControl, + VectorTileSource, +} from 'react-map-gl/maplibre'; import 'maplibre-gl/dist/maplibre-gl.css'; import { TripPattern, TripQuery, TripQueryVariables } from '../../gql/graphql.ts'; import { NavigationMarkers } from './NavigationMarkers.tsx'; @@ -9,13 +17,6 @@ import { ContextMenuPopup } from './ContextMenuPopup.tsx'; import { GeometryPropertyPopup } from './GeometryPropertyPopup.tsx'; import DebugLayerControl from './LayerControl.tsx'; -// TODO: this should be configurable -const initialViewState = { - latitude: 60.7554885, - longitude: 10.2332855, - zoom: 4, -}; - const styleUrl = import.meta.env.VITE_DEBUG_STYLE_URL; type PopupData = { coordinates: LngLat; feature: MapGeoJSONFeature }; @@ -49,6 +50,17 @@ export function MapView({ setShowPropsPopup({ coordinates: e.lngLat, feature: feature }); } }; + const panToWorldEnvelopeIfRequired = (e: MapEvent) => { + const map = e.target; + // if we are really far zoomed out and show the entire world it means that we are not starting + // in a location selected from the URL hash. + // in such a case we pan to the area that is specified in the stop's tile bounds, which is + // provided by the WorldEnvelopeService + if (map.getZoom() < 2) { + const source = map.getSource('stops') as VectorTileSource; + map.fitBounds(source.bounds, { maxDuration: 50, linear: true }); + } + }; return (
      @@ -57,7 +69,6 @@ export function MapView({ mapLib={import('maplibre-gl')} // @ts-ignore mapStyle={styleUrl} - initialViewState={initialViewState} onDblClick={onMapDoubleClick} onContextMenu={(e) => { setShowContextPopup(e.lngLat); @@ -69,6 +80,7 @@ export function MapView({ // disable pitching and rotating the map touchPitch={false} dragRotate={false} + onLoad={panToWorldEnvelopeIfRequired} > Date: Mon, 15 Jan 2024 11:38:05 +0100 Subject: [PATCH 137/356] Last polishing --- client-next/src/components/MapView/MapView.tsx | 4 +++- .../apis/vectortiles/GraphInspectorVectorTileResource.java | 2 +- .../inspector/vector/{edges => edge}/EdgeLayerBuilder.java | 5 ++++- .../inspector/vector/{edges => edge}/EdgePropertyMapper.java | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) rename src/main/java/org/opentripplanner/inspector/vector/{edges => edge}/EdgeLayerBuilder.java (90%) rename src/main/java/org/opentripplanner/inspector/vector/{edges => edge}/EdgePropertyMapper.java (95%) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 074c699ad0c..fa0bfbd022b 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -54,7 +54,7 @@ export function MapView({ const map = e.target; // if we are really far zoomed out and show the entire world it means that we are not starting // in a location selected from the URL hash. - // in such a case we pan to the area that is specified in the stop's tile bounds, which is + // in such a case we pan to the area that is specified in the tile bounds, which is // provided by the WorldEnvelopeService if (map.getZoom() < 2) { const source = map.getSource('stops') as VectorTileSource; @@ -73,6 +73,8 @@ export function MapView({ onContextMenu={(e) => { setShowContextPopup(e.lngLat); }} + // it's unfortunate that you have to list these layers here. + // maybe there is a way around it: https://github.com/visgl/react-map-gl/discussions/2343 interactiveLayerIds={['regular-stop', 'edge-fallback', 'edge', 'link']} onClick={showFeaturePropPopup} // put lat/long in URL and pan to it on page reload diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index b43cd5c109f..c8cd3a089f3 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -31,7 +31,7 @@ import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.inspector.vector.VectorTileResponseFactory; -import org.opentripplanner.inspector.vector.edges.EdgeLayerBuilder; +import org.opentripplanner.inspector.vector.edge.EdgeLayerBuilder; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; import org.opentripplanner.inspector.vector.stop.StopLayerBuilder; import org.opentripplanner.model.FeedInfo; diff --git a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java similarity index 90% rename from src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java rename to src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java index 60e65f7b35a..3823f91f039 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgeLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgeLayerBuilder.java @@ -1,4 +1,4 @@ -package org.opentripplanner.inspector.vector.edges; +package org.opentripplanner.inspector.vector.edge; import java.util.List; import org.locationtech.jts.geom.Envelope; @@ -9,6 +9,9 @@ import org.opentripplanner.routing.graph.index.StreetIndex; import org.opentripplanner.street.model.edge.Edge; +/** + * Selects all edges to be displayed for debugging. + */ public class EdgeLayerBuilder extends LayerBuilder { private final StreetIndex streetIndex; diff --git a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java similarity index 95% rename from src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java rename to src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java index 5bfc2dc6df7..fb65d0b5d3b 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/edges/EdgePropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/edge/EdgePropertyMapper.java @@ -1,4 +1,4 @@ -package org.opentripplanner.inspector.vector.edges; +package org.opentripplanner.inspector.vector.edge; import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; import static org.opentripplanner.inspector.vector.KeyValue.kv; From 8af89a0d21f558bacdf16dab488b68a4082d2611 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 15 Jan 2024 13:08:25 +0100 Subject: [PATCH 138/356] Fix leg based fares --- .../fares/impl/DefaultFareServiceTest.java | 40 ++++++++++++++--- .../ext/fares/impl/FareModelForTest.java | 44 +++++++++++++------ .../ext/fares/impl/DefaultFareService.java | 18 ++++++-- .../ext/fares/model/FareRuleSet.java | 22 ++-------- .../model/fare/ItineraryFares.java | 1 + .../__snapshots__/BikeRentalSnapshotTest.snap | 24 +++++----- .../__snapshots__/ElevationSnapshotTest.snap | 12 ++--- .../__snapshots__/TransitSnapshotTest.snap | 26 +++++------ 8 files changed, 115 insertions(+), 72 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index f306b61ee50..c5e26cc3c9b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -7,6 +7,8 @@ import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_TO_CITY_CENTER_SET; import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_A_STOP; import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_B_STOP; +import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_C_STOP; +import static org.opentripplanner.ext.fares.impl.FareModelForTest.FREE_TRANSFERS_IN_CITY_SET; import static org.opentripplanner.ext.fares.impl.FareModelForTest.INSIDE_CITY_CENTER_SET; import static org.opentripplanner.ext.fares.impl.FareModelForTest.OTHER_FEED_ATTRIBUTE; import static org.opentripplanner.ext.fares.impl.FareModelForTest.OTHER_FEED_ROUTE; @@ -61,6 +63,34 @@ void simpleZoneBasedFare() { assertEquals(TEN_DOLLARS, product.price()); } + @Test + void applyToSeveralLegs() { + var service = new DefaultFareService(); + service.addFareRules(FareType.regular, List.of(FREE_TRANSFERS_IN_CITY_SET)); + var itin = newItinerary(Place.forStop(CITY_CENTER_A_STOP), T11_00) + .bus(1, T11_00, T11_12, Place.forStop(CITY_CENTER_B_STOP)) + .bus(1, T11_16, T11_20, Place.forStop(CITY_CENTER_C_STOP)) + .build(); + + var fare = service.calculateFares(itin); + assertNotNull(fare); + + var legProducts = fare.getLegProducts(); + + var firstLeg = itin.getTransitLeg(0); + var secondLeg = itin.getTransitLeg(1); + + var firstProducts = legProducts.get(firstLeg); + var secondProducts = legProducts.get(secondLeg); + + assertEquals(firstProducts, secondProducts); + + assertEquals( + "[FareProductUse[id=ddbf1572-18bc-3724-8b64-e1c7d5c8b6c6, product=FareProduct{id: 'F:free-transfers', amount: $20.00}]]", + firstProducts.toString() + ); + } + @Test void shouldNotCombineInterlinedLegs() { var service = new DefaultFareService(); @@ -89,17 +119,17 @@ void shouldNotCombineInterlinedLegs() { var legProducts = fare.getLegProducts(); - var firstLeg = itin.getLegs().get(0); + var firstLeg = itin.getLegs().getFirst(); var products = List.copyOf(legProducts.get(firstLeg)); - assertEquals(TEN_DOLLARS, products.get(0).product().price()); + assertEquals(TEN_DOLLARS, products.getFirst().product().price()); var secondLeg = itin.getLegs().get(1); products = List.copyOf(legProducts.get(secondLeg)); - assertEquals(TEN_DOLLARS, products.get(0).product().price()); + assertEquals(TEN_DOLLARS, products.getFirst().product().price()); assertEquals(1, fare.getItineraryProducts().size()); - assertEquals(TWENTY_DOLLARS, fare.getItineraryProducts().get(0).price()); + assertEquals(TWENTY_DOLLARS, fare.getItineraryProducts().getFirst().price()); } @Test @@ -187,7 +217,7 @@ void multipleFeedsWithTransfersWithinFeed() { legProducts.get(secondBusLeg).toString() ); assertEquals( - "[FareProductUse[id=678d201c-e839-35c3-ae7b-1bc3834da5e5, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", legProducts.get(finalBusLeg).toString() ); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java index 200220587a6..e498588d00f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FareModelForTest.java @@ -6,6 +6,7 @@ import org.opentripplanner.ext.fares.model.FareAttribute; import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.framework.geometry.WgsCoordinate; +import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; @@ -27,44 +28,56 @@ public class FareModelForTest { private static final StopModelBuilder STOP_MODEL_BUILDER = StopModel.of(); - static RegularStop AIRPORT_STOP = STOP_MODEL_BUILDER + static final RegularStop AIRPORT_STOP = STOP_MODEL_BUILDER .regularStop(id("airport")) .withCoordinate(new WgsCoordinate(1, 1)) .addFareZones(AIRPORT_ZONE) - .withName(new NonLocalizedString("Airport")) + .withName(I18NString.of("Airport")) .build(); - static RegularStop CITY_CENTER_A_STOP = STOP_MODEL_BUILDER + static final RegularStop CITY_CENTER_A_STOP = STOP_MODEL_BUILDER .regularStop(id("city-center-a")) .withCoordinate(new WgsCoordinate(1, 2)) .addFareZones(CITY_CENTER_ZONE) - .withName(new NonLocalizedString("City center: stop A")) + .withName(I18NString.of("City center: stop A")) .build(); - static RegularStop CITY_CENTER_B_STOP = STOP_MODEL_BUILDER + static final RegularStop CITY_CENTER_B_STOP = STOP_MODEL_BUILDER .regularStop(id("city-center-b")) .withCoordinate(new WgsCoordinate(1, 3)) .addFareZones(CITY_CENTER_ZONE) - .withName(new NonLocalizedString("City center: stop B")) + .withName(I18NString.of("City center: stop B")) .build(); - static RegularStop SUBURB_STOP = STOP_MODEL_BUILDER + static final RegularStop CITY_CENTER_C_STOP = STOP_MODEL_BUILDER + .regularStop(id("city-center-c")) + .withCoordinate(new WgsCoordinate(1, 4)) + .addFareZones(CITY_CENTER_ZONE) + .withName(I18NString.of("City center: stop C")) + .build(); + static final RegularStop SUBURB_STOP = STOP_MODEL_BUILDER .regularStop(id("suburb")) .withCoordinate(new WgsCoordinate(1, 4)) - .withName(new NonLocalizedString("Suburb")) + .withName(I18NString.of("Suburb")) .build(); - static RegularStop OTHER_FEED_STOP = STOP_MODEL_BUILDER + static final RegularStop OTHER_FEED_STOP = STOP_MODEL_BUILDER .regularStop(FeedScopedId.ofNullable("F2", "other-feed-stop")) .withCoordinate(new WgsCoordinate(1, 5)) - .withName(new NonLocalizedString("Other feed stop")) + .withName(I18NString.of("Other feed stop")) .addFareZones(OTHER_FEED_ZONE) .build(); - static FareAttribute TEN_DOLLARS = FareAttribute + static final FareAttribute TEN_DOLLARS = FareAttribute .of(id("airport-to-city-center")) .setPrice(Money.usDollars(10)) .setTransfers(0) .build(); - static FareAttribute OTHER_FEED_ATTRIBUTE = FareAttribute + static final FareAttribute FREE_TRANSFERS = FareAttribute + .of(id("free-transfers")) + .setPrice(Money.usDollars(20)) + .setTransfers(10) + .build(); + + static final FareAttribute OTHER_FEED_ATTRIBUTE = FareAttribute .of(FeedScopedId.ofNullable("F2", "other-feed-attribute")) .setPrice(Money.usDollars(10)) .setTransfers(1) @@ -74,6 +87,7 @@ public class FareModelForTest { // Fare rule sets static FareRuleSet AIRPORT_TO_CITY_CENTER_SET = new FareRuleSet(TEN_DOLLARS); static FareRuleSet INSIDE_CITY_CENTER_SET = new FareRuleSet(TEN_DOLLARS); + static FareRuleSet FREE_TRANSFERS_IN_CITY_SET = new FareRuleSet(FREE_TRANSFERS); static FareRuleSet OTHER_FEED_SET = new FareRuleSet(OTHER_FEED_ATTRIBUTE); @@ -82,6 +96,10 @@ public class FareModelForTest { AIRPORT_ZONE.getId().getId(), CITY_CENTER_ZONE.getId().getId() ); + FREE_TRANSFERS_IN_CITY_SET.addOriginDestination( + CITY_CENTER_ZONE.getId().getId(), + CITY_CENTER_ZONE.getId().getId() + ); INSIDE_CITY_CENTER_SET.addOriginDestination( CITY_CENTER_ZONE.getId().getId(), CITY_CENTER_ZONE.getId().getId() @@ -95,7 +113,7 @@ public class FareModelForTest { static Route OTHER_FEED_ROUTE = Route .of(new FeedScopedId("F2", "other-feed-route")) .withAgency(OTHER_FEED_AGENCY) - .withLongName(new NonLocalizedString("other-feed-route")) + .withLongName(I18NString.of("other-feed-route")) .withMode(TransitMode.BUS) .build(); } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index f0d957bf4ff..0bc4408b635 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -259,24 +259,34 @@ protected boolean populateFare( float cost = r.resultTable[start][via]; FeedScopedId fareId = r.fareIds[start][via]; var product = FareProduct - .of(fareId, fareId.toString(), Money.ofFractionalAmount(currency, cost)) + .of(fareId, fareType.name(), Money.ofFractionalAmount(currency, cost)) .build(); + List applicableLegs = new ArrayList<>(); for (int i = start; i <= via; ++i) { final var leg = legs.get(i); - final var use = new FareProductUse(product.uniqueInstanceId(leg.getStartTime()), product); // if we have a leg that is combined for the purpose of fare calculation we need to // retrieve the original legs so that the fare products are assigned back to the original // legs that the combined one originally consisted of. // (remember that the combined leg only exists during fare calculation and is thrown away // afterwards to associating fare products with it will result in the API not showing any.) if (leg instanceof CombinedInterlinedTransitLeg combinedLeg) { - combinedLeg.originalLegs().forEach(l -> fareProductUses.put(l, use)); + applicableLegs.addAll(combinedLeg.originalLegs()); } else { - fareProductUses.put(leg, use); + applicableLegs.add(leg); } } + if (!applicableLegs.isEmpty()) { + final var use = new FareProductUse( + product.uniqueInstanceId(applicableLegs.getFirst().getStartTime()), + product + ); + applicableLegs.forEach(leg -> { + fareProductUses.put(leg, use); + }); + } + ++count; start = via + 1; } diff --git a/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java b/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java index 61e813e6ea4..30119631216 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java +++ b/src/ext/java/org/opentripplanner/ext/fares/model/FareRuleSet.java @@ -15,7 +15,6 @@ public class FareRuleSet implements Serializable { private final Set routeOriginDestinations; private final Set contains; private final FareAttribute fareAttribute; - private final Set trips; public FareRuleSet(FareAttribute fareAttribute) { this.fareAttribute = fareAttribute; @@ -23,7 +22,6 @@ public FareRuleSet(FareAttribute fareAttribute) { originDestinations = new HashSet<>(); routeOriginDestinations = new HashSet<>(); contains = new HashSet<>(); - trips = new HashSet<>(); } public void addOriginDestination(String origin, String destination) { @@ -62,14 +60,6 @@ public FareAttribute getFareAttribute() { return fareAttribute; } - public void addTrip(FeedScopedId trip) { - trips.add(trip); - } - - public Set getTrips() { - return trips; - } - public boolean matches( String startZone, String endZone, @@ -81,7 +71,7 @@ public boolean matches( Duration journeyTime ) { //check for matching origin/destination, if this ruleset has any origin/destination restrictions - if (originDestinations.size() > 0) { + if (!originDestinations.isEmpty()) { var od = new OriginDestination(startZone, endZone); if (!originDestinations.contains(od)) { var od2 = new OriginDestination(od.origin, null); @@ -95,25 +85,19 @@ public boolean matches( } //check for matching contains, if this ruleset has any containment restrictions - if (contains.size() > 0) { + if (!contains.isEmpty()) { if (!zonesVisited.equals(contains)) { return false; } } //check for matching routes - if (routes.size() != 0) { + if (!routes.isEmpty()) { if (!routes.containsAll(routesVisited)) { return false; } } - //check for matching trips - if (trips.size() != 0) { - if (!trips.containsAll(tripsVisited)) { - return false; - } - } if (fareAttribute.isTransfersSet() && fareAttribute.getTransfers() < transfersUsed) { return false; } diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 80af574636a..d60dbfb249e 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -94,6 +94,7 @@ public void addItineraryProducts(Collection products) { * instead. */ @Nullable + @Deprecated public Money getFare(FareType type) { return fares.get(type); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap index 36c56471be1..41bc4278ca1 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap @@ -51,7 +51,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -537,7 +537,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -981,7 +981,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -1321,7 +1321,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -1807,7 +1807,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -2293,7 +2293,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -3308,7 +3308,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -3846,7 +3846,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -4264,7 +4264,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -4656,7 +4656,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -5194,7 +5194,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -5612,7 +5612,7 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap index 5baa72515ec..6579e4bbd37 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap @@ -579,7 +579,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -973,7 +973,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -1393,7 +1393,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -1787,7 +1787,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -2259,7 +2259,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -2653,7 +2653,7 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap index 8c36afa32e6..d5da342f9a6 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap @@ -279,7 +279,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -762,7 +762,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -1310,7 +1310,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -1793,7 +1793,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -2341,7 +2341,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] }, @@ -2361,7 +2361,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -3088,7 +3088,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -3574,7 +3574,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -4060,7 +4060,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -4546,7 +4546,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] }, @@ -4566,7 +4566,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } @@ -5072,7 +5072,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] }, @@ -5092,7 +5092,7 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan } }, "id" : "prt:8", - "name" : "prt:8" + "name" : "regular" } ] } From 61ab71e1bffb7c68038a01e242bfd6965ffbf9ad Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 15 Jan 2024 17:35:17 +0100 Subject: [PATCH 139/356] Add vertices layer builder --- .../GraphInspectorVectorTileResource.java | 3 ++ .../apis/vectortiles/model/LayerType.java | 1 + .../vector/vertex/VertexLayerBuilder.java | 37 +++++++++++++++++++ .../vector/vertex/VertexPropertyMapper.java | 29 +++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java create mode 100644 src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index c8cd3a089f3..6870f523fcf 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -34,6 +34,7 @@ import org.opentripplanner.inspector.vector.edge.EdgeLayerBuilder; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; import org.opentripplanner.inspector.vector.stop.StopLayerBuilder; +import org.opentripplanner.inspector.vector.vertex.VertexLayerBuilder; import org.opentripplanner.model.FeedInfo; import org.opentripplanner.standalone.api.OtpServerRequestContext; @@ -51,6 +52,7 @@ public class GraphInspectorVectorTileResource { GeofencingZones ); private static final LayerParams EDGES = new LayerParams("edges", Edges); + private static final LayerParams VERTICES = new LayerParams("vertices", Edges); private static final List> DEBUG_LAYERS = List.of( REGULAR_STOPS, AREA_STOPS, @@ -181,6 +183,7 @@ private static LayerBuilder createLayerBuilder( ); case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); case Edges -> new EdgeLayerBuilder(context.graph(), layerParameters); + case Vertices -> new VertexLayerBuilder(context.graph(), layerParameters); }; } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java index 4324a511a6b..4d73b0a14bd 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java @@ -5,4 +5,5 @@ public enum LayerType { AreaStop, GeofencingZones, Edges, + Vertices } diff --git a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java new file mode 100644 index 00000000000..e7aadb6be9e --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java @@ -0,0 +1,37 @@ +package org.opentripplanner.inspector.vector.vertex; + +import java.util.List; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.inspector.vector.LayerBuilder; +import org.opentripplanner.inspector.vector.LayerParameters; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.routing.graph.index.StreetIndex; +import org.opentripplanner.street.model.vertex.Vertex; + +/** + * Selects all vertices to be displayed for debugging. + */ +public class VertexLayerBuilder extends LayerBuilder { + + private final StreetIndex streetIndex; + + public VertexLayerBuilder(Graph graph, LayerParameters layerParameters) { + super(new VertexPropertyMapper(), layerParameters.name(), layerParameters.expansionFactor()); + this.streetIndex = graph.getStreetIndex(); + } + + @Override + protected List getGeometries(Envelope query) { + return streetIndex + .getEdgesForEnvelope(query) + .stream() + .filter(e -> e.getGeometry() != null) + .map(edge -> { + Geometry geometry = edge.getGeometry(); + geometry.setUserData(edge); + return geometry; + }) + .toList(); + } +} diff --git a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java new file mode 100644 index 00000000000..b2deda9647c --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java @@ -0,0 +1,29 @@ +package org.opentripplanner.inspector.vector.vertex; + +import static org.opentripplanner.inspector.vector.KeyValue.kv; + +import java.util.Collection; +import java.util.List; +import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.framework.collection.ListUtils; +import org.opentripplanner.inspector.vector.KeyValue; +import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; +import org.opentripplanner.street.model.vertex.BarrierVertex; +import org.opentripplanner.street.model.vertex.Vertex; + +public class VertexPropertyMapper extends PropertyMapper { + + @Override + protected Collection map(Vertex input) { + List baseProps = List.of(kv("class", input.getClass().getSimpleName())); + List properties = + switch (input) { + case BarrierVertex v -> List.of( + kv("permission", v.getBarrierPermissions().toString()) + ); + case VehicleRentalPlaceVertex v -> List.of(kv("rentalId", v.getStation().getId())); + default -> List.of(); + }; + return ListUtils.combine(baseProps, properties); + } +} From c9bbc7d75b26eae9b2c537741d83c418e9abe4a1 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 07:20:07 +0100 Subject: [PATCH 140/356] Add vertices to debug tiles --- .../src/components/MapView/MapView.tsx | 4 +-- .../apis/vectortiles/DebugStyleSpec.java | 25 ++++++++++++++++--- .../GraphInspectorVectorTileResource.java | 19 ++++++++------ .../apis/vectortiles/model/LayerType.java | 4 +-- .../vector/vertex/VertexLayerBuilder.java | 10 ++++---- .../vector/vertex/VertexPropertyMapper.java | 9 ++++--- .../apis/vectortiles/DebugStyleSpecTest.java | 2 +- 7 files changed, 48 insertions(+), 25 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index fa0bfbd022b..11aa41476d3 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -58,7 +58,7 @@ export function MapView({ // provided by the WorldEnvelopeService if (map.getZoom() < 2) { const source = map.getSource('stops') as VectorTileSource; - map.fitBounds(source.bounds, { maxDuration: 50, linear: true }); + map.fitBounds(source.bounds, { maxDuration: 50, linear: true}); } }; @@ -75,7 +75,7 @@ export function MapView({ }} // it's unfortunate that you have to list these layers here. // maybe there is a way around it: https://github.com/visgl/react-map-gl/discussions/2343 - interactiveLayerIds={['regular-stop', 'edge-fallback', 'edge', 'link']} + interactiveLayerIds={['regular-stop', 'vertex', 'edge', 'link']} onClick={showFeaturePropPopup} // put lat/long in URL and pan to it on page reload hash={true} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index 2393125f780..fd3254bdb05 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -38,14 +38,22 @@ public class DebugStyleSpec { ); private static final String MAGENTA = "#f21d52"; private static final String GREEN = "#22DD9E"; + private static final String PURPLE = "#BC55F2"; private static final int MAX_ZOOM = 23; private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( 1.3f, List.of(new ZoomStop(13, 0.5f), new ZoomStop(MAX_ZOOM, 10)) ); + private static final String BLACK = "#140d0e"; - static StyleSpec build(VectorSourceLayer regularStops, VectorSourceLayer edges) { - var vectorSources = Stream.of(regularStops, edges).map(VectorSourceLayer::vectorSource); + static StyleSpec build( + VectorSourceLayer regularStops, + VectorSourceLayer edges, + VectorSourceLayer vertices + ) { + var vectorSources = Stream + .of(regularStops, edges, vertices) + .map(VectorSourceLayer::vectorSource); var allSources = Stream .concat(Stream.of(BACKGROUND_SOURCE), vectorSources) .collect(Collectors.toSet()); @@ -88,11 +96,22 @@ static StyleSpec build(VectorSourceLayer regularStops, VectorSourceLayer edges) .minZoom(13) .maxZoom(MAX_ZOOM) .intiallyHidden(), + StyleBuilder + .ofId("vertex") + .typeCircle() + .vectorSourceLayer(vertices) + .circleStroke(BLACK, 2) + .circleRadius( + new ZoomDependentNumber(1, List.of(new ZoomStop(15, 1), new ZoomStop(MAX_ZOOM, 5))) + ) + .circleColor(PURPLE) + .minZoom(15) + .maxZoom(MAX_ZOOM), StyleBuilder .ofId("regular-stop") .typeCircle() .vectorSourceLayer(regularStops) - .circleStroke("#140d0e", 2) + .circleStroke(BLACK, 2) .circleRadius( new ZoomDependentNumber(1, List.of(new ZoomStop(11, 1), new ZoomStop(MAX_ZOOM, 10))) ) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 6870f523fcf..5d0778eae6d 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -1,8 +1,9 @@ package org.opentripplanner.apis.vectortiles; -import static org.opentripplanner.apis.vectortiles.model.LayerType.Edges; +import static org.opentripplanner.apis.vectortiles.model.LayerType.Edge; import static org.opentripplanner.apis.vectortiles.model.LayerType.GeofencingZones; import static org.opentripplanner.apis.vectortiles.model.LayerType.RegularStop; +import static org.opentripplanner.apis.vectortiles.model.LayerType.Vertex; import static org.opentripplanner.framework.io.HttpUtils.APPLICATION_X_PROTOBUF; import jakarta.ws.rs.GET; @@ -51,13 +52,14 @@ public class GraphInspectorVectorTileResource { "geofencingZones", GeofencingZones ); - private static final LayerParams EDGES = new LayerParams("edges", Edges); - private static final LayerParams VERTICES = new LayerParams("vertices", Edges); + private static final LayerParams EDGES = new LayerParams("edges", Edge); + private static final LayerParams VERTICES = new LayerParams("vertices", Vertex); private static final List> DEBUG_LAYERS = List.of( REGULAR_STOPS, AREA_STOPS, GEOFENCING_ZONES, - EDGES + EDGES, + VERTICES ); private final OtpServerRequestContext serverContext; @@ -133,12 +135,13 @@ public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) ); var streetSource = new VectorSource( "street", - tileJsonUrl(base, List.of(EDGES, GEOFENCING_ZONES)) + tileJsonUrl(base, List.of(EDGES, GEOFENCING_ZONES, VERTICES)) ); return DebugStyleSpec.build( REGULAR_STOPS.toVectorSourceLayer(stopsSource), - EDGES.toVectorSourceLayer(streetSource) + EDGES.toVectorSourceLayer(streetSource), + VERTICES.toVectorSourceLayer(streetSource) ); } @@ -182,8 +185,8 @@ private static LayerBuilder createLayerBuilder( e -> context.transitService().findAreaStops(e) ); case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); - case Edges -> new EdgeLayerBuilder(context.graph(), layerParameters); - case Vertices -> new VertexLayerBuilder(context.graph(), layerParameters); + case Edge -> new EdgeLayerBuilder(context.graph(), layerParameters); + case Vertex -> new VertexLayerBuilder(context.graph(), layerParameters); }; } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java index 4d73b0a14bd..ece75f29b60 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java @@ -4,6 +4,6 @@ public enum LayerType { RegularStop, AreaStop, GeofencingZones, - Edges, - Vertices + Edge, + Vertex, } diff --git a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java index e7aadb6be9e..0b3bb79b72e 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java +++ b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexLayerBuilder.java @@ -3,6 +3,7 @@ import java.util.List; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.routing.graph.Graph; @@ -24,12 +25,11 @@ public VertexLayerBuilder(Graph graph, LayerParameters layerParameters) { @Override protected List getGeometries(Envelope query) { return streetIndex - .getEdgesForEnvelope(query) + .getVerticesForEnvelope(query) .stream() - .filter(e -> e.getGeometry() != null) - .map(edge -> { - Geometry geometry = edge.getGeometry(); - geometry.setUserData(edge); + .map(vertex -> { + Geometry geometry = GeometryUtils.getGeometryFactory().createPoint(vertex.getCoordinate()); + geometry.setUserData(vertex); return geometry; }) .toList(); diff --git a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java index b2deda9647c..a493269cc3b 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java +++ b/src/main/java/org/opentripplanner/inspector/vector/vertex/VertexPropertyMapper.java @@ -15,12 +15,13 @@ public class VertexPropertyMapper extends PropertyMapper { @Override protected Collection map(Vertex input) { - List baseProps = List.of(kv("class", input.getClass().getSimpleName())); + List baseProps = List.of( + kv("class", input.getClass().getSimpleName()), + kv("label", input.getLabel().toString()) + ); List properties = switch (input) { - case BarrierVertex v -> List.of( - kv("permission", v.getBarrierPermissions().toString()) - ); + case BarrierVertex v -> List.of(kv("permission", v.getBarrierPermissions().toString())); case VehicleRentalPlaceVertex v -> List.of(kv("rentalId", v.getStation().getId())); default -> List.of(); }; diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index 693ddbc2d79..af7598285e1 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -17,7 +17,7 @@ void spec() { var vectorSource = new VectorSource("vectorSource", "https://example.com"); var stops = new VectorSourceLayer(vectorSource, "stops"); var edges = new VectorSourceLayer(vectorSource, "edges"); - var spec = DebugStyleSpec.build(stops, edges); + var spec = DebugStyleSpec.build(stops, edges, VERTICES.toVectorSourceLayer(streetSource)); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RESOURCES.fileToString("style.json"); From c6306b8bd0eb50f9e4d02a5a75159c9d99d07f45 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 11:24:05 +0100 Subject: [PATCH 141/356] Set 2.0 as the version the MQTT updater was added --- docs/UpdaterConfig.md | 10 +++++----- .../updaters/MqttGtfsRealtimeUpdaterConfig.java | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/UpdaterConfig.md b/docs/UpdaterConfig.md index 212a2d55370..a819a898240 100644 --- a/docs/UpdaterConfig.md +++ b/docs/UpdaterConfig.md @@ -179,11 +179,11 @@ This system powers the realtime updates in Helsinki and more information can be |-----------------------------------------------------------------------|:---------:|----------------------------------------------|:----------:|----------------------|:-----:| | type = "mqtt-gtfs-rt-updater" | `enum` | The type of the updater. | *Required* | | 1.5 | | [backwardsDelayPropagationType](#u__6__backwardsDelayPropagationType) | `enum` | How backwards propagation should be handled. | *Optional* | `"required-no-data"` | 2.2 | -| feedId | `string` | The feed id to apply the updates to. | *Required* | | na | -| fuzzyTripMatching | `boolean` | Whether to match trips fuzzily. | *Optional* | `false` | na | -| qos | `integer` | QOS level. | *Optional* | `0` | na | -| topic | `string` | The topic to subscribe to. | *Required* | | na | -| url | `string` | URL of the MQTT broker. | *Required* | | na | +| feedId | `string` | The feed id to apply the updates to. | *Required* | | 2.0 | +| fuzzyTripMatching | `boolean` | Whether to match trips fuzzily. | *Optional* | `false` | 2.0 | +| qos | `integer` | QOS level. | *Optional* | `0` | 2.0 | +| topic | `string` | The topic to subscribe to. | *Required* | | 2.0 | +| url | `string` | URL of the MQTT broker. | *Required* | | 2.0 | ##### Parameter details diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java index 372bd36227e..ccc4ca5e80f 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/updaters/MqttGtfsRealtimeUpdaterConfig.java @@ -1,6 +1,6 @@ package org.opentripplanner.standalone.config.routerconfig.updaters; -import static org.opentripplanner.standalone.config.framework.json.OtpVersion.NA; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -12,13 +12,13 @@ public class MqttGtfsRealtimeUpdaterConfig { public static MqttGtfsRealtimeUpdaterParameters create(String configRef, NodeAdapter c) { return new MqttGtfsRealtimeUpdaterParameters( configRef, - c.of("feedId").since(NA).summary("The feed id to apply the updates to.").asString(), - c.of("url").since(NA).summary("URL of the MQTT broker.").asString(), - c.of("topic").since(NA).summary("The topic to subscribe to.").asString(), - c.of("qos").since(NA).summary("QOS level.").asInt(0), + c.of("feedId").since(V2_0).summary("The feed id to apply the updates to.").asString(), + c.of("url").since(V2_0).summary("URL of the MQTT broker.").asString(), + c.of("topic").since(V2_0).summary("The topic to subscribe to.").asString(), + c.of("qos").since(V2_0).summary("QOS level.").asInt(0), c .of("fuzzyTripMatching") - .since(NA) + .since(V2_0) .summary("Whether to match trips fuzzily.") .asBoolean(false), c From cec3655f5e55b2b2666fe554b407f6322c52f15d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 13:02:03 +0100 Subject: [PATCH 142/356] Add comment to visualizer [ci skip] --- .../java/org/opentripplanner/visualizer/GraphVisualizer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java index 73516b0348f..9f8bbffb22d 100644 --- a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java +++ b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java @@ -157,6 +157,10 @@ public DisplayVertex getElementAt(int index) { * TransitStops only, and allows a user to select stops, examine incoming and outgoing edges, and * examine trip patterns. It's meant mainly for debugging, so it's totally OK if it develops (say) a * bunch of weird buttons designed to debug specific cases. + *

      + * 2024-01-26: We talked about the visualizer in the developer meeting and while the code is a bit + * dusty, we decided that we want to keep the option open to build make the visualization of routing + * steps work again in the future and won't delete it. */ public class GraphVisualizer extends JFrame implements VertexSelectionListener { From f1a9be02e20373fa33776e9d38d3478ede8f6932 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 13:17:30 +0100 Subject: [PATCH 143/356] Update vertex styles --- .../src/components/MapView/MapView.tsx | 2 +- .../apis/vectortiles/DebugStyleSpec.java | 13 ++++-- .../apis/vectortiles/model/StyleBuilder.java | 6 +++ .../apis/vectortiles/DebugStyleSpecTest.java | 3 +- .../apis/vectortiles/style.json | 44 ++++++++++++++++++- 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 11aa41476d3..51cb39068f8 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -58,7 +58,7 @@ export function MapView({ // provided by the WorldEnvelopeService if (map.getZoom() < 2) { const source = map.getSource('stops') as VectorTileSource; - map.fitBounds(source.bounds, { maxDuration: 50, linear: true}); + map.fitBounds(source.bounds, { maxDuration: 50, linear: true }); } }; diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index fd3254bdb05..f7ca564b149 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -39,12 +39,16 @@ public class DebugStyleSpec { private static final String MAGENTA = "#f21d52"; private static final String GREEN = "#22DD9E"; private static final String PURPLE = "#BC55F2"; + private static final String BLACK = "#140d0e"; private static final int MAX_ZOOM = 23; private static final ZoomDependentNumber LINE_WIDTH = new ZoomDependentNumber( 1.3f, List.of(new ZoomStop(13, 0.5f), new ZoomStop(MAX_ZOOM, 10)) ); - private static final String BLACK = "#140d0e"; + private static final ZoomDependentNumber CIRCLE_STROKE = new ZoomDependentNumber( + 1, + List.of(new ZoomStop(15, 0.2f), new ZoomStop(MAX_ZOOM, 3)) + ); static StyleSpec build( VectorSourceLayer regularStops, @@ -100,13 +104,14 @@ static StyleSpec build( .ofId("vertex") .typeCircle() .vectorSourceLayer(vertices) - .circleStroke(BLACK, 2) + .circleStroke(BLACK, CIRCLE_STROKE) .circleRadius( - new ZoomDependentNumber(1, List.of(new ZoomStop(15, 1), new ZoomStop(MAX_ZOOM, 5))) + new ZoomDependentNumber(1, List.of(new ZoomStop(15, 1), new ZoomStop(MAX_ZOOM, 7))) ) .circleColor(PURPLE) .minZoom(15) - .maxZoom(MAX_ZOOM), + .maxZoom(MAX_ZOOM) + .intiallyHidden(), StyleBuilder .ofId("regular-stop") .typeCircle() diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java index f60531b461a..3b2f36d3156 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java @@ -104,6 +104,12 @@ public StyleBuilder circleStroke(String color, int width) { return this; } + public StyleBuilder circleStroke(String color, ZoomDependentNumber width) { + paint.put("circle-stroke-color", validateColor(color)); + paint.put("circle-stroke-width", width.toJson()); + return this; + } + public StyleBuilder circleRadius(ZoomDependentNumber radius) { paint.put("circle-radius", radius.toJson()); return this; diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index af7598285e1..befd34a3b38 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -17,7 +17,8 @@ void spec() { var vectorSource = new VectorSource("vectorSource", "https://example.com"); var stops = new VectorSourceLayer(vectorSource, "stops"); var edges = new VectorSourceLayer(vectorSource, "edges"); - var spec = DebugStyleSpec.build(stops, edges, VERTICES.toVectorSourceLayer(streetSource)); + var vertices = new VectorSourceLayer(vectorSource, "vertices"); + var spec = DebugStyleSpec.build(stops, edges, vertices); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RESOURCES.fileToString("style.json"); diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index 06a602a8cd3..9555f32c1e5 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -1,5 +1,4 @@ { - "name" : "OTP Debug Tiles", "sources" : { "background" : { @@ -101,6 +100,47 @@ "visibility" : "none" } }, + { + "id" : "vertex", + "type" : "circle", + "source" : "vectorSource", + "source-layer" : "vertices", + "minzoom" : 15, + "maxzoom" : 23, + "paint" : { + "circle-stroke-color" : "#140d0e", + "circle-stroke-width" : { + "base" : 1.0, + "stops" : [ + [ + 15, + 0.2 + ], + [ + 23, + 3.0 + ] + ] + }, + "circle-radius" : { + "base" : 1.0, + "stops" : [ + [ + 15, + 1.0 + ], + [ + 23, + 7.0 + ] + ] + }, + "circle-color" : "#BC55F2" + }, + "layout" : { + "visibility" : "none" + } + }, { "id" : "regular-stop", "type" : "circle", @@ -129,4 +169,4 @@ } ], "version" : 8 -} \ No newline at end of file +} From 9e806f7957f7c487d6647b80fd11166cbdbff80f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 14:41:09 +0100 Subject: [PATCH 144/356] Move fallback class into framework.time package --- .../opentripplanner/ext/restapi/resources/RoutingResource.java | 2 +- .../opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java | 2 +- .../{api/support => framework/time}/ZoneIdFallback.java | 2 +- .../routing/algorithm/mapping/GraphPathToItineraryMapper.java | 2 +- .../opentripplanner/routing/service/DefaultRoutingService.java | 2 +- .../{api/support => framework/time}/ZoneIdFallbackTest.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/org/opentripplanner/{api/support => framework/time}/ZoneIdFallback.java (96%) rename src/test/java/org/opentripplanner/{api/support => framework/time}/ZoneIdFallbackTest.java (89%) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index ae63a95feaa..bfb3d6ed15a 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -19,11 +19,11 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import org.opentripplanner.api.parameter.QualifiedModeSet; -import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; +import org.opentripplanner.framework.time.ZoneIdFallback; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index e4094aaa888..2eeaf229b11 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -15,9 +15,9 @@ import org.opentripplanner.api.common.LocationStringParser; import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; -import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.framework.graphql.GraphQLUtils; +import org.opentripplanner.framework.time.ZoneIdFallback; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; diff --git a/src/main/java/org/opentripplanner/api/support/ZoneIdFallback.java b/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java similarity index 96% rename from src/main/java/org/opentripplanner/api/support/ZoneIdFallback.java rename to src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java index 0175337e2d4..2d43216e4b2 100644 --- a/src/main/java/org/opentripplanner/api/support/ZoneIdFallback.java +++ b/src/main/java/org/opentripplanner/framework/time/ZoneIdFallback.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.support; +package org.opentripplanner.framework.time; import java.time.ZoneId; import javax.annotation.Nullable; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java index ee86f8de720..11302098f25 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/GraphPathToItineraryMapper.java @@ -12,13 +12,13 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; -import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.ext.flex.FlexibleTransitLeg; import org.opentripplanner.ext.flex.edgetype.FlexTripEdge; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.framework.time.ZoneIdFallback; import org.opentripplanner.model.plan.ElevationProfile; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; diff --git a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java index dd5d5615be8..01736aac80e 100644 --- a/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java +++ b/src/main/java/org/opentripplanner/routing/service/DefaultRoutingService.java @@ -1,8 +1,8 @@ package org.opentripplanner.routing.service; import java.time.ZoneId; -import org.opentripplanner.api.support.ZoneIdFallback; import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.opentripplanner.framework.time.ZoneIdFallback; import org.opentripplanner.framework.tostring.MultiLineToStringBuilder; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.algorithm.RoutingWorker; diff --git a/src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java b/src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java similarity index 89% rename from src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java rename to src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java index 02013f0856b..b69e3ee2ff1 100644 --- a/src/test/java/org/opentripplanner/api/support/ZoneIdFallbackTest.java +++ b/src/test/java/org/opentripplanner/framework/time/ZoneIdFallbackTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.support; +package org.opentripplanner.framework.time; import static org.junit.jupiter.api.Assertions.assertEquals; From 83dd2282948c083ddd64653b617ed3fd0d8cb14b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 14:46:55 +0100 Subject: [PATCH 145/356] Allow dependency on logging package --- .../opentripplanner/framework/FrameworkArchitectureTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java b/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java index e1e00076a73..9e44dd05dda 100644 --- a/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java +++ b/src/test/java/org/opentripplanner/framework/FrameworkArchitectureTest.java @@ -97,7 +97,7 @@ void enforceTextPackageDependencies() { @Test void enforceTimePackageDependencies() { - TIME.verify(); + TIME.dependsOn(LOGGING).verify(); } @Test From 216bea8239631ef9c99e72b7180f7c50a55b8127 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 17:21:50 +0100 Subject: [PATCH 146/356] Change path of GTFS API to /otp/gtfs/v1 --- docs/apis/GTFS-GraphQL-API.md | 4 +- magidoc.mjs | 2 +- src/client/graphiql/index.html | 2 +- .../opentripplanner/apis/APIEndpoints.java | 2 + .../apis/gtfs/GtfsGraphQLAPI.java | 94 ++++--------------- .../graphql/GraphQLResponseSerializer.java | 26 ----- 6 files changed, 23 insertions(+), 107 deletions(-) diff --git a/docs/apis/GTFS-GraphQL-API.md b/docs/apis/GTFS-GraphQL-API.md index a9937afc6b2..b67b2882ec9 100644 --- a/docs/apis/GTFS-GraphQL-API.md +++ b/docs/apis/GTFS-GraphQL-API.md @@ -6,7 +6,7 @@ used heavily by [digitransit-ui](https://github.com/HSLdevcom/digitransit-ui). [otp-react-redux](https://github.com/opentripplanner/otp-react-redux) has also migrated to this API in 2023. ## URLs - - GraphQL endpoint: [`http://localhost:8080/otp/routers/default/index/graphql`](http://localhost:8080/otp/routers/default/index/graphql) + - GraphQL endpoint: [`http://localhost:8080/otp/gtfs/v1`](http://localhost:8080/otp/gtfs/v1) - HTML schema documentation: [https://docs.opentripplanner.org/api/dev-2.x/graphql-gtfs/](https://docs.opentripplanner.org/api/dev-2.x/graphql-gtfs/) - Built-in visual GraphQL client: [http://localhost:8080/graphiql](http://localhost:8080/graphiql) @@ -22,7 +22,7 @@ A complete example that fetches the list of all stops from OTP is: ``` curl --request POST \ - --url http://localhost:8080/otp/routers/default/index/graphql \ + --url http://localhost:8080/otp/gtfs/v1 \ --header 'Content-Type: application/json' \ --header 'OTPTimeout: 180000' \ --data '{"query":"query stops {\n stops {\n gtfsId\n name\n }\n}\n","operationName":"stops"}' diff --git a/magidoc.mjs b/magidoc.mjs index 44997e3fc9d..a02976f4bcc 100644 --- a/magidoc.mjs +++ b/magidoc.mjs @@ -17,7 +17,7 @@ export default { This is the static documentation of the OTP GraphQL GTFS API. The GraphQL endpoint of your instance, which you should point your tooling to, is -\`http://localhost:8080/otp/routers/default/index/graphql\` +\`http://localhost:8080/otp/gtfs/v1\` Please also check out the interactive API explorer built into every instance and available at http://localhost:8080/graphiql diff --git a/src/client/graphiql/index.html b/src/client/graphiql/index.html index 44016557a92..d96f736b287 100644 --- a/src/client/graphiql/index.html +++ b/src/client/graphiql/index.html @@ -152,7 +152,7 @@ let apiFlavor = parameters.flavor || "gtfs"; let urls = { - gtfs: '/otp/routers/default/index/graphql', + gtfs: '/otp/gtfs/v1', transmodel: '/otp/routers/default/transmodel/index/graphql' } diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java index fc49c02431f..00fcb61f439 100644 --- a/src/main/java/org/opentripplanner/apis/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -51,6 +51,8 @@ private APIEndpoints() { addIfEnabled(APIServerInfo, ServerInfo.class); addIfEnabled(APIUpdaterStatus, UpdaterStatusResource.class); addIfEnabled(GtfsGraphQlApi, GtfsGraphQLAPI.class); + // scheduled to be removed and only here for backwards compatibility + addIfEnabled(GtfsGraphQlApi, GtfsGraphQLAPI.GtfsGraphQLAPIOldPath.class); addIfEnabled(TransmodelGraphQlApi, TransmodelAPI.class); // Sandbox extension APIs diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java index b9b93190816..fd135d05544 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLAPI.java @@ -1,7 +1,6 @@ package org.opentripplanner.apis.gtfs; import com.fasterxml.jackson.databind.ObjectMapper; -import graphql.ExecutionResult; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.HeaderParam; @@ -14,39 +13,40 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import org.opentripplanner.framework.graphql.GraphQLResponseSerializer; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Path("/routers/{ignoreRouterId}/index/graphql") -@Produces(MediaType.APPLICATION_JSON) // One @Produces annotation for all endpoints. +@Path("/gtfs/v1/") +@Produces(MediaType.APPLICATION_JSON) public class GtfsGraphQLAPI { - @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(GtfsGraphQLAPI.class); private final OtpServerRequestContext serverContext; private final ObjectMapper deserializer = new ObjectMapper(); - public GtfsGraphQLAPI( - @Context OtpServerRequestContext serverContext, - /** - * @deprecated The support for multiple routers are removed from OTP2. - * See https://github.com/opentripplanner/OpenTripPlanner/issues/2760 - */ - @Deprecated @PathParam("ignoreRouterId") String ignoreRouterId - ) { + public GtfsGraphQLAPI(@Context OtpServerRequestContext serverContext) { this.serverContext = serverContext; } + /** + * This class is only here for backwards-compatibility. It will be removed in the future. + */ + @Path("/routers/{ignoreRouterId}/index/graphql") + public static class GtfsGraphQLAPIOldPath extends GtfsGraphQLAPI { + + public GtfsGraphQLAPIOldPath( + @Context OtpServerRequestContext serverContext, + @PathParam("ignoreRouterId") String ignore + ) { + super(serverContext); + } + } + @POST @Consumes(MediaType.APPLICATION_JSON) public Response getGraphQL( @@ -120,64 +120,4 @@ public Response getGraphQL( GraphQLRequestContext.ofServerContext(serverContext) ); } - - @POST - @Path("/batch") - @Consumes(MediaType.APPLICATION_JSON) - public Response getGraphQLBatch( - List> queries, - @HeaderParam("OTPTimeout") @DefaultValue("30000") int timeout, - @HeaderParam("OTPMaxResolves") @DefaultValue("1000000") int maxResolves, - @Context HttpHeaders headers - ) { - List> futures = new ArrayList<>(); - Locale locale = headers.getAcceptableLanguages().size() > 0 - ? headers.getAcceptableLanguages().get(0) - : serverContext.defaultLocale(); - - for (HashMap query : queries) { - Map variables; - if (query.get("variables") instanceof Map) { - variables = (Map) query.get("variables"); - } else if ( - query.get("variables") instanceof String && ((String) query.get("variables")).length() > 0 - ) { - try { - variables = deserializer.readValue((String) query.get("variables"), Map.class); - } catch (IOException e) { - return Response - .status(Response.Status.BAD_REQUEST) - .type(MediaType.TEXT_PLAIN_TYPE) - .entity("Variables must be a valid json object") - .build(); - } - } else { - variables = null; - } - String operationName = (String) query.getOrDefault("operationName", null); - - futures.add(() -> - GtfsGraphQLIndex.getGraphQLExecutionResult( - (String) query.get("query"), - variables, - operationName, - maxResolves, - timeout, - locale, - GraphQLRequestContext.ofServerContext(serverContext) - ) - ); - } - - try { - List> results = GtfsGraphQLIndex.threadPool.invokeAll(futures); - return Response - .status(Response.Status.OK) - .entity(GraphQLResponseSerializer.serializeBatch(queries, results)) - .build(); - } catch (InterruptedException e) { - LOG.error("Batch query interrupted", e); - throw new RuntimeException(e); - } - } } diff --git a/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java index cb3b146a113..1497f63285d 100644 --- a/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java +++ b/src/main/java/org/opentripplanner/framework/graphql/GraphQLResponseSerializer.java @@ -33,30 +33,4 @@ public static String serialize(ExecutionResult executionResult) { throw new RuntimeException(e); } } - - public static String serializeBatch( - List> queries, - List> futures - ) { - List> responses = new LinkedList<>(); - for (int i = 0; i < queries.size(); i++) { - ExecutionResult executionResult; - // Try each request separately, returning both completed and failed responses is ok - try { - executionResult = futures.get(i).get(); - } catch (InterruptedException | ExecutionException e) { - executionResult = new AbortExecutionException(e).toExecutionResult(); - } - responses.add( - Map.of("id", queries.get(i).get("id"), "payload", executionResult.toSpecification()) - ); - } - - try { - return objectMapper.writeValueAsString(responses); - } catch (JsonProcessingException e) { - LOG.error("Unable to serialize response", e); - throw new RuntimeException(e); - } - } } From 91609ec3c7127ac6b3f53f7e152fcd1600d2a2e8 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 22:59:31 +0100 Subject: [PATCH 147/356] Remove VehicleToStopHeuristics from examples [ci skip] --- docs/examples/ibi/atlanta/otp-config.json | 1 - docs/examples/ibi/portland/otp-config.json | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/examples/ibi/atlanta/otp-config.json b/docs/examples/ibi/atlanta/otp-config.json index b1c4b530cf2..2269e35d6ec 100644 --- a/docs/examples/ibi/atlanta/otp-config.json +++ b/docs/examples/ibi/atlanta/otp-config.json @@ -2,7 +2,6 @@ "otpFeatures" : { "FlexRouting": true, "GtfsGraphQlApi": true, - "VehicleToStopHeuristics": true, "ParallelRouting": true } } diff --git a/docs/examples/ibi/portland/otp-config.json b/docs/examples/ibi/portland/otp-config.json index 3227d4d90ca..2f4b1f586cc 100644 --- a/docs/examples/ibi/portland/otp-config.json +++ b/docs/examples/ibi/portland/otp-config.json @@ -1,6 +1,5 @@ { "otpFeatures" : { - "GtfsGraphQlApi": true, - "VehicleToStopHeuristics": true + "GtfsGraphQlApi": true } } From 25c7fc85607298c7eb3654d23d40f099a9cad373 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Wed, 17 Jan 2024 10:41:04 +0000 Subject: [PATCH 148/356] Add changelog entry for #4652 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 50846c3fce7..b26ab6ba080 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -74,6 +74,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Fix high walk reluctance leading to zero egress results for rental searches [#5605](https://github.com/opentripplanner/OpenTripPlanner/pull/5605) - Remove GTFS-RT websocket updater [#5604](https://github.com/opentripplanner/OpenTripPlanner/pull/5604) - Add stop layer to new Debug UI [#5602](https://github.com/opentripplanner/OpenTripPlanner/pull/5602) +- Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 7826c0dc2074bb59716f73c74b93ae5d257828d4 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Wed, 17 Jan 2024 11:49:59 +0000 Subject: [PATCH 149/356] Add changelog entry for #5581 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index b26ab6ba080..4af1393c748 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -75,6 +75,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Remove GTFS-RT websocket updater [#5604](https://github.com/opentripplanner/OpenTripPlanner/pull/5604) - Add stop layer to new Debug UI [#5602](https://github.com/opentripplanner/OpenTripPlanner/pull/5602) - Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652) +- Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 5a4cb9a67023fb0eadf556d98004d3e620ed6c8f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 14:08:01 +0100 Subject: [PATCH 150/356] Introduce extra layer for vector tiles config --- docs/RouterConfiguration.md | 108 +++++------ docs/sandbox/MapboxVectorTilesApi.md | 176 +++++++++--------- .../standalone/config/RouterConfig.java | 9 +- .../config/routerconfig/VectorTileConfig.java | 32 +++- .../configure/ConstructApplicationModule.java | 2 +- .../server/DefaultServerRequestContext.java | 13 +- .../opentripplanner/TestServerContext.java | 2 +- .../mapping/TripRequestMapperTest.java | 2 +- .../doc/RouterConfigurationDocTest.java | 2 +- .../transit/speed_test/SpeedTest.java | 3 +- .../standalone/config/router-config.json | 146 ++++++++------- 11 files changed, 267 insertions(+), 228 deletions(-) diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 5ca87a2aefa..351c582d72d 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -67,7 +67,7 @@ A full list of them can be found in the [RouteRequest](RouteRequest.md). |    [hideFeedId](#transmodelApi_hideFeedId) | `boolean` | Hide the FeedId in all API output, and add it to input. | *Optional* | `false` | na | |    [tracingHeaderTags](#transmodelApi_tracingHeaderTags) | `string[]` | Used to group requests when monitoring OTP. | *Optional* | | na | | [updaters](UpdaterConfig.md) | `object[]` | Configuration for the updaters that import various types of data into OTP. | *Optional* | | 1.5 | -| [vectorTileLayers](sandbox/MapboxVectorTilesApi.md) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | +| [vectorTiles](sandbox/MapboxVectorTilesApi.md) | `object` | TODO: Add short summary. | *Optional* | | na | | [vehicleRentalServiceDirectory](sandbox/VehicleRentalServiceDirectory.md) | `object` | Configuration for the vehicle rental service directory. | *Optional* | | 2.0 | @@ -602,58 +602,60 @@ Used to group requests when monitoring OTP. "transmodelApi" : { "hideFeedId" : true }, - "vectorTileLayers" : [ - { - "name" : "stops", - "type" : "Stop", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 600 - }, - { - "name" : "stations", - "type" : "Station", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 12, - "cacheMaxSeconds" : 600 - }, - { - "name" : "rentalPlaces", - "type" : "VehicleRental", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 60, - "expansionFactor" : 0.25 - }, - { - "name" : "rentalVehicle", - "type" : "VehicleRentalVehicle", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 60 - }, - { - "name" : "rentalStation", - "type" : "VehicleRentalStation", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 600 - }, - { - "name" : "vehicleParking", - "type" : "VehicleParking", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 60, - "expansionFactor" : 0.25 - } - ], + "vectorTiles" : { + "layers" : [ + { + "name" : "stops", + "type" : "Stop", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 600 + }, + { + "name" : "stations", + "type" : "Station", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 12, + "cacheMaxSeconds" : 600 + }, + { + "name" : "rentalPlaces", + "type" : "VehicleRental", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 60, + "expansionFactor" : 0.25 + }, + { + "name" : "rentalVehicle", + "type" : "VehicleRentalVehicle", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 60 + }, + { + "name" : "rentalStation", + "type" : "VehicleRentalStation", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 600 + }, + { + "name" : "vehicleParking", + "type" : "VehicleParking", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 60, + "expansionFactor" : 0.25 + } + ] + }, "timetableUpdates" : { "purgeExpiredData" : false, "maxSnapshotFrequency" : "2s" diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 8ef8ee179e7..0904bd1fef6 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -35,93 +35,95 @@ The feature must be configured in `router-config.json` as follows ```JSON { - "vectorTileLayers": [ - { - "name": "stops", - "type": "Stop", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600 - }, - { - "name": "stations", - "type": "Station", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 12, - "cacheMaxSeconds": 600 - }, - // all rental places: stations and free-floating vehicles - { - "name": "citybikes", - "type": "VehicleRental", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0.25 - }, - // just free-floating vehicles - { - "name": "rentalVehicles", - "type": "VehicleRentalVehicle", - "mapper": "DigitransitRealtime", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60 - }, - // just rental stations - { - "name": "rentalStations", - "type": "VehicleRentalStation", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600 - }, - // Contains just stations and real-time information for them - { - "name": "realtimeRentalStations", - "type": "VehicleRentalStation", - "mapper": "DigitransitRealtime", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60 - }, - // This exists for backwards compatibility. At some point, we might want - // to add a new real-time parking mapper with better translation support - // and less unnecessary fields. - { - "name": "stadtnaviVehicleParking", - "type": "VehicleParking", - "mapper": "Stadtnavi", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0.25 - }, - // no real-time, translatable fields are translated based on accept-language header - // and contains less fields than the Stadtnavi mapper - { - "name": "vehicleParking", - "type": "VehicleParking", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600, - "expansionFactor": 0.25 - }, - { - "name": "vehicleParkingGroups", - "type": "VehicleParkingGroup", - "mapper": "Digitransit", - "maxZoom": 17, - "minZoom": 14, - "cacheMaxSeconds": 600, - "expansionFactor": 0.25 - } - ] + "vectorTiles": + "layers": [ + { + "name": "stops", + "type": "Stop", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + { + "name": "stations", + "type": "Station", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 12, + "cacheMaxSeconds": 600 + }, + // all rental places: stations and free-floating vehicles + { + "name": "citybikes", + "type": "VehicleRental", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + }, + // just free-floating vehicles + { + "name": "rentalVehicles", + "type": "VehicleRentalVehicle", + "mapper": "DigitransitRealtime", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60 + }, + // just rental stations + { + "name": "rentalStations", + "type": "VehicleRentalStation", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + // Contains just stations and real-time information for them + { + "name": "realtimeRentalStations", + "type": "VehicleRentalStation", + "mapper": "DigitransitRealtime", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60 + }, + // This exists for backwards compatibility. At some point, we might want + // to add a new real-time parking mapper with better translation support + // and less unnecessary fields. + { + "name": "stadtnaviVehicleParking", + "type": "VehicleParking", + "mapper": "Stadtnavi", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + }, + // no real-time, translatable fields are translated based on accept-language header + // and contains less fields than the Stadtnavi mapper + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600, + "expansionFactor": 0.25 + }, + { + "name": "vehicleParkingGroups", + "type": "VehicleParkingGroup", + "mapper": "Digitransit", + "maxZoom": 17, + "minZoom": 14, + "cacheMaxSeconds": 600, + "expansionFactor": 0.25 + } + ] + } } ``` diff --git a/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java b/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java index ae92486037d..bf97155b747 100644 --- a/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/RouterConfig.java @@ -9,7 +9,6 @@ import java.io.Serializable; import java.util.List; import org.opentripplanner.ext.ridehailing.RideHailingServiceParameters; -import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.routerconfig.RideHailingServicesConfig; @@ -48,7 +47,7 @@ public class RouterConfig implements Serializable { private final RideHailingServicesConfig rideHailingConfig; private final FlexConfig flexConfig; private final TransmodelAPIConfig transmodelApi; - private final VectorTileConfig vectorTileLayers; + private final VectorTileConfig vectorTileConfig; public RouterConfig(JsonNode node, String source, boolean logUnusedParams) { this(new NodeAdapter(node, source), logUnusedParams); @@ -72,7 +71,7 @@ public RouterConfig(JsonNode node, String source, boolean logUnusedParams) { this.routingRequestDefaults.setMaxSearchWindow(transitConfig.maxSearchWindow()); this.updatersParameters = new UpdatersConfig(root); this.rideHailingConfig = new RideHailingServicesConfig(root); - this.vectorTileLayers = VectorTileConfig.mapVectorTilesParameters(root, "vectorTileLayers"); + this.vectorTileConfig = VectorTileConfig.mapVectorTilesParameters(root, "vectorTiles"); this.flexConfig = new FlexConfig(root, "flex"); if (logUnusedParams && LOG.isWarnEnabled()) { @@ -124,8 +123,8 @@ public List rideHailingServiceParameters() { return rideHailingConfig.rideHailingServiceParameters(); } - public VectorTilesResource.LayersParameters vectorTileLayers() { - return vectorTileLayers; + public VectorTileConfig vectorTileConfig() { + return vectorTileConfig; } public FlexConfig flexConfig() { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index a0342910be9..b3b48e19c23 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -5,22 +5,32 @@ import static org.opentripplanner.inspector.vector.LayerParameters.MAX_ZOOM; import static org.opentripplanner.inspector.vector.LayerParameters.MIN_ZOOM; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; import java.util.Collection; import java.util.List; +import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; +import org.opentripplanner.standalone.config.framework.json.ParameterBuilder; public class VectorTileConfig implements VectorTilesResource.LayersParameters { - List> layers; + public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null); + private final List> layers; - public VectorTileConfig( - Collection> layers + @Nullable + private final String basePath; + + VectorTileConfig( + Collection> layers, + @Nullable String basePath ) { this.layers = List.copyOf(layers); + this.basePath = basePath; } @Override @@ -28,16 +38,20 @@ public List> layers() { return layers; } - public static VectorTileConfig mapVectorTilesParameters( - NodeAdapter root, - String vectorTileLayers - ) { + @Nullable + public String basePath() { + return basePath; + } + + public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String paramName) { + var root = node.of(paramName).asObject(); return new VectorTileConfig( root - .of(vectorTileLayers) + .of("layers") .since(V2_0) .summary("Configuration of the individual layers for the Mapbox vector tiles.") - .asObjects(VectorTileConfig::mapLayer) + .asObjects(VectorTileConfig::mapLayer), + root.of("basePath").since(V2_5).asString(null) ); } diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java index c9d7253b0be..5d8efcd3a5b 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java +++ b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplicationModule.java @@ -49,7 +49,7 @@ OtpServerRequestContext providesServerContext( graph, transitService, Metrics.globalRegistry, - routerConfig.vectorTileLayers(), + routerConfig.vectorTileConfig(), worldEnvelopeService, realtimeVehicleService, vehicleRentalService, diff --git a/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java b/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java index f14fea66693..c0ac70309e6 100644 --- a/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java +++ b/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java @@ -24,6 +24,7 @@ import org.opentripplanner.standalone.api.HttpRequestScoped; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.routerconfig.TransitRoutingConfig; +import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.standalone.config.sandbox.FlexConfig; import org.opentripplanner.transit.service.TransitService; @@ -39,7 +40,7 @@ public class DefaultServerRequestContext implements OtpServerRequestContext { private final MeterRegistry meterRegistry; private final RaptorConfig raptorConfig; private final TileRendererManager tileRendererManager; - private final VectorTilesResource.LayersParameters vectorTileLayers; + private final VectorTileConfig vectorTileConfig; private final FlexConfig flexConfig; private final TraverseVisitor traverseVisitor; private final WorldEnvelopeService worldEnvelopeService; @@ -59,7 +60,7 @@ private DefaultServerRequestContext( MeterRegistry meterRegistry, RaptorConfig raptorConfig, TileRendererManager tileRendererManager, - VectorTilesResource.LayersParameters vectorTileLayers, + VectorTileConfig vectorTileConfig, WorldEnvelopeService worldEnvelopeService, RealtimeVehicleService realtimeVehicleService, VehicleRentalService vehicleRentalService, @@ -75,7 +76,7 @@ private DefaultServerRequestContext( this.meterRegistry = meterRegistry; this.raptorConfig = raptorConfig; this.tileRendererManager = tileRendererManager; - this.vectorTileLayers = vectorTileLayers; + this.vectorTileConfig = vectorTileConfig; this.vehicleRentalService = vehicleRentalService; this.flexConfig = flexConfig; this.traverseVisitor = traverseVisitor; @@ -97,7 +98,7 @@ public static DefaultServerRequestContext create( Graph graph, TransitService transitService, MeterRegistry meterRegistry, - VectorTilesResource.LayersParameters vectorTileLayers, + VectorTileConfig vectorTileConfig, WorldEnvelopeService worldEnvelopeService, RealtimeVehicleService realtimeVehicleService, VehicleRentalService vehicleRentalService, @@ -115,7 +116,7 @@ public static DefaultServerRequestContext create( meterRegistry, raptorConfig, new TileRendererManager(graph, routeRequestDefaults.preferences()), - vectorTileLayers, + vectorTileConfig, worldEnvelopeService, realtimeVehicleService, vehicleRentalService, @@ -221,7 +222,7 @@ public FlexConfig flexConfig() { @Override public VectorTilesResource.LayersParameters vectorTileLayers() { - return vectorTileLayers; + return vectorTileConfig; } @Override diff --git a/src/test/java/org/opentripplanner/TestServerContext.java b/src/test/java/org/opentripplanner/TestServerContext.java index 1f3e6491232..dd640c1f000 100644 --- a/src/test/java/org/opentripplanner/TestServerContext.java +++ b/src/test/java/org/opentripplanner/TestServerContext.java @@ -42,7 +42,7 @@ public static OtpServerRequestContext createServerContext( graph, new DefaultTransitService(transitModel), Metrics.globalRegistry, - routerConfig.vectorTileLayers(), + routerConfig.vectorTileConfig(), createWorldEnvelopeService(), createRealtimeVehicleService(transitService), createVehicleRentalService(), diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java index 3058f622281..a59b3e3f4bc 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java @@ -124,7 +124,7 @@ public class TripRequestMapperTest implements PlanTestConstants { graph, transitService, Metrics.globalRegistry, - RouterConfig.DEFAULT.vectorTileLayers(), + RouterConfig.DEFAULT.vectorTileConfig(), new DefaultWorldEnvelopeService(new DefaultWorldEnvelopeRepository()), new DefaultRealtimeVehicleService(transitService), new DefaultVehicleRentalService(), diff --git a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java index d13f423ffc4..a48374e755c 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java @@ -33,7 +33,7 @@ public class RouterConfigurationDocTest { .skip("flex", "sandbox/Flex.md") .skip("routingDefaults", "RouteRequest.md") .skip("updaters", "UpdaterConfig.md") - .skip("vectorTileLayers", "sandbox/MapboxVectorTilesApi.md") + .skip("vectorTiles", "sandbox/MapboxVectorTilesApi.md") .skipNestedElements("transferCacheRequests", "RouteRequest.md") .skip("rideHailingServices", "sandbox/RideHailing.md") .skip("vehicleRentalServiceDirectory", "sandbox/VehicleRentalServiceDirectory.md") diff --git a/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java b/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java index 642e192539c..7a11c35bace 100644 --- a/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java +++ b/src/test/java/org/opentripplanner/transit/speed_test/SpeedTest.java @@ -29,6 +29,7 @@ import org.opentripplanner.standalone.config.BuildConfig; import org.opentripplanner.standalone.config.ConfigModel; import org.opentripplanner.standalone.config.OtpConfigLoader; +import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.standalone.server.DefaultServerRequestContext; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitModel; @@ -111,7 +112,7 @@ public SpeedTest( graph, new DefaultTransitService(transitModel), timer.getRegistry(), - List::of, + VectorTileConfig.DEFAULT, TestServerContext.createWorldEnvelopeService(), TestServerContext.createRealtimeVehicleService(transitService), TestServerContext.createVehicleRentalService(), diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 5abb5ef87a6..f64a3b0f3b9 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -55,11 +55,14 @@ "accessEgress": { "maxDuration": "45m", "maxDurationForMode": { - "BIKE_RENTAL": "20m" + "BIKE_RENTAL": "20m" }, "maxStopCount": 500, "penalty": { - "FLEXIBLE" : { "timePenalty": "2m + 1.1t", "costFactor": 1.7 } + "FLEXIBLE": { + "timePenalty": "2m + 1.1t", + "costFactor": 1.7 + } } }, "itineraryFilters": { @@ -80,8 +83,12 @@ "geoidElevation": false, "maxJourneyDuration": "36h", "unpreferred": { - "agencies": ["HSL:123"], - "routes": ["HSL:456"] + "agencies": [ + "HSL:123" + ], + "routes": [ + "HSL:456" + ] }, "unpreferredCost": "10m + 2.0 x", "streetRoutingTimeout": "5s", @@ -135,8 +142,15 @@ "PREFERRED": 0 }, "transferCacheRequests": [ - { "modes": "WALK" }, - { "modes": "WALK", "wheelchairAccessibility": { "enabled": true } } + { + "modes": "WALK" + }, + { + "modes": "WALK", + "wheelchairAccessibility": { + "enabled": true + } + } ] }, "vehicleRentalServiceDirectory": { @@ -151,61 +165,63 @@ "transmodelApi": { "hideFeedId": true }, - "vectorTileLayers": [ - { - "name": "stops", - "type": "Stop", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600 - }, - { - "name": "stations", - "type": "Station", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 12, - "cacheMaxSeconds": 600 - }, - { - "name": "rentalPlaces", - // all rental places: stations and free-floating vehicles - "type": "VehicleRental", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0.25 - }, - { - "name": "rentalVehicle", - // just free-floating vehicles - "type": "VehicleRentalVehicle", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60 - }, - { - "name": "rentalStation", - // just rental stations - "type": "VehicleRentalStation", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600 - }, - { - "name": "vehicleParking", - "type": "VehicleParking", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0.25 - } - ], + "vectorTiles": { + "layers": [ + { + "name": "stops", + "type": "Stop", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + { + "name": "stations", + "type": "Station", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 12, + "cacheMaxSeconds": 600 + }, + { + "name": "rentalPlaces", + // all rental places: stations and free-floating vehicles + "type": "VehicleRental", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + }, + { + "name": "rentalVehicle", + // just free-floating vehicles + "type": "VehicleRentalVehicle", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60 + }, + { + "name": "rentalStation", + // just rental stations + "type": "VehicleRentalStation", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + } + ] + }, "timetableUpdates": { "purgeExpiredData": false, "maxSnapshotFrequency": "2s" @@ -301,7 +317,9 @@ "Header-Name": "Header-Value" }, "fuzzyTripMatching": false, - "features": ["position"] + "features": [ + "position" + ] }, // Siri-ET over HTTP { @@ -345,8 +363,10 @@ "clientSecret": "very-secret", "wheelchairAccessibleProductId": "545de0c4-659f-49c6-be65-0d5e448dffd5", "bannedProductIds": [ - "1196d0dd-423b-4a81-a1d8-615367d3a365", "f58761e5-8dd5-4940-a472-872f1236c596" + "1196d0dd-423b-4a81-a1d8-615367d3a365", + "f58761e5-8dd5-4940-a472-872f1236c596" ] } ] } + From 2d31331fe0914fa99b0fb226159f29abea8f5d1e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 14:38:45 +0100 Subject: [PATCH 151/356] Add test for base path --- .../VehicleParkingGroupsLayerTest.java | 26 ++++++------ .../ext/vectortiles/VectorTilesResource.java | 9 ++-- .../apis/support/TileJson.java | 42 ++++++++++++++----- .../GraphInspectorVectorTileResource.java | 7 ++-- .../api/OtpServerRequestContext.java | 4 +- .../config/routerconfig/VectorTileConfig.java | 6 +-- .../server/DefaultServerRequestContext.java | 3 +- .../apis/support/TileJsonTest.java | 23 ++++++++++ 8 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 src/test/java/org/opentripplanner/apis/support/TileJsonTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java index 1442b57fd60..66afc530e76 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java @@ -97,21 +97,23 @@ public void vehicleParkingGroupGeometryTest() { var config = """ { - "vectorTileLayers": [ - { - "name": "vehicleParkingGroups", - "type": "VehicleParkingGroup", - "mapper": "Digitransit", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 600, - "expansionFactor": 0 - } - ] + "vectorTiles": { + "layers" :[ + { + "name": "vehicleParkingGroups", + "type": "VehicleParkingGroup", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600, + "expansionFactor": 0 + } + ] + } } """; var nodeAdapter = newNodeAdapterForTest(config); - var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTileLayers"); + var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTiles"); assertEquals(1, tiles.layers().size()); var builder = new VehicleParkingGroupsLayerBuilderWithPublicGeometry( graph, diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index af2715d6928..0f04e26c833 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -66,7 +66,7 @@ public Response tileGet( z, locale, Arrays.asList(requestedLayers.split(",")), - serverContext.vectorTileLayers().layers(), + serverContext.vectorTileConfig().layers(), VectorTilesResource::crateLayerBuilder, serverContext ); @@ -89,15 +89,14 @@ public TileJson getTileJson( .filter(Predicate.not(Objects::isNull)) .toList(); - return new TileJson( + var url = TileJson.tileUrl( uri, headers, requestedLayers, ignoreRouterId, - "vectorTiles", - envelope, - feedInfos + "vectorTiles" ); + return new TileJson(url, envelope, feedInfos); } private static LayerBuilder crateLayerBuilder( diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index 2259d72d828..0975f7eb7b8 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -5,6 +5,7 @@ import java.io.Serializable; import java.util.Collection; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.model.FeedInfo; import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; @@ -35,11 +36,7 @@ public class TileJson implements Serializable { public final double[] center; public TileJson( - UriInfo uri, - HttpHeaders headers, - String layers, - String ignoreRouterId, - String path, + String tileUrl, WorldEnvelope envelope, Collection feedInfos ) { @@ -53,12 +50,7 @@ public TileJson( tiles = new String[] { - "%s/otp/routers/%s/%s/%s/{z}/{x}/{y}.pbf".formatted( - HttpUtils.getBaseAddress(uri, headers), - ignoreRouterId, - path, - layers - ), + tileUrl }; bounds = @@ -72,4 +64,32 @@ public TileJson( var c = envelope.center(); center = new double[] { c.longitude(), c.latitude(), 9 }; } + + public static String tileUrl( + UriInfo uri, + HttpHeaders headers, + String layers, + String ignoreRouterId, + String path + ) { + return "%s/otp/routers/%s/%s/%s/{z}/{x}/{y}.pbf".formatted( + HttpUtils.getBaseAddress(uri, headers), + ignoreRouterId, + path, + layers + ); + } + public static String tileUrl( + UriInfo uri, + HttpHeaders headers, + String overridePath, + String layers + ) { + var strippedPath = StringUtils.stripStart(overridePath, "/"); + return "%s/%s/%s/{z}/{x}/{y}.pbf".formatted( + HttpUtils.getBaseAddress(uri, headers), + strippedPath, + layers + ); + } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 67f92f01ee3..17cd44c1328 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -103,15 +103,14 @@ public TileJson getTileJson( var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); List feedInfos = feedInfos(); - return new TileJson( + var url = TileJson.tileUrl( uri, headers, requestedLayers, ignoreRouterId, - "inspector/vectortile", - envelope, - feedInfos + "inspector/vectortile" ); + return new TileJson(url, envelope, feedInfos); } @GET diff --git a/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java b/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java index fa6ead99c5e..fa3a7069e2d 100644 --- a/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java +++ b/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java @@ -9,7 +9,6 @@ import org.opentripplanner.ext.emissions.EmissionsService; import org.opentripplanner.ext.ridehailing.RideHailingService; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; -import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.inspector.raster.TileRendererManager; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; @@ -23,6 +22,7 @@ import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService; import org.opentripplanner.service.vehiclerental.VehicleRentalService; import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; +import org.opentripplanner.standalone.config.routerconfig.VectorTileConfig; import org.opentripplanner.standalone.config.sandbox.FlexConfig; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.search.state.State; @@ -119,7 +119,7 @@ default GraphFinder graphFinder() { FlexConfig flexConfig(); - VectorTilesResource.LayersParameters vectorTileLayers(); + VectorTileConfig vectorTileConfig(); default DataOverlayContext dataOverlayContext(RouteRequest request) { return OTPFeature.DataOverlay.isOnElseNull(() -> diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index b3b48e19c23..288ca5dbb49 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -10,6 +10,7 @@ import java.util.Collection; import java.util.List; +import java.util.Optional; import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerParameters; @@ -38,9 +39,8 @@ public List> layers() { return layers; } - @Nullable - public String basePath() { - return basePath; + public Optional basePath() { + return Optional.ofNullable(basePath); } public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String paramName) { diff --git a/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java b/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java index c0ac70309e6..9a586219ba1 100644 --- a/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java +++ b/src/main/java/org/opentripplanner/standalone/server/DefaultServerRequestContext.java @@ -8,7 +8,6 @@ import org.opentripplanner.ext.emissions.EmissionsService; import org.opentripplanner.ext.ridehailing.RideHailingService; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; -import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.raster.TileRendererManager; import org.opentripplanner.raptor.api.request.RaptorTuningParameters; import org.opentripplanner.raptor.configure.RaptorConfig; @@ -221,7 +220,7 @@ public FlexConfig flexConfig() { } @Override - public VectorTilesResource.LayersParameters vectorTileLayers() { + public VectorTileConfig vectorTileConfig() { return vectorTileConfig; } diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java new file mode 100644 index 00000000000..00c9a94aa24 --- /dev/null +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -0,0 +1,23 @@ +package org.opentripplanner.apis.support; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.net.URI; +import java.net.URISyntaxException; +import org.glassfish.jersey.internal.MapPropertiesDelegate; +import org.glassfish.jersey.server.ContainerRequest; +import org.glassfish.jersey.server.internal.routing.UriRoutingContext; +import org.junit.jupiter.api.Test; + +class TileJsonTest { + + @Test + void url() throws URISyntaxException { + + var uri= new URI("https://localhost:8080"); + var header = new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); + var uriInfo =new UriRoutingContext(header); + assertEquals("", TileJson.tileUrl(uriInfo, header, "/OTP_CT/some/config/path/", "foo,bar")); + } + +} \ No newline at end of file From 18e1ce6abe54016b2ce8acc392ce109a7dadf1f6 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 18:23:03 +0100 Subject: [PATCH 152/356] Fix tests --- .../VehicleParkingGroupsLayerTest.java | 2 +- .../VehicleParkingsLayerTest.java | 28 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java index 66afc530e76..1ec7d042894 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingGroupsLayerTest.java @@ -98,7 +98,7 @@ public void vehicleParkingGroupGeometryTest() { """ { "vectorTiles": { - "layers" :[ + "layers" :[ { "name": "vehicleParkingGroups", "type": "VehicleParkingGroup", diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java index b4988ab398d..fdb723b3dc7 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/vehicleparkings/VehicleParkingsLayerTest.java @@ -93,23 +93,25 @@ public void vehicleParkingGeometryTest() { var config = """ { - "vectorTileLayers": [ - { - "name": "vehicleParking", - "type": "VehicleParking", - "mapper": "Stadtnavi", - "maxZoom": 20, - "minZoom": 14, - "cacheMaxSeconds": 60, - "expansionFactor": 0 - } - ] + "vectorTiles": { + "layers" : [ + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Stadtnavi", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0 + } + ] + } } """; var nodeAdapter = newNodeAdapterForTest(config); - var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTileLayers"); + var tiles = VectorTileConfig.mapVectorTilesParameters(nodeAdapter, "vectorTiles"); assertEquals(1, tiles.layers().size()); - var builder = new VehicleParkingsLayerBuilder(graph, tiles.layers().get(0), Locale.US); + var builder = new VehicleParkingsLayerBuilder(graph, tiles.layers().getFirst(), Locale.US); List geometries = builder.getGeometries(new Envelope(0.99, 1.01, 1.99, 2.01)); From 5dac9ddf8c3359e3686c37771ed6309a8280b101 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 22:51:53 +0100 Subject: [PATCH 153/356] Add parameter documentation for vector tiles --- doc-templates/sandbox/MapboxVectorTilesApi.md | 198 ++++++++++++ docs/sandbox/MapboxVectorTilesApi.md | 297 ++++++++++++++++++ .../vectortiles/VectorTilesConfigDocTest.java | 80 +++++ 3 files changed, 575 insertions(+) create mode 100644 doc-templates/sandbox/MapboxVectorTilesApi.md create mode 100644 src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java diff --git a/doc-templates/sandbox/MapboxVectorTilesApi.md b/doc-templates/sandbox/MapboxVectorTilesApi.md new file mode 100644 index 00000000000..dfba427919a --- /dev/null +++ b/doc-templates/sandbox/MapboxVectorTilesApi.md @@ -0,0 +1,198 @@ +# Mapbox Vector Tiles API + +## Contact Info + +- HSL, Finland +- Kyyti Group Oy, Finland +- Hannes Junnila + +## Documentation + +This API produces [Mapbox vector tiles](https://docs.mapbox.com/vector-tiles/reference/), which are +used by eg. [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) to show information about +public transit entities on the map. + +The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, +where `layers` is a comma separated list of layer names from the configuration. + +Translatable fields in the tiles are translated based on the `accept-language` header in requests. +Currently, only the language with the highest priority from the header is used. + +### Configuration + +To enable this you need to add the feature `otp-config.json`. + +```json +// otp-config.json +{ + "otpFeatures": { + "SandboxAPIMapboxVectorTilesApi": true + } +} +``` + +The feature must be configured in `router-config.json` as follows + +```JSON +{ + "vectorTiles": + "layers": [ + { + "name": "stops", + "type": "Stop", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + { + "name": "stations", + "type": "Station", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 12, + "cacheMaxSeconds": 600 + }, + // all rental places: stations and free-floating vehicles + { + "name": "citybikes", + "type": "VehicleRental", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + }, + // just free-floating vehicles + { + "name": "rentalVehicles", + "type": "VehicleRentalVehicle", + "mapper": "DigitransitRealtime", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60 + }, + // just rental stations + { + "name": "rentalStations", + "type": "VehicleRentalStation", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + // Contains just stations and real-time information for them + { + "name": "realtimeRentalStations", + "type": "VehicleRentalStation", + "mapper": "DigitransitRealtime", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60 + }, + // This exists for backwards compatibility. At some point, we might want + // to add a new real-time parking mapper with better translation support + // and less unnecessary fields. + { + "name": "stadtnaviVehicleParking", + "type": "VehicleParking", + "mapper": "Stadtnavi", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + }, + // no real-time, translatable fields are translated based on accept-language header + // and contains less fields than the Stadtnavi mapper + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600, + "expansionFactor": 0.25 + }, + { + "name": "vehicleParkingGroups", + "type": "VehicleParkingGroup", + "mapper": "Digitransit", + "maxZoom": 17, + "minZoom": 14, + "cacheMaxSeconds": 600, + "expansionFactor": 0.25 + } + ] + } +} +``` + +For each layer, the configuration includes: + +- `name` which is used in the url to fetch tiles, and as the layer name in the vector tiles. +- `type` which tells the type of the layer. Currently supported: + - `Stop` + - `Station` + - `VehicleRental`: all rental places: stations and free-floating vehicles + - `VehicleRentalVehicle`: free-floating rental vehicles + - `VehicleRentalStation`: rental stations + - `VehicleParking` + - `VehicleParkingGroup` +- `mapper` which describes the mapper converting the properties from the OTP model entities to the + vector tile properties. Currently `Digitransit` is supported for all layer types. +- `minZoom` and `maxZoom` which describe the zoom levels the layer is active for. +- `cacheMaxSeconds` which sets the cache header in the response. The lowest value of the layers + included is selected. +- `expansionFactor` How far outside its boundaries should the tile contain information. The value is + a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile + edges, then increase this number. + +### Extending + +If more generic layers are created for this API, it should be moved out from the sandbox, into the +core code, with potentially leaving specific property mappers in place. + +#### Creating a new layer + +In order to create a new type of layer, you need to create a new class extending `LayerBuilder`. +You need to implement two methods, `List getGeometries(Envelope query)`, which returns a +list of geometries, with an object of type `T` as their userData in the geometry, +and `double getExpansionFactor()`, which describes how much information outside the tile bounds +should be included. This layer then needs to be added into `VectorTilesResource.layers`, with a +new `LayerType` enum as the key, and the class constructor as the value. + +A new mapper needs to be added every time a new layer is added. See below for information. + + + + +#### Creating a new mapper + +The mapping contains information of what data to include in the vector tiles. The mappers are +defined per layer. + +In order to create a new mapper for a layer, you need to create a new class +extending `PropertyMapper`. In that class, you need to implement the +method `Collection> map(T input)`. The type T is dependent on the layer for which +you implement the mapper for. It needs to return a list of attributes, as key-value pairs which will +be written into the vector tile. + +The mapper needs to be added to the `mappers` map in the layer, with a new `MapperType` enum as the +key, and a function to create the mapper, with a `Graph` object as a parameter, as the value. + +## Changelog + +- 2020-07-09: Initial version of Mapbox vector tiles API +- 2021-05-12: Make expansion factor configurable +- 2021-09-07: Rename `BikeRental` to `VehicleRental` +- 2021-10-13: Correctly serialize the vehicle rental name [#3648](https://github.com/opentripplanner/OpenTripPlanner/pull/3648) +- 2022-01-03: Add support for VehicleParking entities +- 2022-04-27: Read the headsign for frequency-only patterns correctly [#4122](https://github.com/opentripplanner/OpenTripPlanner/pull/4122) +- 2022-08-23: Remove patterns and add route gtfsTypes to stop layer [#4404](https://github.com/opentripplanner/OpenTripPlanner/pull/4404) +- 2022-10-11: Added layer for VehicleParkingGroups [#4510](https://github.com/opentripplanner/OpenTripPlanner/pull/4510) +- 2022-10-14: Add separate layers for vehicle rental place types [#4516](https://github.com/opentripplanner/OpenTripPlanner/pull/4516) +- 2022-10-19 [#4529](https://github.com/opentripplanner/OpenTripPlanner/pull/4529): + * Translatable fields are now translated based on accept-language header + * Added DigitransitRealtime for vehicle rental stations + * Changed old vehicle parking mapper to be Stadtnavi + * Added a new Digitransit vehicle parking mapper with no real-time information and less fields diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 0904bd1fef6..e11fe320ef8 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -163,6 +163,303 @@ new `LayerType` enum as the key, and the class constructor as the value. A new mapper needs to be added every time a new layer is added. See below for information. + + + + +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|------------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| basePath | `string` | TODO: Add short summary. | *Optional* | | 2.5 | +| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "station" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_1_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_1_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_1_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerental" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__2__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__2__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__2__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerentalvehicle" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__3__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__3__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__3__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerentalstation" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__4__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__4__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__4__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehicleparking" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__5__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__5__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__5__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | + + +#### Details + +

      layers

      + +**Since version:** `2.0` ∙ **Type:** `object[]` ∙ **Cardinality:** `Optional` +**Path:** /vectorTiles + +Configuration of the individual layers for the Mapbox vector tiles. + +

      cacheMaxSeconds

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` +**Path:** /vectorTiles/layers/[0] + +Sets the cache header in the response. + +The lowest value of the layers included is selected. + +

      expansionFactor

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` +**Path:** /vectorTiles/layers/[0] + +How far outside its boundaries should the tile contain information. + +The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. + +

      mapper

      + +**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /vectorTiles/layers/[0] + +Describes the mapper converting from the OTP model entities to the vector tile properties. + +Currently `Digitransit` is supported for all layer types. + +

      cacheMaxSeconds

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` +**Path:** /vectorTiles/layers/[1] + +Sets the cache header in the response. + +The lowest value of the layers included is selected. + +

      expansionFactor

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` +**Path:** /vectorTiles/layers/[1] + +How far outside its boundaries should the tile contain information. + +The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. + +

      mapper

      + +**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /vectorTiles/layers/[1] + +Describes the mapper converting from the OTP model entities to the vector tile properties. + +Currently `Digitransit` is supported for all layer types. + +

      cacheMaxSeconds

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` +**Path:** /vectorTiles/layers/[2] + +Sets the cache header in the response. + +The lowest value of the layers included is selected. + +

      expansionFactor

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` +**Path:** /vectorTiles/layers/[2] + +How far outside its boundaries should the tile contain information. + +The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. + +

      mapper

      + +**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /vectorTiles/layers/[2] + +Describes the mapper converting from the OTP model entities to the vector tile properties. + +Currently `Digitransit` is supported for all layer types. + +

      cacheMaxSeconds

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` +**Path:** /vectorTiles/layers/[3] + +Sets the cache header in the response. + +The lowest value of the layers included is selected. + +

      expansionFactor

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` +**Path:** /vectorTiles/layers/[3] + +How far outside its boundaries should the tile contain information. + +The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. + +

      mapper

      + +**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /vectorTiles/layers/[3] + +Describes the mapper converting from the OTP model entities to the vector tile properties. + +Currently `Digitransit` is supported for all layer types. + +

      cacheMaxSeconds

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` +**Path:** /vectorTiles/layers/[4] + +Sets the cache header in the response. + +The lowest value of the layers included is selected. + +

      expansionFactor

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` +**Path:** /vectorTiles/layers/[4] + +How far outside its boundaries should the tile contain information. + +The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. + +

      mapper

      + +**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /vectorTiles/layers/[4] + +Describes the mapper converting from the OTP model entities to the vector tile properties. + +Currently `Digitransit` is supported for all layer types. + +

      cacheMaxSeconds

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` +**Path:** /vectorTiles/layers/[5] + +Sets the cache header in the response. + +The lowest value of the layers included is selected. + +

      expansionFactor

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` +**Path:** /vectorTiles/layers/[5] + +How far outside its boundaries should the tile contain information. + +The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. + +

      mapper

      + +**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` +**Path:** /vectorTiles/layers/[5] + +Describes the mapper converting from the OTP model entities to the vector tile properties. + +Currently `Digitransit` is supported for all layer types. + + + +##### Example configuration + +```JSON +// router-config.json +{ + "updaters" : [ + { + "layers" : [ + { + "name" : "stops", + "type" : "Stop", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 600 + }, + { + "name" : "stations", + "type" : "Station", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 12, + "cacheMaxSeconds" : 600 + }, + { + "name" : "rentalPlaces", + "type" : "VehicleRental", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 60, + "expansionFactor" : 0.25 + }, + { + "name" : "rentalVehicle", + "type" : "VehicleRentalVehicle", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 60 + }, + { + "name" : "rentalStation", + "type" : "VehicleRentalStation", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 600 + }, + { + "name" : "vehicleParking", + "type" : "VehicleParking", + "mapper" : "Digitransit", + "maxZoom" : 20, + "minZoom" : 14, + "cacheMaxSeconds" : 60, + "expansionFactor" : 0.25 + } + ] + } + ] +} +``` + + + #### Creating a new mapper The mapping contains information of what data to include in the vector tiles. The mappers are diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java new file mode 100644 index 00000000000..50dbd24008f --- /dev/null +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java @@ -0,0 +1,80 @@ +package org.opentripplanner.ext.vectortiles; + +import static org.opentripplanner.framework.application.OtpFileNames.ROUTER_CONFIG_FILENAME; +import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; +import static org.opentripplanner.framework.io.FileUtils.readFile; +import static org.opentripplanner.framework.io.FileUtils.writeFile; +import static org.opentripplanner.framework.text.MarkdownFormatter.HEADER_4; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; +import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; +import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; +import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; + +import java.io.File; +import org.junit.jupiter.api.Test; +import org.opentripplanner.generate.doc.framework.DocBuilder; +import org.opentripplanner.generate.doc.framework.GeneratesDocumentation; +import org.opentripplanner.generate.doc.framework.ParameterDetailsList; +import org.opentripplanner.generate.doc.framework.ParameterSummaryTable; +import org.opentripplanner.generate.doc.framework.SkipNodes; +import org.opentripplanner.standalone.config.RouterConfig; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +@GeneratesDocumentation +public class VectorTilesConfigDocTest { + + private static final String DOCUMENT = "sandbox/MapboxVectorTilesApi.md"; + private static final File TEMPLATE = new File(TEMPLATE_ROOT, DOCUMENT); + private static final File OUT_FILE = new File(DOCS_ROOT, DOCUMENT); + private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); + private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; + + @Test + public void updateDoc() { + NodeAdapter node = readVectorTiles(); + + // Read and close inout file (same as output file) + String template = readFile(TEMPLATE); + String original = readFile(OUT_FILE); + + template = replaceSection(template, "parameters", updaterDoc(node)); + + writeFile(OUT_FILE, template); + assertFileEquals(original, OUT_FILE); + } + + private NodeAdapter readVectorTiles() { + var json = jsonNodeFromResource(ROUTER_CONFIG_PATH); + var conf = new RouterConfig(json, ROUTER_CONFIG_PATH, false); + return conf.asNodeAdapter().child("vectorTiles"); + } + + private String updaterDoc(NodeAdapter node) { + DocBuilder buf = new DocBuilder(); + addParameterSummaryTable(buf, node); + addDetailsSection(buf, node); + addExample(buf, node); + return buf.toString(); + } + + private void addParameterSummaryTable(DocBuilder buf, NodeAdapter node) { + buf.addSection(new ParameterSummaryTable(SKIP_NODES).createTable(node).toMarkdownTable()); + } + + private void addDetailsSection(DocBuilder buf, NodeAdapter node) { + String details = getParameterDetailsTable(node); + + if (!details.isBlank()) { + buf.header(4, "Details", null).addSection(details); + } + } + + private String getParameterDetailsTable(NodeAdapter node) { + return ParameterDetailsList.listParametersWithDetails(node, SKIP_NODES, HEADER_4); + } + + private void addExample(DocBuilder buf, NodeAdapter node) { + buf.addSection("##### Example configuration"); + buf.addUpdaterExample(ROUTER_CONFIG_FILENAME, node.rawNode()); + } +} From 6bd6e08d6574df857506922e8b4c150b6e596065 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 11:56:58 +0100 Subject: [PATCH 154/356] Generate docs for vector tiles --- docs/sandbox/MapboxVectorTilesApi.md | 104 +++++++++--------- .../ext/vectortiles/VectorTilesResource.java | 8 +- .../apis/support/TileJson.java | 30 ++--- .../GraphInspectorVectorTileResource.java | 2 +- .../config/routerconfig/VectorTileConfig.java | 21 ++-- .../apis/support/TileJsonTest.java | 10 +- 6 files changed, 80 insertions(+), 95 deletions(-) diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index e11fe320ef8..5f86af742f0 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -167,58 +167,58 @@ A new mapper needs to be added every time a new layer is added. See below for in -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|------------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| basePath | `string` | TODO: Add short summary. | *Optional* | | 2.5 | -| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "station" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers_1_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers_1_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers_1_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerental" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__2__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__2__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__2__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerentalvehicle" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__3__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__3__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__3__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerentalstation" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__4__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__4__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__4__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehicleparking" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__5__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__5__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__5__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|------------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|--------------------------------------|:-----:| +| basePath | `string` | TODO: Add short summary. | *Optional* | `"/otp/routers/default/vectorTiles"` | 2.5 | +| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "station" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_1_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_1_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_1_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerental" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__2__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__2__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__2__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerentalvehicle" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__3__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__3__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__3__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerentalstation" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__4__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__4__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__4__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehicleparking" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__5__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__5__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__5__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | #### Details diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index 0f04e26c833..d2796bf63d3 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -89,13 +89,7 @@ public TileJson getTileJson( .filter(Predicate.not(Objects::isNull)) .toList(); - var url = TileJson.tileUrl( - uri, - headers, - requestedLayers, - ignoreRouterId, - "vectorTiles" - ); + var url = TileJson.tileUrl(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles"); return new TileJson(url, envelope, feedInfos); } diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index 0975f7eb7b8..b8f8fc8d27c 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -35,11 +35,7 @@ public class TileJson implements Serializable { public final double[] bounds; public final double[] center; - public TileJson( - String tileUrl, - WorldEnvelope envelope, - Collection feedInfos - ) { + public TileJson(String tileUrl, WorldEnvelope envelope, Collection feedInfos) { attribution = feedInfos .stream() @@ -48,10 +44,7 @@ public TileJson( ) .collect(Collectors.joining(", ")); - tiles = - new String[] { - tileUrl - }; + tiles = new String[] { tileUrl }; bounds = new double[] { @@ -73,12 +66,13 @@ public static String tileUrl( String path ) { return "%s/otp/routers/%s/%s/%s/{z}/{x}/{y}.pbf".formatted( - HttpUtils.getBaseAddress(uri, headers), - ignoreRouterId, - path, - layers - ); + HttpUtils.getBaseAddress(uri, headers), + ignoreRouterId, + path, + layers + ); } + public static String tileUrl( UriInfo uri, HttpHeaders headers, @@ -87,9 +81,9 @@ public static String tileUrl( ) { var strippedPath = StringUtils.stripStart(overridePath, "/"); return "%s/%s/%s/{z}/{x}/{y}.pbf".formatted( - HttpUtils.getBaseAddress(uri, headers), - strippedPath, - layers - ); + HttpUtils.getBaseAddress(uri, headers), + strippedPath, + layers + ); } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 17cd44c1328..4015d3073ac 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -108,7 +108,7 @@ public TileJson getTileJson( headers, requestedLayers, ignoreRouterId, - "inspector/vectortile" + "inspector/vectortile" ); return new TileJson(url, envelope, feedInfos); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 288ca5dbb49..e4905d0f63b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -5,33 +5,32 @@ import static org.opentripplanner.inspector.vector.LayerParameters.MAX_ZOOM; import static org.opentripplanner.inspector.vector.LayerParameters.MIN_ZOOM; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; -import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; import java.util.Collection; import java.util.List; -import java.util.Optional; -import javax.annotation.Nullable; +import java.util.Objects; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; -import org.opentripplanner.standalone.config.framework.json.ParameterBuilder; public class VectorTileConfig implements VectorTilesResource.LayersParameters { - public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null); + public static final VectorTileConfig DEFAULT = new VectorTileConfig( + List.of(), + "/otp/routers/default/vectorTiles" + ); private final List> layers; - @Nullable private final String basePath; VectorTileConfig( Collection> layers, - @Nullable String basePath + String basePath ) { this.layers = List.copyOf(layers); - this.basePath = basePath; + this.basePath = Objects.requireNonNull(basePath); } @Override @@ -39,8 +38,8 @@ public List> layers() { return layers; } - public Optional basePath() { - return Optional.ofNullable(basePath); + public String basePath() { + return basePath; } public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String paramName) { @@ -51,7 +50,7 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String .since(V2_0) .summary("Configuration of the individual layers for the Mapbox vector tiles.") .asObjects(VectorTileConfig::mapLayer), - root.of("basePath").since(V2_5).asString(null) + root.of("basePath").since(V2_5).asString(DEFAULT.basePath) ); } diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index 00c9a94aa24..4d21ee315ea 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -13,11 +13,9 @@ class TileJsonTest { @Test void url() throws URISyntaxException { - - var uri= new URI("https://localhost:8080"); + var uri = new URI("https://localhost:8080"); var header = new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); - var uriInfo =new UriRoutingContext(header); - assertEquals("", TileJson.tileUrl(uriInfo, header, "/OTP_CT/some/config/path/", "foo,bar")); + var uriInfo = new UriRoutingContext(header); + assertEquals("", TileJson.tileUrl(uriInfo, header, "/OTP_CT/some/config/path/", "foo,bar")); } - -} \ No newline at end of file +} From 586f692922b259a19eaf621e8b2e1538803e6dab Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 12:19:18 +0100 Subject: [PATCH 155/356] Use new config option in resource --- docs/sandbox/MapboxVectorTilesApi.md | 104 +++++++++--------- .../ext/vectortiles/VectorTilesResource.java | 11 +- .../apis/support/TileJson.java | 5 +- .../GraphInspectorVectorTileResource.java | 2 +- .../config/routerconfig/VectorTileConfig.java | 16 +-- .../apis/support/TileJsonTest.java | 20 +++- 6 files changed, 90 insertions(+), 68 deletions(-) diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 5f86af742f0..e11fe320ef8 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -167,58 +167,58 @@ A new mapper needs to be added every time a new layer is added. See below for in -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|------------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|--------------------------------------|:-----:| -| basePath | `string` | TODO: Add short summary. | *Optional* | `"/otp/routers/default/vectorTiles"` | 2.5 | -| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "station" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers_1_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers_1_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers_1_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerental" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__2__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__2__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__2__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerentalvehicle" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__3__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__3__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__3__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerentalstation" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__4__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__4__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__4__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehicleparking" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__5__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__5__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__5__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|------------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| basePath | `string` | TODO: Add short summary. | *Optional* | | 2.5 | +| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "station" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_1_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_1_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_1_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerental" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__2__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__2__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__2__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerentalvehicle" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__3__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__3__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__3__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehiclerentalstation" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__4__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__4__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__4__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | +|       type = "vehicleparking" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers__5__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers__5__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers__5__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | #### Details diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index d2796bf63d3..e1c119713d1 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -89,7 +89,16 @@ public TileJson getTileJson( .filter(Predicate.not(Objects::isNull)) .toList(); - var url = TileJson.tileUrl(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles"); + var url = serverContext + .vectorTileConfig() + .basePath() + .map(overrideBasePath -> + TileJson.overrideBasePath(uri, headers, overrideBasePath, requestedLayers) + ) + .orElseGet(() -> + TileJson.defaultBasePath(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles") + ); + return new TileJson(url, envelope, feedInfos); } diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index b8f8fc8d27c..840542d68a8 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -58,7 +58,7 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee center = new double[] { c.longitude(), c.latitude(), 9 }; } - public static String tileUrl( + public static String defaultBasePath( UriInfo uri, HttpHeaders headers, String layers, @@ -73,13 +73,14 @@ public static String tileUrl( ); } - public static String tileUrl( + public static String overrideBasePath( UriInfo uri, HttpHeaders headers, String overridePath, String layers ) { var strippedPath = StringUtils.stripStart(overridePath, "/"); + strippedPath = StringUtils.stripEnd(strippedPath, "/"); return "%s/%s/%s/{z}/{x}/{y}.pbf".formatted( HttpUtils.getBaseAddress(uri, headers), strippedPath, diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 4015d3073ac..ada9381ec1d 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -103,7 +103,7 @@ public TileJson getTileJson( var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); List feedInfos = feedInfos(); - var url = TileJson.tileUrl( + var url = TileJson.defaultBasePath( uri, headers, requestedLayers, diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index e4905d0f63b..df353f40079 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -10,6 +10,8 @@ import java.util.Collection; import java.util.List; import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -17,20 +19,18 @@ public class VectorTileConfig implements VectorTilesResource.LayersParameters { - public static final VectorTileConfig DEFAULT = new VectorTileConfig( - List.of(), - "/otp/routers/default/vectorTiles" - ); + public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null); private final List> layers; + @Nullable private final String basePath; VectorTileConfig( Collection> layers, - String basePath + @Nullable String basePath ) { this.layers = List.copyOf(layers); - this.basePath = Objects.requireNonNull(basePath); + this.basePath = basePath; } @Override @@ -38,8 +38,8 @@ public List> layers() { return layers; } - public String basePath() { - return basePath; + public Optional basePath() { + return Optional.ofNullable(basePath); } public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String paramName) { diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index 4d21ee315ea..890dc09aa92 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -7,15 +7,27 @@ import org.glassfish.jersey.internal.MapPropertiesDelegate; import org.glassfish.jersey.server.ContainerRequest; import org.glassfish.jersey.server.internal.routing.UriRoutingContext; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class TileJsonTest { - @Test - void url() throws URISyntaxException { + @ParameterizedTest + @ValueSource( + strings = { + "/otp_ct/vectorTiles", + "otp_ct/vectorTiles/", + "otp_ct/vectorTiles///", + "///otp_ct/vectorTiles/", + } + ) + void overrideBasePath(String basePath) throws URISyntaxException { var uri = new URI("https://localhost:8080"); var header = new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); var uriInfo = new UriRoutingContext(header); - assertEquals("", TileJson.tileUrl(uriInfo, header, "/OTP_CT/some/config/path/", "foo,bar")); + assertEquals( + "https://localhost:8080/otp_ct/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", + TileJson.overrideBasePath(uriInfo, header, basePath, "stops,rentalVehicles") + ); } } From bf4605b7f509965a1aba27792cb887b394e000e7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 12:46:54 +0100 Subject: [PATCH 156/356] Improve documentation --- docs/sandbox/MapboxVectorTilesApi.md | 261 +----------------- .../vectortiles/VectorTilesConfigDocTest.java | 19 +- .../ext/vectortiles/router-config.json | 16 ++ .../standalone/config/router-config.json | 1 + 4 files changed, 35 insertions(+), 262 deletions(-) create mode 100644 src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index e11fe320ef8..547eb3501c1 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -167,58 +167,17 @@ A new mapper needs to be added every time a new layer is added. See below for in -| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | -|------------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| basePath | `string` | TODO: Add short summary. | *Optional* | | 2.5 | -| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "station" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers_1_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers_1_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers_1_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerental" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__2__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__2__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__2__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerentalvehicle" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__3__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__3__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__3__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehiclerentalstation" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__4__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__4__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__4__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | -|    { object } | `object` | Nested object in array. The object type is determined by the parameters. | *Optional* | | 2.0 | -|       type = "vehicleparking" | `enum` | Type of the layer. | *Required* | | 2.0 | -|       [cacheMaxSeconds](#vectorTiles_layers__5__cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | -|       [expansionFactor](#vectorTiles_layers__5__expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | -|       [mapper](#vectorTiles_layers__5__mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | -|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | -|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | -|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | +| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | +|----------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| basePath | `string` | TODO: Add short summary. | *Optional* | | 2.5 | +| [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | +|       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | +|       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | +|       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | +|       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | +|       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | +|       name | `string` | Used in the url to fetch tiles, and as the layer name in the vector tiles. | *Required* | | 2.0 | #### Details @@ -257,206 +216,8 @@ Describes the mapper converting from the OTP model entities to the vector tile p Currently `Digitransit` is supported for all layer types. -

      cacheMaxSeconds

      -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` -**Path:** /vectorTiles/layers/[1] - -Sets the cache header in the response. - -The lowest value of the layers included is selected. - -

      expansionFactor

      - -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` -**Path:** /vectorTiles/layers/[1] - -How far outside its boundaries should the tile contain information. - -The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. - -

      mapper

      - -**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /vectorTiles/layers/[1] - -Describes the mapper converting from the OTP model entities to the vector tile properties. - -Currently `Digitransit` is supported for all layer types. - -

      cacheMaxSeconds

      - -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` -**Path:** /vectorTiles/layers/[2] - -Sets the cache header in the response. - -The lowest value of the layers included is selected. - -

      expansionFactor

      - -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` -**Path:** /vectorTiles/layers/[2] - -How far outside its boundaries should the tile contain information. - -The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. - -

      mapper

      - -**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /vectorTiles/layers/[2] - -Describes the mapper converting from the OTP model entities to the vector tile properties. - -Currently `Digitransit` is supported for all layer types. - -

      cacheMaxSeconds

      - -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` -**Path:** /vectorTiles/layers/[3] - -Sets the cache header in the response. - -The lowest value of the layers included is selected. - -

      expansionFactor

      - -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` -**Path:** /vectorTiles/layers/[3] - -How far outside its boundaries should the tile contain information. - -The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. - -

      mapper

      -**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /vectorTiles/layers/[3] - -Describes the mapper converting from the OTP model entities to the vector tile properties. - -Currently `Digitransit` is supported for all layer types. - -

      cacheMaxSeconds

      - -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` -**Path:** /vectorTiles/layers/[4] - -Sets the cache header in the response. - -The lowest value of the layers included is selected. - -

      expansionFactor

      - -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` -**Path:** /vectorTiles/layers/[4] - -How far outside its boundaries should the tile contain information. - -The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. - -

      mapper

      - -**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /vectorTiles/layers/[4] - -Describes the mapper converting from the OTP model entities to the vector tile properties. - -Currently `Digitransit` is supported for all layer types. - -

      cacheMaxSeconds

      - -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `-1` -**Path:** /vectorTiles/layers/[5] - -Sets the cache header in the response. - -The lowest value of the layers included is selected. - -

      expansionFactor

      - -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.25` -**Path:** /vectorTiles/layers/[5] - -How far outside its boundaries should the tile contain information. - -The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. - -

      mapper

      - -**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` -**Path:** /vectorTiles/layers/[5] - -Describes the mapper converting from the OTP model entities to the vector tile properties. - -Currently `Digitransit` is supported for all layer types. - - - -##### Example configuration - -```JSON -// router-config.json -{ - "updaters" : [ - { - "layers" : [ - { - "name" : "stops", - "type" : "Stop", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 600 - }, - { - "name" : "stations", - "type" : "Station", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 12, - "cacheMaxSeconds" : 600 - }, - { - "name" : "rentalPlaces", - "type" : "VehicleRental", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 60, - "expansionFactor" : 0.25 - }, - { - "name" : "rentalVehicle", - "type" : "VehicleRentalVehicle", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 60 - }, - { - "name" : "rentalStation", - "type" : "VehicleRentalStation", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 600 - }, - { - "name" : "vehicleParking", - "type" : "VehicleParking", - "mapper" : "Digitransit", - "maxZoom" : 20, - "minZoom" : 14, - "cacheMaxSeconds" : 60, - "expansionFactor" : 0.25 - } - ] - } - ] -} -``` diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java index 50dbd24008f..c0adbbd143b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java @@ -1,6 +1,5 @@ package org.opentripplanner.ext.vectortiles; -import static org.opentripplanner.framework.application.OtpFileNames.ROUTER_CONFIG_FILENAME; import static org.opentripplanner.framework.io.FileUtils.assertFileEquals; import static org.opentripplanner.framework.io.FileUtils.readFile; import static org.opentripplanner.framework.io.FileUtils.writeFile; @@ -8,7 +7,7 @@ import static org.opentripplanner.generate.doc.framework.DocsTestConstants.DOCS_ROOT; import static org.opentripplanner.generate.doc.framework.DocsTestConstants.TEMPLATE_ROOT; import static org.opentripplanner.generate.doc.framework.TemplateUtil.replaceSection; -import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromResource; +import static org.opentripplanner.standalone.config.framework.json.JsonSupport.jsonNodeFromPath; import java.io.File; import org.junit.jupiter.api.Test; @@ -19,6 +18,7 @@ import org.opentripplanner.generate.doc.framework.SkipNodes; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; +import org.opentripplanner.test.support.ResourceLoader; @GeneratesDocumentation public class VectorTilesConfigDocTest { @@ -27,7 +27,6 @@ public class VectorTilesConfigDocTest { private static final File TEMPLATE = new File(TEMPLATE_ROOT, DOCUMENT); private static final File OUT_FILE = new File(DOCS_ROOT, DOCUMENT); private static final SkipNodes SKIP_NODES = SkipNodes.of().build(); - private static final String ROUTER_CONFIG_PATH = "standalone/config/" + ROUTER_CONFIG_FILENAME; @Test public void updateDoc() { @@ -37,23 +36,23 @@ public void updateDoc() { String template = readFile(TEMPLATE); String original = readFile(OUT_FILE); - template = replaceSection(template, "parameters", updaterDoc(node)); + template = replaceSection(template, "parameters", vectorTilesDoc(node)); writeFile(OUT_FILE, template); assertFileEquals(original, OUT_FILE); } private NodeAdapter readVectorTiles() { - var json = jsonNodeFromResource(ROUTER_CONFIG_PATH); - var conf = new RouterConfig(json, ROUTER_CONFIG_PATH, false); + var path = ResourceLoader.of(this).file("router-config.json").toPath(); + var json = jsonNodeFromPath(path); + var conf = new RouterConfig(json, path.toString(), false); return conf.asNodeAdapter().child("vectorTiles"); } - private String updaterDoc(NodeAdapter node) { + private String vectorTilesDoc(NodeAdapter node) { DocBuilder buf = new DocBuilder(); addParameterSummaryTable(buf, node); addDetailsSection(buf, node); - addExample(buf, node); return buf.toString(); } @@ -73,8 +72,4 @@ private String getParameterDetailsTable(NodeAdapter node) { return ParameterDetailsList.listParametersWithDetails(node, SKIP_NODES, HEADER_4); } - private void addExample(DocBuilder buf, NodeAdapter node) { - buf.addSection("##### Example configuration"); - buf.addUpdaterExample(ROUTER_CONFIG_FILENAME, node.rawNode()); - } } diff --git a/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json b/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json new file mode 100644 index 00000000000..df325d076a3 --- /dev/null +++ b/src/ext/resources/org/opentripplanner/ext/vectortiles/router-config.json @@ -0,0 +1,16 @@ +{ + "vectorTiles": { + "basePath": "/otp_ct/vectorTiles", + "layers": [ + { + "name": "stops", + "type": "Stop", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + } + ] + } +} + diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index f64a3b0f3b9..ced4564ca8a 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -166,6 +166,7 @@ "hideFeedId": true }, "vectorTiles": { + "basePath": "/otp_ct/vectorTiles", "layers": [ { "name": "stops", From 9ab2afd1d6d5910ea14d481c9e1626b79606985d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 14:00:03 +0100 Subject: [PATCH 157/356] Improve tests --- doc-templates/sandbox/MapboxVectorTilesApi.md | 3 +-- docs/RouterConfiguration.md | 1 + docs/sandbox/MapboxVectorTilesApi.md | 3 +-- .../vectortiles/VectorTilesConfigDocTest.java | 1 - .../ext/vectortiles/VectorTilesResource.java | 2 +- .../apis/support/TileJson.java | 2 +- .../GraphInspectorVectorTileResource.java | 2 +- .../apis/support/TileJsonTest.java | 27 ++++++++++++++++--- 8 files changed, 29 insertions(+), 12 deletions(-) diff --git a/doc-templates/sandbox/MapboxVectorTilesApi.md b/doc-templates/sandbox/MapboxVectorTilesApi.md index dfba427919a..7fa1fefa56d 100644 --- a/doc-templates/sandbox/MapboxVectorTilesApi.md +++ b/doc-templates/sandbox/MapboxVectorTilesApi.md @@ -3,8 +3,7 @@ ## Contact Info - HSL, Finland -- Kyyti Group Oy, Finland -- Hannes Junnila +- IBI Arcardis, US ## Documentation diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 351c582d72d..556e672e482 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -603,6 +603,7 @@ Used to group requests when monitoring OTP. "hideFeedId" : true }, "vectorTiles" : { + "basePath" : "/otp_ct/vectorTiles", "layers" : [ { "name" : "stops", diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 547eb3501c1..75ab5008124 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -3,8 +3,7 @@ ## Contact Info - HSL, Finland -- Kyyti Group Oy, Finland -- Hannes Junnila +- IBI Arcardis, US ## Documentation diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java index c0adbbd143b..e758026d02b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java @@ -71,5 +71,4 @@ private void addDetailsSection(DocBuilder buf, NodeAdapter node) { private String getParameterDetailsTable(NodeAdapter node) { return ParameterDetailsList.listParametersWithDetails(node, SKIP_NODES, HEADER_4); } - } diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index e1c119713d1..3182936b281 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -96,7 +96,7 @@ public TileJson getTileJson( TileJson.overrideBasePath(uri, headers, overrideBasePath, requestedLayers) ) .orElseGet(() -> - TileJson.defaultBasePath(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles") + TileJson.defaultPath(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles") ); return new TileJson(url, envelope, feedInfos); diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index 840542d68a8..feedf1657ef 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -58,7 +58,7 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee center = new double[] { c.longitude(), c.latitude(), 9 }; } - public static String defaultBasePath( + public static String defaultPath( UriInfo uri, HttpHeaders headers, String layers, diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index ada9381ec1d..f5839cdabc2 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -103,7 +103,7 @@ public TileJson getTileJson( var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); List feedInfos = feedInfos(); - var url = TileJson.defaultBasePath( + var url = TileJson.defaultPath( uri, headers, requestedLayers, diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index 890dc09aa92..e9a7fe39eba 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -4,14 +4,18 @@ import java.net.URI; import java.net.URISyntaxException; +import javax.annotation.Nonnull; import org.glassfish.jersey.internal.MapPropertiesDelegate; import org.glassfish.jersey.server.ContainerRequest; import org.glassfish.jersey.server.internal.routing.UriRoutingContext; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; class TileJsonTest { + private static final String LAYERS = "stops,rentalVehicles"; + @ParameterizedTest @ValueSource( strings = { @@ -22,12 +26,27 @@ class TileJsonTest { } ) void overrideBasePath(String basePath) throws URISyntaxException { - var uri = new URI("https://localhost:8080"); - var header = new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); - var uriInfo = new UriRoutingContext(header); + var req = container(); + var uriInfo = new UriRoutingContext(req); assertEquals( "https://localhost:8080/otp_ct/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", - TileJson.overrideBasePath(uriInfo, header, basePath, "stops,rentalVehicles") + TileJson.overrideBasePath(uriInfo, req, basePath, LAYERS) ); } + + @Test + void defaultPath() throws URISyntaxException { + var req = container(); + var uriInfo = new UriRoutingContext(req); + assertEquals( + "https://localhost:8080/otp/routers/default/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", + TileJson.defaultPath(uriInfo, req, LAYERS, "default", "vectorTiles") + ); + } + + @Nonnull + private static ContainerRequest container() throws URISyntaxException { + var uri = new URI("https://localhost:8080"); + return new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); + } } From b542cb2970b3e5b1f3c48a94754d392d3feb696e Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 17 Jan 2024 12:21:54 +0100 Subject: [PATCH 158/356] doc+test: Add JavaDoc and UnitTest to DecorateFilter --- .../framework/filter/DecorateFilter.java | 6 +- .../framework/filter/DecorateFilterTest.java | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java index b2101c0ebfc..f0d44872db8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilter.java @@ -5,7 +5,11 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryListFilter; -public class DecorateFilter implements ItineraryListFilter { +/** + * This is the decorator filter implementation. To add a decorator, you should implement + * the {@link ItineraryDecorator}. + */ +public final class DecorateFilter implements ItineraryListFilter { private final ItineraryDecorator decorator; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java new file mode 100644 index 00000000000..9ae8e0da7df --- /dev/null +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java @@ -0,0 +1,60 @@ +package org.opentripplanner.routing.algorithm.filterchain.framework.filter; + +import static org.junit.jupiter.api.Assertions.*; +import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; + +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.PlanTestConstants; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; + +class DecorateFilterTest implements ItineraryDecorator, PlanTestConstants { + + private static final Itinerary i1 = newItinerary(A, 6).walk(1, B).build(); + private static final Itinerary i2 = newItinerary(A).bicycle(6, 8, B).build(); + + private Iterator expectedQueue; + + @Override + public void decorate(Itinerary itinerary) { + if (expectedQueue == null) { + fail("The expected queue is null, this method should not be called."); + } + + if (!expectedQueue.hasNext()) { + fail("No itineraries in list of expected, but filter is still processing: " + itinerary); + } + + var current = expectedQueue.next(); + assertEquals(current, itinerary); + } + + @Test + void filterEmptyList() { + // Make sure the filter does nothing and do not crash on empty lists + new DecorateFilter(this).filter(List.of()); + } + + @Test + void filterOneElement() { + var input = List.of(i1); + expectedQueue = input.iterator(); + new DecorateFilter(this).filter(input); + assertTrue(!expectedQueue.hasNext(), "All elements are processed"); + } + + @Test + void filterTwoElements() { + var input = List.of(i1, i2); + expectedQueue = input.iterator(); + new DecorateFilter(this).filter(input); + assertTrue(!expectedQueue.hasNext(), "All elements are processed"); + } +} From 3f47b57d0f8b3cb40aaa49a329a10febcd87ed64 Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 17 Jan 2024 15:43:14 +0100 Subject: [PATCH 159/356] Adds EncompassingAreaGeometry to the GroupStop and makes it queryable in the flexibleArea on the QuayType. --- .../apis/transmodel/model/stop/QuayType.java | 17 +++++++++-------- .../netex/mapping/FlexStopsMapper.java | 5 ++++- .../transit/model/site/GroupStop.java | 7 +++++++ .../transit/model/site/GroupStopBuilder.java | 19 +++++++++++++++++++ .../apis/transmodel/schema.graphql | 2 +- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index b80efab77b5..a15bf2f838e 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -380,20 +380,21 @@ public static GraphQLObjectType create( .name("flexibleArea") .description("Geometry for flexible area.") .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) - .dataFetcher(environment -> - ( - environment.getSource() instanceof AreaStop areaStop - ? areaStop.getGeometry().getCoordinates() - : null - ) - ) + .dataFetcher(environment -> { + if (environment.getSource() instanceof AreaStop areaStop) { + return areaStop.getGeometry().getCoordinates(); + } else if (environment.getSource() instanceof GroupStop groupStop) { + return groupStop.getEncompassingAreaGeometry().getCoordinates(); + } + return null; + }) .build() ) .field( GraphQLFieldDefinition .newFieldDefinition() .name("flexibleGroup") - .description("the Quays part of an flexible group.") + .description("the Quays part of a flexible group.") .type(GraphQLList.list(REF)) .dataFetcher(environment -> ( diff --git a/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java b/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java index 1e6eb1979bb..5bc8d63679a 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java +++ b/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java @@ -62,6 +62,7 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { List stops = new ArrayList<>(); TransitMode flexibleStopTransitMode = mapTransitMode(flexibleStopPlace); var areas = flexibleStopPlace.getAreas().getFlexibleAreaOrFlexibleAreaRefOrHailAndRideArea(); + ArrayList areaGeometries = new ArrayList<>(); for (var area : areas) { if (!(area instanceof FlexibleArea flexibleArea)) { issueStore.add( @@ -76,6 +77,7 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { } Geometry flexibleAreaGeometry = mapGeometry(flexibleArea); + areaGeometries.add(flexibleAreaGeometry); if (shouldAddStopsFromArea(flexibleArea, flexibleStopPlace)) { stops.addAll( @@ -100,7 +102,8 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { // get the ids for the area and stop place correct var builder = stopModelBuilder .groupStop(idFactory.createId(flexibleStopPlace.getId())) - .withName(new NonLocalizedString(flexibleStopPlace.getName().getValue())); + .withName(new NonLocalizedString(flexibleStopPlace.getName().getValue())) + .withEncompassingAreaGeometries(areaGeometries); stops.forEach(builder::addLocation); return builder.build(); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index ac3cca3dd13..f2baf84b5c3 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -24,6 +24,8 @@ public class GroupStop private final I18NString name; private final GeometryCollection geometry; + private final GeometryCollection encompassingAreaGeometry; + private final WgsCoordinate centroid; GroupStop(GroupStopBuilder builder) { @@ -33,6 +35,7 @@ public class GroupStop this.geometry = builder.geometry(); this.centroid = Objects.requireNonNull(builder.centroid()); this.stopLocations = builder.stopLocations(); + this.encompassingAreaGeometry = builder.encompassingAreaGeometry(); } public static GroupStopBuilder of(FeedScopedId id, IntSupplier indexCounter) { @@ -79,6 +82,10 @@ public Geometry getGeometry() { return geometry; } + public Geometry getEncompassingAreaGeometry() { + return encompassingAreaGeometry; + } + @Override public boolean isPartOfStation() { return false; diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 5e0dc596eba..b474658f5ec 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -1,5 +1,6 @@ package org.opentripplanner.transit.model.site; +import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import java.util.function.IntSupplier; @@ -26,6 +27,11 @@ public class GroupStopBuilder extends AbstractEntityBuilder geometries) { + this.encompassingAreaGeometry = + new GeometryCollection( + geometries.toArray(new Geometry[0]), + GeometryUtils.getGeometryFactory() + ); + return this; + } + public I18NString name() { return name; } @@ -90,6 +105,10 @@ public GeometryCollection geometry() { return geometry; } + public GeometryCollection encompassingAreaGeometry() { + return encompassingAreaGeometry; + } + public WgsCoordinate centroid() { return centroid; } diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 9b49283c180..25cf95ca2f9 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -579,7 +579,7 @@ type Quay implements PlaceInterface { ): [EstimatedCall!]! @timingData "Geometry for flexible area." flexibleArea: Coordinates - "the Quays part of an flexible group." + "the Quays part of a flexible group." flexibleGroup: [Quay] id: ID! "List of journey patterns servicing this quay" From b4eb8de32538fb6b1c8c1c8be926b0e0ceb3e481 Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 17 Jan 2024 15:43:14 +0100 Subject: [PATCH 160/356] Adds EncompassingAreaGeometry to the GroupStop and makes it queryable in the flexibleArea on the QuayType. --- .../apis/transmodel/model/stop/QuayType.java | 17 +++++++++-------- .../netex/mapping/FlexStopsMapper.java | 5 ++++- .../transit/model/site/GroupStop.java | 7 +++++++ .../transit/model/site/GroupStopBuilder.java | 19 +++++++++++++++++++ .../apis/transmodel/schema.graphql | 2 +- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index b80efab77b5..a15bf2f838e 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -380,20 +380,21 @@ public static GraphQLObjectType create( .name("flexibleArea") .description("Geometry for flexible area.") .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) - .dataFetcher(environment -> - ( - environment.getSource() instanceof AreaStop areaStop - ? areaStop.getGeometry().getCoordinates() - : null - ) - ) + .dataFetcher(environment -> { + if (environment.getSource() instanceof AreaStop areaStop) { + return areaStop.getGeometry().getCoordinates(); + } else if (environment.getSource() instanceof GroupStop groupStop) { + return groupStop.getEncompassingAreaGeometry().getCoordinates(); + } + return null; + }) .build() ) .field( GraphQLFieldDefinition .newFieldDefinition() .name("flexibleGroup") - .description("the Quays part of an flexible group.") + .description("the Quays part of a flexible group.") .type(GraphQLList.list(REF)) .dataFetcher(environment -> ( diff --git a/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java b/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java index 1e6eb1979bb..7e06db882f1 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java +++ b/src/main/java/org/opentripplanner/netex/mapping/FlexStopsMapper.java @@ -62,6 +62,7 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { List stops = new ArrayList<>(); TransitMode flexibleStopTransitMode = mapTransitMode(flexibleStopPlace); var areas = flexibleStopPlace.getAreas().getFlexibleAreaOrFlexibleAreaRefOrHailAndRideArea(); + List areaGeometries = new ArrayList<>(); for (var area : areas) { if (!(area instanceof FlexibleArea flexibleArea)) { issueStore.add( @@ -76,6 +77,7 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { } Geometry flexibleAreaGeometry = mapGeometry(flexibleArea); + areaGeometries.add(flexibleAreaGeometry); if (shouldAddStopsFromArea(flexibleArea, flexibleStopPlace)) { stops.addAll( @@ -100,7 +102,8 @@ StopLocation map(FlexibleStopPlace flexibleStopPlace) { // get the ids for the area and stop place correct var builder = stopModelBuilder .groupStop(idFactory.createId(flexibleStopPlace.getId())) - .withName(new NonLocalizedString(flexibleStopPlace.getName().getValue())); + .withName(new NonLocalizedString(flexibleStopPlace.getName().getValue())) + .withEncompassingAreaGeometries(areaGeometries); stops.forEach(builder::addLocation); return builder.build(); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index ac3cca3dd13..f2baf84b5c3 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -24,6 +24,8 @@ public class GroupStop private final I18NString name; private final GeometryCollection geometry; + private final GeometryCollection encompassingAreaGeometry; + private final WgsCoordinate centroid; GroupStop(GroupStopBuilder builder) { @@ -33,6 +35,7 @@ public class GroupStop this.geometry = builder.geometry(); this.centroid = Objects.requireNonNull(builder.centroid()); this.stopLocations = builder.stopLocations(); + this.encompassingAreaGeometry = builder.encompassingAreaGeometry(); } public static GroupStopBuilder of(FeedScopedId id, IntSupplier indexCounter) { @@ -79,6 +82,10 @@ public Geometry getGeometry() { return geometry; } + public Geometry getEncompassingAreaGeometry() { + return encompassingAreaGeometry; + } + @Override public boolean isPartOfStation() { return false; diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 5e0dc596eba..0c7b1f644d0 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -1,6 +1,7 @@ package org.opentripplanner.transit.model.site; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.function.IntSupplier; import javax.annotation.Nonnull; @@ -26,6 +27,11 @@ public class GroupStopBuilder extends AbstractEntityBuilder geometries) { + this.encompassingAreaGeometry = + new GeometryCollection( + geometries.toArray(new Geometry[0]), + GeometryUtils.getGeometryFactory() + ); + return this; + } + public I18NString name() { return name; } @@ -90,6 +105,10 @@ public GeometryCollection geometry() { return geometry; } + public GeometryCollection encompassingAreaGeometry() { + return encompassingAreaGeometry; + } + public WgsCoordinate centroid() { return centroid; } diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 9b49283c180..25cf95ca2f9 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -579,7 +579,7 @@ type Quay implements PlaceInterface { ): [EstimatedCall!]! @timingData "Geometry for flexible area." flexibleArea: Coordinates - "the Quays part of an flexible group." + "the Quays part of a flexible group." flexibleGroup: [Quay] id: ID! "List of journey patterns servicing this quay" From f290e95b5f38973c5e8a7d4079ca698e59dfc78d Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Wed, 17 Jan 2024 17:24:46 +0200 Subject: [PATCH 161/356] Move public methods up --- .../TriangleOptimizationConfig.java | 20 +++++++++---------- .../routerequest/VehicleParkingConfig.java | 18 ++++++++--------- .../routerequest/VehicleRentalConfig.java | 15 ++++++++------ .../routerequest/VehicleWalkingConfig.java | 18 ++++++++--------- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java index 361e591891c..e6da735a4ac 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java @@ -8,6 +8,16 @@ public class TriangleOptimizationConfig { + static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Builder preferences) { + var optimizationTriangle = c + .of("triangle") + .since(V2_5) + .summary("Triangle optimization criteria.") + .description("Optimization type doesn't need to be defined if these values are defined.") + .asObject(); + mapTriangleParameters(optimizationTriangle, preferences); + } + private static void mapTriangleParameters( NodeAdapter c, TimeSlopeSafetyTriangle.Builder builder @@ -41,14 +51,4 @@ private static void mapTriangleParameters( .asDouble(builder.safety()) ); } - - static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Builder preferences) { - var optimizationTriangle = c - .of("triangle") - .since(V2_5) - .summary("Triangle optimization criteria.") - .description("Optimization type doesn't need to be defined if these values are defined.") - .asObject(); - mapTriangleParameters(optimizationTriangle, preferences); - } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java index b4afc67e31c..218ac3b33df 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java @@ -11,6 +11,15 @@ public class VehicleParkingConfig { + static void mapParking(NodeAdapter c, VehicleParkingPreferences.Builder preferences) { + var vehicleParking = c + .of("parking") + .since(V2_5) + .summary("Preferences for parking a vehicle.") + .asObject(); + mapParkingPreferences(vehicleParking, preferences); + } + private static void mapParkingPreferences( NodeAdapter c, VehicleParkingPreferences.Builder builder @@ -81,13 +90,4 @@ Vehicle parking tags can originate from different places depending on the origin .asStringSet(List.of()) ); } - - static void mapParking(NodeAdapter c, VehicleParkingPreferences.Builder preferences) { - var vehicleParking = c - .of("parking") - .since(V2_5) - .summary("Preferences for parking a vehicle.") - .asObject(); - mapParkingPreferences(vehicleParking, preferences); - } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index f862e9b9628..401d977762d 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -10,7 +10,15 @@ public class VehicleRentalConfig { - static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder builder) { + static void mapRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { + var vehicleRental = c.of("rental").since(V2_3).summary("Vehicle rental options").asObject(); + mapRentalPreferences(vehicleRental, preferences); + } + + private static void mapRentalPreferences( + NodeAdapter c, + VehicleRentalPreferences.Builder builder + ) { var dft = builder.original(); builder .withDropOffCost( @@ -87,9 +95,4 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder .asStringSet(dft.bannedNetworks()) ); } - - static void mapRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { - var vehicleRental = c.of("rental").since(V2_3).summary("Vehicle rental options").asObject(); - mapRentalPreferences(vehicleRental, preferences); - } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index 6bc3bd3ffca..f2ba922c8e3 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -10,6 +10,15 @@ public class VehicleWalkingConfig { + static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { + var vehicleWalking = c + .of("walk") + .since(V2_5) + .summary("Preferences for walking a vehicle.") + .asObject(); + mapVehicleWalkingPreferences(vehicleWalking, preferences); + } + private static void mapVehicleWalkingPreferences( NodeAdapter c, VehicleWalkingPreferences.Builder builder @@ -70,13 +79,4 @@ private static void mapVehicleWalkingPreferences( .asDouble(dft.stairsReluctance()) ); } - - static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { - var vehicleWalking = c - .of("walk") - .since(V2_5) - .summary("Preferences for walking a vehicle.") - .asObject(); - mapVehicleWalkingPreferences(vehicleWalking, preferences); - } } From 7dbffd0122fa65b7bf5b0a3e03fc2c5208076153 Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 17 Jan 2024 16:26:49 +0100 Subject: [PATCH 162/356] Adds docstring to getEncompassingAreaGeometry and getGeometry methods of the GroupStop. --- .../org/opentripplanner/transit/model/site/GroupStop.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index f2baf84b5c3..2f2ddca044f 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -77,11 +77,17 @@ public WgsCoordinate getCoordinate() { return centroid; } + /** + * Returns the geometry of all stops and areas belonging to this location group. + */ @Override public Geometry getGeometry() { return geometry; } + /** + * Returns the geometry of the area that encompasses the bounds of this location group. + */ public Geometry getEncompassingAreaGeometry() { return encompassingAreaGeometry; } From 103c498130c9845532b5075d1fbb94b6de4f4082 Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 17 Jan 2024 16:34:21 +0100 Subject: [PATCH 163/356] Defaults encompassingAreaGeometry in GroupStopBuilder (and therefore also GroupStop) to null instead of an empty GeometryCollection. --- .../opentripplanner/transit/model/site/GroupStopBuilder.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 0c7b1f644d0..b574eb8c9ea 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -27,10 +27,7 @@ public class GroupStopBuilder extends AbstractEntityBuilder Date: Wed, 17 Jan 2024 17:37:57 +0200 Subject: [PATCH 164/356] Rename variables --- .../routerequest/RouteRequestConfig.java | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 6ee164f0083..ed3fa29cc8e 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -334,19 +334,19 @@ The board time is added to the time when going from the stop (offboard) to onboa ); } - private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder builder) { + private static void mapBikePreferences(NodeAdapter root, BikePreferences.Builder builder) { var dft = builder.original(); - NodeAdapter cb = c.of("bicycle").since(V2_5).summary("Bicycle preferences.").asObject(); + NodeAdapter c = root.of("bicycle").since(V2_5).summary("Bicycle preferences.").asObject(); builder .withSpeed( - cb + c .of("speed") .since(V2_0) .summary("Max bicycle speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - cb + c .of("reluctance") .since(V2_0) .summary( @@ -355,7 +355,7 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .asDouble(dft.reluctance()) ) .withBoardCost( - cb + c .of("boardCost") .since(V2_0) .summary( @@ -368,7 +368,7 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .asInt(dft.boardCost()) ) .withOptimizeType( - cb + c .of("optimization") .since(V2_0) .summary("The set of characteristics that the user wants to optimize for.") @@ -378,10 +378,10 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .asEnum(dft.optimizeType()) ) // triangle overrides the optimization type if defined - .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) - .withWalking(it -> mapVehicleWalking(cb, it)) - .withParking(it -> mapParking(cb, it)) - .withRental(it -> mapRental(cb, it)); + .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(c, it)) + .withWalking(it -> mapVehicleWalking(c, it)) + .withParking(it -> mapParking(c, it)) + .withRental(it -> mapRental(c, it)); } private static void mapStreetPreferences(NodeAdapter c, StreetPreferences.Builder builder) { @@ -570,19 +570,19 @@ The street search(AStar) aborts after this duration and any paths found are retu ); } - private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder builder) { + private static void mapCarPreferences(NodeAdapter root, CarPreferences.Builder builder) { var dft = builder.original(); - NodeAdapter cc = c.of("car").since(V2_5).summary("Car preferences.").asObject(); + NodeAdapter c = root.of("car").since(V2_5).summary("Car preferences.").asObject(); builder .withSpeed( - cc + c .of("speed") .since(V2_0) .summary("Max car speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - cc + c .of("reluctance") .since(V2_0) .summary( @@ -591,35 +591,35 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .asDouble(dft.reluctance()) ) .withPickupCost( - cc + c .of("pickupCost") .since(V2_1) .summary("Add a cost for car pickup changes when a pickup or drop off takes place") .asInt(dft.pickupCost().toSeconds()) ) .withPickupTime( - cc + c .of("pickupTime") .since(V2_1) .summary("Add a time for car pickup changes when a pickup or drop off takes place") .asDuration(dft.pickupTime()) ) .withAccelerationSpeed( - cc + c .of("accelerationSpeed") .since(V2_0) .summary("The acceleration speed of an automobile, in meters per second per second.") .asDouble(dft.accelerationSpeed()) ) .withDecelerationSpeed( - cc + c .of("decelerationSpeed") .since(V2_0) .summary("The deceleration speed of an automobile, in meters per second per second.") .asDouble(dft.decelerationSpeed()) ) - .withParking(it -> mapParking(cc, it)) - .withRental(it -> mapRental(cc, it)); + .withParking(it -> mapParking(c, it)) + .withRental(it -> mapRental(c, it)); } private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builder builder) { @@ -670,19 +670,19 @@ private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builde } } - private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder walk) { + private static void mapWalkPreferences(NodeAdapter root, WalkPreferences.Builder walk) { var dft = walk.original(); - NodeAdapter cw = c.of("walk").since(V2_5).summary("Walking preferences.").asObject(); + NodeAdapter c = root.of("walk").since(V2_5).summary("Walking preferences.").asObject(); walk .withSpeed( - cw + c .of("speed") .since(V2_0) .summary("The user's walking speed in meters/second.") .asDouble(dft.speed()) ) .withReluctance( - cw + c .of("reluctance") .since(V2_0) .summary( @@ -700,7 +700,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.reluctance()) ) .withBoardCost( - cw + c .of("boardCost") .since(V2_0) .summary( @@ -712,14 +712,14 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asInt(dft.boardCost()) ) .withStairsReluctance( - cw + c .of("stairsReluctance") .since(V2_0) .summary("Used instead of walkReluctance for stairs.") .asDouble(dft.stairsReluctance()) ) .withStairsTimeFactor( - cw + c .of("stairsTimeFactor") .since(V2_1) .summary( @@ -734,7 +734,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.stairsTimeFactor()) ) .withSafetyFactor( - cw + c .of("safetyFactor") .since(V2_2) .summary("Factor for how much the walk safety is considered in routing.") @@ -744,7 +744,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.safetyFactor()) ) .withEscalatorReluctance( - cw + c .of("escalatorReluctance") .since(V2_4) .summary( From ba16135dee31b74d722419cb483b0a449235b030 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Sun, 14 Jan 2024 12:41:02 +0100 Subject: [PATCH 165/356] refactor: Code cleanup Throttle --- .../opentripplanner/framework/logging/Throttle.java | 12 ++++++++---- .../framework/logging/ThrottleTest.java | 5 +++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/opentripplanner/framework/logging/Throttle.java b/src/main/java/org/opentripplanner/framework/logging/Throttle.java index 631d59a2697..ed8a2c1bef4 100644 --- a/src/main/java/org/opentripplanner/framework/logging/Throttle.java +++ b/src/main/java/org/opentripplanner/framework/logging/Throttle.java @@ -1,5 +1,6 @@ package org.opentripplanner.framework.logging; +import java.time.Duration; import org.opentripplanner.framework.time.TimeUtils; /** @@ -26,17 +27,20 @@ public class Throttle { private long timeout = Long.MIN_VALUE; private final String setupInfo; - Throttle(int quietPeriodMilliseconds) { - this.quietPeriodMilliseconds = quietPeriodMilliseconds; + /** + * Package local to be able to unit test. + */ + Throttle(Duration quietPeriod) { + this.quietPeriodMilliseconds = (int) quietPeriod.toMillis(); this.setupInfo = "(throttle " + TimeUtils.msToString(quietPeriodMilliseconds) + " interval)"; } public static Throttle ofOneSecond() { - return new Throttle(1000); + return new Throttle(Duration.ofSeconds(1)); } public static Throttle ofOneMinute() { - return new Throttle(1000 * 60); + return new Throttle(Duration.ofMinutes(1)); } public String setupInfo() { diff --git a/src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java b/src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java index 91f1667486d..c9155992daa 100644 --- a/src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java +++ b/src/test/java/org/opentripplanner/framework/logging/ThrottleTest.java @@ -1,5 +1,6 @@ package org.opentripplanner.framework.logging; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -36,8 +37,8 @@ void smokeTest() { @Test @Disabled("Run this test manually") void manualTest() { - double quietPeriodMs = 50.0; - var subject = new Throttle((int) quietPeriodMs); + var quietPeriod = Duration.ofMillis(50); + var subject = new Throttle(quietPeriod); List events = createIntegerSequence(20_000_000); long start = System.currentTimeMillis(); From 1a0e3739b7c61d060348de3186bb329087ee1e6f Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 17 Jan 2024 16:58:02 +0100 Subject: [PATCH 166/356] refactor: Reduce dependency scope for PriorityGroupConfigurator This will make it simpler to build a report later --- .../transit/request/PriorityGroupConfigurator.java | 12 +++++------- .../RaptorRoutingRequestTransitDataCreator.java | 2 +- .../request/PriorityGroupConfiguratorTest.java | 12 ++++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java index 826b9c09a13..6ef82786b99 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfigurator.java @@ -11,7 +11,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.grouppriority.TransitGroupPriority32n; import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.RoutingTripPattern; +import org.opentripplanner.transit.model.network.TripPattern; /** * This class dynamically builds an index of transit-group-ids from the @@ -94,16 +94,14 @@ public static PriorityGroupConfigurator of( *

      * @throws IllegalArgumentException if more than 32 group-ids are requested. */ - public int lookupTransitGroupPriorityId(RoutingTripPattern tripPattern) { + public int lookupTransitGroupPriorityId(TripPattern tripPattern) { if (!enabled || tripPattern == null) { return baseGroupId; } - var p = tripPattern.getPattern(); - for (var it : agencyMatchersIds) { - if (it.matcher().match(p)) { - var agencyId = p.getRoute().getAgency().getId(); + if (it.matcher().match(tripPattern)) { + var agencyId = tripPattern.getRoute().getAgency().getId(); int groupId = it.ids().get(agencyId); if (groupId < 0) { @@ -115,7 +113,7 @@ public int lookupTransitGroupPriorityId(RoutingTripPattern tripPattern) { } for (var it : globalMatchersIds) { - if (it.matcher.match(p)) { + if (it.matcher.match(tripPattern)) { return it.groupId(); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java index b8f915d6eb4..863a4ca9ae8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/RaptorRoutingRequestTransitDataCreator.java @@ -147,7 +147,7 @@ static List merge( tripPattern.getAlightingPossible(), BoardAlight.ALIGHT ), - priorityGroupConfigurator.lookupTransitGroupPriorityId(tripPattern) + priorityGroupConfigurator.lookupTransitGroupPriorityId(tripPattern.getPattern()) ) ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java index cc4bb09f01e..7f974927c1b 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/PriorityGroupConfiguratorTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.routing.api.request.request.filter.TransitGroupSelect; import org.opentripplanner.transit.model.basic.TransitMode; -import org.opentripplanner.transit.model.network.RoutingTripPattern; +import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; class PriorityGroupConfiguratorTest { @@ -60,11 +60,11 @@ class PriorityGroupConfiguratorTest { "10:00 10:10" ); - private final RoutingTripPattern railR1 = routeR1.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern busB2 = routeB2.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern railR3 = routeR3.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern ferryF3 = routeF3.getTripPattern().getRoutingTripPattern(); - private final RoutingTripPattern busB3 = routeB3.getTripPattern().getRoutingTripPattern(); + private final TripPattern railR1 = routeR1.getTripPattern(); + private final TripPattern busB2 = routeB2.getTripPattern(); + private final TripPattern railR3 = routeR3.getTripPattern(); + private final TripPattern ferryF3 = routeF3.getTripPattern(); + private final TripPattern busB3 = routeB3.getTripPattern(); @Test void emptyConfigurationShouldReturnGroupZero() { From 390fe32ec826a99bc41e0cd7f96eabd84857e14a Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 17 Jan 2024 16:59:25 +0100 Subject: [PATCH 167/356] feature: Add a report for transit groups to the report API --- .../model/TransitGroupPriorityReport.java | 86 +++++++++++++++++++ .../reportapi/resource/ReportResource.java | 14 +++ 2 files changed, 100 insertions(+) create mode 100644 src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java b/src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java new file mode 100644 index 00000000000..635469cb3a2 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/reportapi/model/TransitGroupPriorityReport.java @@ -0,0 +1,86 @@ +package org.opentripplanner.ext.reportapi.model; + +import java.util.Collection; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.stream.Collectors; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.request.PriorityGroupConfigurator; +import org.opentripplanner.routing.api.request.request.TransitRequest; +import org.opentripplanner.transit.model.network.TripPattern; + +/** + * This class is used to report all transit-groups used for transit-group-priority. The report is + * useful when configuring/debugging this functionality. + *

      + * The format is pure text. + */ +public class TransitGroupPriorityReport { + + public static String build(Collection patterns, TransitRequest request) { + var c = PriorityGroupConfigurator.of( + request.priorityGroupsByAgency(), + request.priorityGroupsGlobal() + ); + + var map = new TreeMap(); + for (var it : patterns) { + int groupId = c.lookupTransitGroupPriorityId(it); + var de = map.computeIfAbsent(groupId, DebugEntity::new); + de.add( + it.getRoute().getAgency().getId().toString(), + it.getMode().name(), + it.getNetexSubmode().name() + ); + } + return ( + "TRANSIT GROUPS PRIORITY" + + map.values().stream().map(DebugEntity::toString).sorted().collect(Collectors.joining("")) + ); + } + + private static class DebugEntity { + + private final int groupId; + private final TreeMap agencies = new TreeMap<>(); + + public DebugEntity(int groupId) { + this.groupId = groupId; + } + + void add(String agency, String mode, String submode) { + agencies.computeIfAbsent(agency, AgencyEntry::new).add(mode, submode); + } + + @Override + public String toString() { + var buf = new StringBuilder("\n %#010x".formatted(groupId)); + for (var it : agencies.values()) { + buf.append("\n ").append(it.toString()); + } + return buf.toString(); + } + } + + private record AgencyEntry(String agency, TreeMap> modes) { + private AgencyEntry(String agency) { + this(agency, new TreeMap<>()); + } + + void add(String mode, String submode) { + modes.computeIfAbsent(mode, m -> new TreeSet<>()).add(submode); + } + + @Override + public String toString() { + var buf = new StringBuilder(); + for (var it : modes.entrySet()) { + buf.append(", "); + buf.append(it.getKey()); + if (!it.getValue().isEmpty()) { + buf.append(" (").append(String.join(", ", it.getValue())).append(")"); + } + } + return agency + " ~ " + buf.substring(2); + } + } +} diff --git a/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java b/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java index 6ccb728800e..a859b4ff78a 100644 --- a/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java +++ b/src/ext/java/org/opentripplanner/ext/reportapi/resource/ReportResource.java @@ -17,8 +17,10 @@ import org.opentripplanner.ext.reportapi.model.GraphReportBuilder; import org.opentripplanner.ext.reportapi.model.GraphReportBuilder.GraphStats; import org.opentripplanner.ext.reportapi.model.TransfersReport; +import org.opentripplanner.ext.reportapi.model.TransitGroupPriorityReport; import org.opentripplanner.model.transfer.TransferService; import org.opentripplanner.openstreetmap.tagmapping.OsmTagMapperSource; +import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.service.TransitService; @@ -33,11 +35,13 @@ public class ReportResource { private final TransferService transferService; private final TransitService transitService; + private final RouteRequest defaultRequest; @SuppressWarnings("unused") public ReportResource(@Context OtpServerRequestContext requestContext) { this.transferService = requestContext.transitService().getTransferService(); this.transitService = requestContext.transitService(); + this.defaultRequest = requestContext.defaultRouteRequest(); } @GET @@ -80,6 +84,16 @@ public Response getBicycleSafetyAsCsv( .build(); } + @GET + @Path("/transit/group/priorities") + @Produces(MediaType.TEXT_PLAIN) + public String getTransitGroupPriorities() { + return TransitGroupPriorityReport.build( + transitService.getAllTripPatterns(), + defaultRequest.journey().transit() + ); + } + @GET @Path("/graph.json") public Response stats(@Context OtpServerRequestContext serverRequestContext) { From 90eb73cea489823295bcce368a7a3a2778217ba1 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Wed, 17 Jan 2024 17:08:48 +0100 Subject: [PATCH 168/356] doc: Add sandbox report doc. --- docs/sandbox/ReportApi.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/sandbox/ReportApi.md b/docs/sandbox/ReportApi.md index fdb6c2d3146..1a0668d1740 100644 --- a/docs/sandbox/ReportApi.md +++ b/docs/sandbox/ReportApi.md @@ -32,6 +32,8 @@ This module mounts an endpoint for generating reports under `otp/report`. Availa - [German version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=germany) - [UK version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=uk) - [Finnish version](http://localhost:8080/otp/report/bicycle-safety.csv?osmWayPropertySet=finland) +- [/otp/report/transit/group/priorities](http://localhost:8080/otp/report/transit/group/priorities): + List all transit groups used for transit-group-priority (Competition neutral planning). ### Configuration From 66f3fc59f4ff247b8c521177ed2318aff9591b48 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 16:49:52 +0100 Subject: [PATCH 169/356] Improve documentation --- doc-templates/sandbox/MapboxVectorTilesApi.md | 18 ++--- docs/sandbox/MapboxVectorTilesApi.md | 66 +++++++++++-------- .../apis/support/TileJson.java | 8 +++ .../config/routerconfig/VectorTileConfig.java | 20 +++++- 4 files changed, 71 insertions(+), 41 deletions(-) diff --git a/doc-templates/sandbox/MapboxVectorTilesApi.md b/doc-templates/sandbox/MapboxVectorTilesApi.md index 7fa1fefa56d..4e3e047fedb 100644 --- a/doc-templates/sandbox/MapboxVectorTilesApi.md +++ b/doc-templates/sandbox/MapboxVectorTilesApi.md @@ -14,6 +14,9 @@ public transit entities on the map. The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, where `layers` is a comma separated list of layer names from the configuration. +Maplibre/Mapbox GL JS also require a tilejson.json endpoint which is available at +`/otp/routers/{routerId}/vectorTiles/{layers}/tilejson.json`. + Translatable fields in the tiles are translated based on the `accept-language` header in requests. Currently, only the language with the highest priority from the header is used. @@ -137,14 +140,8 @@ For each layer, the configuration includes: - `VehicleRentalStation`: rental stations - `VehicleParking` - `VehicleParkingGroup` -- `mapper` which describes the mapper converting the properties from the OTP model entities to the - vector tile properties. Currently `Digitransit` is supported for all layer types. -- `minZoom` and `maxZoom` which describe the zoom levels the layer is active for. -- `cacheMaxSeconds` which sets the cache header in the response. The lowest value of the layers - included is selected. -- `expansionFactor` How far outside its boundaries should the tile contain information. The value is - a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile - edges, then increase this number. + + ### Extending @@ -162,9 +159,6 @@ new `LayerType` enum as the key, and the class constructor as the value. A new mapper needs to be added every time a new layer is added. See below for information. - - - #### Creating a new mapper The mapping contains information of what data to include in the vector tiles. The mappers are @@ -172,7 +166,7 @@ defined per layer. In order to create a new mapper for a layer, you need to create a new class extending `PropertyMapper`. In that class, you need to implement the -method `Collection> map(T input)`. The type T is dependent on the layer for which +method `Collection> map(T input)`. The type T is dependent on the layer for which you implement the mapper for. It needs to return a list of attributes, as key-value pairs which will be written into the vector tile. diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 75ab5008124..cfb9a634129 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -14,6 +14,9 @@ public transit entities on the map. The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, where `layers` is a comma separated list of layer names from the configuration. +Maplibre/Mapbox GL JS also require a tilejson.json endpoint which is available at +`/otp/routers/{routerId}/vectorTiles/{layers}/tilejson.json`. + Translatable fields in the tiles are translated based on the `accept-language` header in requests. Currently, only the language with the highest priority from the header is used. @@ -137,38 +140,13 @@ For each layer, the configuration includes: - `VehicleRentalStation`: rental stations - `VehicleParking` - `VehicleParkingGroup` -- `mapper` which describes the mapper converting the properties from the OTP model entities to the - vector tile properties. Currently `Digitransit` is supported for all layer types. -- `minZoom` and `maxZoom` which describe the zoom levels the layer is active for. -- `cacheMaxSeconds` which sets the cache header in the response. The lowest value of the layers - included is selected. -- `expansionFactor` How far outside its boundaries should the tile contain information. The value is - a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile - edges, then increase this number. - -### Extending - -If more generic layers are created for this API, it should be moved out from the sandbox, into the -core code, with potentially leaving specific property mappers in place. - -#### Creating a new layer - -In order to create a new type of layer, you need to create a new class extending `LayerBuilder`. -You need to implement two methods, `List getGeometries(Envelope query)`, which returns a -list of geometries, with an object of type `T` as their userData in the geometry, -and `double getExpansionFactor()`, which describes how much information outside the tile bounds -should be included. This layer then needs to be added into `VectorTilesResource.layers`, with a -new `LayerType` enum as the key, and the class constructor as the value. - -A new mapper needs to be added every time a new layer is added. See below for information. - | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |----------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| basePath | `string` | TODO: Add short summary. | *Optional* | | 2.5 | +| [basePath](#vectorTiles_basePath) | `string` | The path of the vector tile source URLs in `tilejson.json`. | *Optional* | | 2.5 | | [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | |       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | |       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | @@ -181,6 +159,24 @@ A new mapper needs to be added every time a new layer is added. See below for in #### Details +

      basePath

      + +**Since version:** `2.5` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` +**Path:** /vectorTiles + +The path of the vector tile source URLs in `tilejson.json`. + +This is useful if you have a proxy setup and rewrite the path that is passed to OTP. + +If you don't configure this optional value then the path returned in `tilejson.json` is +`/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you set a value of +`/otp_test/tiles` then the returned path changes to `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. + +The protocol and host are read from the incoming HTTP request. If you run OTP behind a proxy +then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP +return the protocol and host for the original request and not the proxied one. + +

      layers

      **Since version:** `2.0` ∙ **Type:** `object[]` ∙ **Cardinality:** `Optional` @@ -220,6 +216,22 @@ Currently `Digitransit` is supported for all layer types. +### Extending + +If more generic layers are created for this API, it should be moved out from the sandbox, into the +core code, with potentially leaving specific property mappers in place. + +#### Creating a new layer + +In order to create a new type of layer, you need to create a new class extending `LayerBuilder`. +You need to implement two methods, `List getGeometries(Envelope query)`, which returns a +list of geometries, with an object of type `T` as their userData in the geometry, +and `double getExpansionFactor()`, which describes how much information outside the tile bounds +should be included. This layer then needs to be added into `VectorTilesResource.layers`, with a +new `LayerType` enum as the key, and the class constructor as the value. + +A new mapper needs to be added every time a new layer is added. See below for information. + #### Creating a new mapper The mapping contains information of what data to include in the vector tiles. The mappers are @@ -227,7 +239,7 @@ defined per layer. In order to create a new mapper for a layer, you need to create a new class extending `PropertyMapper`. In that class, you need to implement the -method `Collection> map(T input)`. The type T is dependent on the layer for which +method `Collection> map(T input)`. The type T is dependent on the layer for which you implement the mapper for. It needs to return a list of attributes, as key-value pairs which will be written into the vector tile. diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index feedf1657ef..c30e4809533 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -58,6 +58,10 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee center = new double[] { c.longitude(), c.latitude(), 9 }; } + /** + * Creates a vector source layer URL from a hard-coded path plus information from the incoming + * HTTP request. + */ public static String defaultPath( UriInfo uri, HttpHeaders headers, @@ -73,6 +77,10 @@ public static String defaultPath( ); } + /** + * Creates a vector source layer URL from a configured base path plus information from the incoming + * HTTP request. + */ public static String overrideBasePath( UriInfo uri, HttpHeaders headers, diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index df353f40079..67fd2496e3c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -9,7 +9,6 @@ import java.util.Collection; import java.util.List; -import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; @@ -50,7 +49,24 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String .since(V2_0) .summary("Configuration of the individual layers for the Mapbox vector tiles.") .asObjects(VectorTileConfig::mapLayer), - root.of("basePath").since(V2_5).asString(DEFAULT.basePath) + root + .of("basePath") + .since(V2_5) + .summary("The path of the vector tile source URLs in `tilejson.json`.") + .description( + """ + This is useful if you have a proxy setup and rewrite the path that is passed to OTP. + + If you don't configure this optional value then the path returned in `tilejson.json` is + `/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you set a value of + `/otp_test/tiles` then the returned path changes to `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. + + The protocol and host are read from the incoming HTTP request. If you run OTP behind a proxy + then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP + return the protocol and host for the original request and not the proxied one. + """ + ) + .asString(DEFAULT.basePath) ); } From 7c9958b2fe10f55c626fa4bb715185f471e58eae Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 21:10:52 +0100 Subject: [PATCH 170/356] Add test for resource --- .../vectortiles/VectorTilesResourceTest.java | 31 +++++++++++++++++++ .../opentripplanner/TestServerContext.java | 10 +++++- .../apis/support/TileJsonTest.java | 20 +++--------- .../test/support/HttpForTest.java | 18 +++++++++++ 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java create mode 100644 src/test/java/org/opentripplanner/test/support/HttpForTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java new file mode 100644 index 00000000000..ff9509a8474 --- /dev/null +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesResourceTest.java @@ -0,0 +1,31 @@ +package org.opentripplanner.ext.vectortiles; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.glassfish.grizzly.http.server.Request; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.opentripplanner.TestServerContext; +import org.opentripplanner.routing.graph.Graph; +import org.opentripplanner.test.support.HttpForTest; +import org.opentripplanner.transit.service.TransitModel; + +class VectorTilesResourceTest { + + @Test + void tileJson() { + // the Grizzly request is awful to instantiate, using Mockito + var grizzlyRequest = Mockito.mock(Request.class); + var resource = new VectorTilesResource( + TestServerContext.createServerContext(new Graph(), new TransitModel()), + grizzlyRequest, + "default" + ); + var req = HttpForTest.containerRequest(); + var tileJson = resource.getTileJson(req.getUriInfo(), req, "layer1,layer2"); + assertEquals( + "https://localhost:8080/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{y}.pbf", + tileJson.tiles[0] + ); + } +} diff --git a/src/test/java/org/opentripplanner/TestServerContext.java b/src/test/java/org/opentripplanner/TestServerContext.java index dd640c1f000..5d74dbba240 100644 --- a/src/test/java/org/opentripplanner/TestServerContext.java +++ b/src/test/java/org/opentripplanner/TestServerContext.java @@ -16,6 +16,7 @@ import org.opentripplanner.service.worldenvelope.WorldEnvelopeService; import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeRepository; import org.opentripplanner.service.worldenvelope.internal.DefaultWorldEnvelopeService; +import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.RouterConfig; import org.opentripplanner.standalone.server.DefaultServerRequestContext; @@ -58,7 +59,14 @@ public static OtpServerRequestContext createServerContext( /** Static factory method to create a service for test purposes. */ public static WorldEnvelopeService createWorldEnvelopeService() { - return new DefaultWorldEnvelopeService(new DefaultWorldEnvelopeRepository()); + var repository = new DefaultWorldEnvelopeRepository(); + var envelope = WorldEnvelope + .of() + .expandToIncludeStreetEntities(0, 0) + .expandToIncludeStreetEntities(1, 1) + .build(); + repository.saveEnvelope(envelope); + return new DefaultWorldEnvelopeService(repository); } public static RealtimeVehicleService createRealtimeVehicleService(TransitService transitService) { diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index e9a7fe39eba..053b6ee89ef 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -2,15 +2,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import java.net.URI; -import java.net.URISyntaxException; -import javax.annotation.Nonnull; -import org.glassfish.jersey.internal.MapPropertiesDelegate; -import org.glassfish.jersey.server.ContainerRequest; import org.glassfish.jersey.server.internal.routing.UriRoutingContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.test.support.HttpForTest; class TileJsonTest { @@ -25,8 +21,8 @@ class TileJsonTest { "///otp_ct/vectorTiles/", } ) - void overrideBasePath(String basePath) throws URISyntaxException { - var req = container(); + void overrideBasePath(String basePath) { + var req = HttpForTest.containerRequest(); var uriInfo = new UriRoutingContext(req); assertEquals( "https://localhost:8080/otp_ct/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", @@ -35,18 +31,12 @@ void overrideBasePath(String basePath) throws URISyntaxException { } @Test - void defaultPath() throws URISyntaxException { - var req = container(); + void defaultPath() { + var req = HttpForTest.containerRequest(); var uriInfo = new UriRoutingContext(req); assertEquals( "https://localhost:8080/otp/routers/default/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", TileJson.defaultPath(uriInfo, req, LAYERS, "default", "vectorTiles") ); } - - @Nonnull - private static ContainerRequest container() throws URISyntaxException { - var uri = new URI("https://localhost:8080"); - return new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); - } } diff --git a/src/test/java/org/opentripplanner/test/support/HttpForTest.java b/src/test/java/org/opentripplanner/test/support/HttpForTest.java new file mode 100644 index 00000000000..b130a2f3fde --- /dev/null +++ b/src/test/java/org/opentripplanner/test/support/HttpForTest.java @@ -0,0 +1,18 @@ +package org.opentripplanner.test.support; + +import java.net.URI; +import java.net.URISyntaxException; +import org.glassfish.jersey.internal.MapPropertiesDelegate; +import org.glassfish.jersey.server.ContainerRequest; + +public class HttpForTest { + + public static ContainerRequest containerRequest() { + try { + URI uri = new URI("https://localhost:8080"); + return new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } +} From 34793eb6a8e4eb9b2de25adff5f6e6cb97f684d5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 21:58:21 +0100 Subject: [PATCH 171/356] Rename methods --- .../opentripplanner/ext/vectortiles/VectorTilesResource.java | 4 ++-- src/main/java/org/opentripplanner/apis/support/TileJson.java | 4 ++-- .../apis/vectortiles/GraphInspectorVectorTileResource.java | 2 +- .../java/org/opentripplanner/apis/support/TileJsonTest.java | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index 3182936b281..d87c60836de 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -93,10 +93,10 @@ public TileJson getTileJson( .vectorTileConfig() .basePath() .map(overrideBasePath -> - TileJson.overrideBasePath(uri, headers, overrideBasePath, requestedLayers) + TileJson.urlFromOverriddenBasePath(uri, headers, overrideBasePath, requestedLayers) ) .orElseGet(() -> - TileJson.defaultPath(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles") + TileJson.urlWithDefaultPath(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles") ); return new TileJson(url, envelope, feedInfos); diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index c30e4809533..09261e295e0 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -62,7 +62,7 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee * Creates a vector source layer URL from a hard-coded path plus information from the incoming * HTTP request. */ - public static String defaultPath( + public static String urlWithDefaultPath( UriInfo uri, HttpHeaders headers, String layers, @@ -81,7 +81,7 @@ public static String defaultPath( * Creates a vector source layer URL from a configured base path plus information from the incoming * HTTP request. */ - public static String overrideBasePath( + public static String urlFromOverriddenBasePath( UriInfo uri, HttpHeaders headers, String overridePath, diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index f5839cdabc2..666adebbbf7 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -103,7 +103,7 @@ public TileJson getTileJson( var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); List feedInfos = feedInfos(); - var url = TileJson.defaultPath( + var url = TileJson.urlWithDefaultPath( uri, headers, requestedLayers, diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index 053b6ee89ef..6b78042bf29 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -26,7 +26,7 @@ void overrideBasePath(String basePath) { var uriInfo = new UriRoutingContext(req); assertEquals( "https://localhost:8080/otp_ct/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", - TileJson.overrideBasePath(uriInfo, req, basePath, LAYERS) + TileJson.urlFromOverriddenBasePath(uriInfo, req, basePath, LAYERS) ); } @@ -36,7 +36,7 @@ void defaultPath() { var uriInfo = new UriRoutingContext(req); assertEquals( "https://localhost:8080/otp/routers/default/vectorTiles/stops,rentalVehicles/{z}/{x}/{y}.pbf", - TileJson.defaultPath(uriInfo, req, LAYERS, "default", "vectorTiles") + TileJson.urlWithDefaultPath(uriInfo, req, LAYERS, "default", "vectorTiles") ); } } From ded7050e670e3e3b5268cc81e0e489415c2a91c2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 22:19:17 +0100 Subject: [PATCH 172/356] Reuse helper class --- .../standalone/server/EtagRequestFilterTest.java | 11 +++-------- .../org/opentripplanner/test/support/HttpForTest.java | 8 ++++++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java b/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java index 1451a218852..5adf8264d8e 100644 --- a/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java +++ b/src/test/java/org/opentripplanner/standalone/server/EtagRequestFilterTest.java @@ -8,7 +8,6 @@ import java.nio.charset.StandardCharsets; import java.util.stream.Stream; import javax.annotation.Nonnull; -import org.glassfish.jersey.internal.MapPropertiesDelegate; import org.glassfish.jersey.message.internal.OutboundJaxrsResponse; import org.glassfish.jersey.message.internal.OutboundMessageContext; import org.glassfish.jersey.message.internal.Statuses; @@ -17,6 +16,7 @@ import org.jets3t.service.utils.Mimetypes; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.opentripplanner.test.support.HttpForTest; import org.opentripplanner.test.support.VariableSource; class EtagRequestFilterTest { @@ -44,7 +44,7 @@ void writeEtag( byte[] entity, String expectedEtag ) throws IOException { - var request = request(method); + var request = HttpForTest.containerRequest(method); var response = response(status, request); var headers = response.getHeaders(); headers.add(EtagRequestFilter.HEADER_CONTENT_TYPE, responseContentType); @@ -65,7 +65,7 @@ void writeEtag( @VariableSource("ifNoneMatchCases") void ifNoneMatch(String ifNoneMatch, int expectedStatus, byte[] expectedEntity) throws IOException { - var request = request("GET"); + var request = HttpForTest.containerRequest("GET"); request.header(EtagRequestFilter.HEADER_IF_NONE_MATCH, ifNoneMatch); var response = response(200, request); var headers = response.getHeaders(); @@ -92,9 +92,4 @@ private static ContainerResponse response(int status, ContainerRequest request) private static byte[] bytes(String input) { return input.getBytes(StandardCharsets.UTF_8); } - - @Nonnull - private static ContainerRequest request(String method) { - return new ContainerRequest(null, null, method, null, new MapPropertiesDelegate(), null); - } } diff --git a/src/test/java/org/opentripplanner/test/support/HttpForTest.java b/src/test/java/org/opentripplanner/test/support/HttpForTest.java index b130a2f3fde..7bbe272572d 100644 --- a/src/test/java/org/opentripplanner/test/support/HttpForTest.java +++ b/src/test/java/org/opentripplanner/test/support/HttpForTest.java @@ -7,12 +7,16 @@ public class HttpForTest { - public static ContainerRequest containerRequest() { + public static ContainerRequest containerRequest(String method) { try { URI uri = new URI("https://localhost:8080"); - return new ContainerRequest(uri, uri, "GET", null, new MapPropertiesDelegate(), null); + return new ContainerRequest(uri, uri, method, null, new MapPropertiesDelegate(), null); } catch (URISyntaxException e) { throw new RuntimeException(e); } } + + public static ContainerRequest containerRequest() { + return containerRequest("GET"); + } } From fc1225926a42f2716a6e61d17cbd39788a19c647 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 01:43:24 +0000 Subject: [PATCH 173/356] Update dependency org.entur.gbfs:gbfs-java-model to v3.0.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e5f86fe5b66..c3f7392bb42 100644 --- a/pom.xml +++ b/pom.xml @@ -688,7 +688,7 @@ org.entur.gbfs gbfs-java-model - 3.0.16 + 3.0.20 From 71decf9e3849e0bc11776d2fbd4f45c06fa9969c Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 18 Jan 2024 06:10:41 +0000 Subject: [PATCH 174/356] Upgrade debug client to version 2024/01/2024-01-18T06:10 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index 5f77418dbe6..e9443e240c4 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
      From ac45106c7956d15ca7b5cb0621664ca48f7c8b42 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 18 Jan 2024 08:59:17 +0100 Subject: [PATCH 175/356] Revert REST API spelling of real-time --- .../ext/restapi/mapping/TripTimeMapper.java | 8 ++++---- .../ext/restapi/model/ApiTripTimeShort.java | 8 ++++---- .../ext/restapi/model/ApiVehicleParkingWithEntrance.java | 4 ++-- .../algorithm/mapping/__snapshots__/CarSnapshotTest.snap | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java index f1f37e6d8b4..46607cccb6a 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java @@ -29,13 +29,13 @@ public static ApiTripTimeShort mapToApi(TripTimeOnDate domain) { api.stopCount = domain.getStopCount(); api.scheduledArrival = domain.getScheduledArrival(); api.scheduledDeparture = domain.getScheduledDeparture(); - api.realTimeArrival = domain.getRealtimeArrival(); - api.realTimeDeparture = domain.getRealtimeDeparture(); + api.realimeArrival = domain.getRealtimeArrival(); + api.realtimeDeparture = domain.getRealtimeDeparture(); api.arrivalDelay = domain.getArrivalDelay(); api.departureDelay = domain.getDepartureDelay(); api.timepoint = domain.isTimepoint(); - api.realTime = domain.isRealtime(); - api.realTimeState = ApiRealTimeState.RealTimeState(domain.getRealTimeState()); + api.realtime = domain.isRealtime(); + api.realtimeState = ApiRealTimeState.RealTimeState(domain.getRealTimeState()); api.blockId = domain.getBlockId(); api.headsign = I18NStringMapper.mapToApi(domain.getHeadsign(), null); api.tripId = FeedScopedIdMapper.mapToApi(domain.getTrip().getId()); diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java index 21c6010c5a2..c0337ba18d4 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java @@ -11,13 +11,13 @@ public class ApiTripTimeShort implements Serializable { public int stopCount; public int scheduledArrival = UNDEFINED; public int scheduledDeparture = UNDEFINED; - public int realTimeArrival = UNDEFINED; - public int realTimeDeparture = UNDEFINED; + public int realimeArrival = UNDEFINED; + public int realtimeDeparture = UNDEFINED; public int arrivalDelay = UNDEFINED; public int departureDelay = UNDEFINED; public boolean timepoint = false; - public boolean realTime = false; - public ApiRealTimeState realTimeState = ApiRealTimeState.SCHEDULED; + public boolean realtime = false; + public ApiRealTimeState realtimeState = ApiRealTimeState.SCHEDULED; public long serviceDay; public String tripId; public String blockId; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java index 68a9f37dfe4..79c5decbaeb 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java @@ -81,7 +81,7 @@ public class ApiVehicleParkingWithEntrance { /** * True if real-time information is used for checking availability. */ - public final boolean realTime; + public final boolean realtime; ApiVehicleParkingWithEntrance( String id, @@ -114,7 +114,7 @@ public class ApiVehicleParkingWithEntrance { this.hasWheelchairAccessibleCarPlaces = hasWheelchairAccessibleCarPlaces; this.capacity = capacity; this.availability = availability; - this.realTime = realTime; + this.realtime = realTime; } public static ApiVehicleParkingWithEntranceBuilder builder() { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap index 31d59483807..8f527b15bf7 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap @@ -106,7 +106,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "hasWheelchairAccessibleCarPlaces" : false, "id" : "OSM:OSMWay/-102488", "name" : "P+R", - "realTime" : false, + "realtime" : false, "tags" : [ "osm:amenity=parking" ] @@ -137,7 +137,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "hasWheelchairAccessibleCarPlaces" : false, "id" : "OSM:OSMWay/-102488", "name" : "P+R", - "realTime" : false, + "realtime" : false, "tags" : [ "osm:amenity=parking" ] From 5451b6de87b07ff3cb6a77ce3186d6348086d1ed Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 18 Jan 2024 09:06:21 +0100 Subject: [PATCH 176/356] Remove mention of REST in README [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 582511ce7f2..4486818745b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ OpenTripPlanner (OTP) is an open source multi-modal trip planner, focusing on travel by scheduled public transportation in combination with bicycling, walking, and mobility services including bike share and ride hailing. Its server component runs on any platform with a Java virtual machine ( -including Linux, Mac, and Windows). It exposes REST and GraphQL APIs that can be accessed by various +including Linux, Mac, and Windows). It exposes GraphQL APIs that can be accessed by various clients including open source Javascript components and native mobile applications. It builds its representation of the transportation network from open data in open standard file formats (primarily GTFS and OpenStreetMap). It applies real-time updates and alerts with immediate visibility to From aaff0ecb45aa8efe5efd09f43ed1ec945806b446 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 18 Jan 2024 11:51:39 +0200 Subject: [PATCH 177/356] Make builder field private --- .../routing/api/request/preference/BikePreferences.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 2d887eba596..26da1476b38 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -166,8 +166,7 @@ public static class Builder { private VehicleRentalPreferences rental; private BicycleOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; - - public VehicleWalkingPreferences walking; + private VehicleWalkingPreferences walking; public Builder(BikePreferences original) { this.original = original; From ed51e526f1c026503cd9ea5d2b861304d9b43ed6 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 18 Jan 2024 15:56:10 +0200 Subject: [PATCH 178/356] Move class to correct package --- .../ext/restapi/mapping}/LegacyBicycleOptimizeType.java | 2 +- .../ext/restapi/resources/RequestToPreferencesMapper.java | 2 +- .../opentripplanner/ext/restapi/resources/RoutingResource.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/{main/java/org/opentripplanner/framework/i18n => ext/java/org/opentripplanner/ext/restapi/mapping}/LegacyBicycleOptimizeType.java (93%) diff --git a/src/main/java/org/opentripplanner/framework/i18n/LegacyBicycleOptimizeType.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/i18n/LegacyBicycleOptimizeType.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java index 1cc262ad720..ff50a03534b 100644 --- a/src/main/java/org/opentripplanner/framework/i18n/LegacyBicycleOptimizeType.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.routing.core.BicycleOptimizeType; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index d8ebeb30f63..2236e7fbcaa 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -2,7 +2,7 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; -import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; +import org.opentripplanner.ext.restapi.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 49659cfe940..0cd16217ca7 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -18,9 +18,9 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; +import org.opentripplanner.ext.restapi.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; From b50c1276acd2cfc6ddf48ae54ba3b8cdcf357dba Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 18 Jan 2024 18:08:43 +0100 Subject: [PATCH 179/356] Apply suggestions from code review Co-authored-by: Eivind Morris Bakke --- .../transit/RemoveItinerariesWithShortStreetLeg.java | 2 +- .../filterchain/framework/filter/RemoveFilter.java | 2 +- .../filterchain/framework/spi/ItineraryDecorator.java | 2 +- .../routing/algorithm/filterchain/package.md | 6 +++--- .../filterchain/framework/filter/DecorateFilterTest.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java index 0014d8925a9..713775911b3 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveItinerariesWithShortStreetLeg.java @@ -15,7 +15,7 @@ * several queries are combined in the frontend. *

      * Example: you have two queries for bike+transit and walk+transit each. Both give you very short legs - * to reach a train station. A user would not expect to see a bike+transit shorted than 200m leg when it's + * to reach a train station. A user would not expect to see a bike+transit shorter than 200m leg when it's * presented right next to a walk+transit leg of the same length. *

      * In other words, this offloads the comparison part of the filter chain to a system outside of OTP and diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java index b53edf05a79..e83aa237cab 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/RemoveFilter.java @@ -10,7 +10,7 @@ /** * This class is responsible for flagging itineraries for deletion based on a predicate in the - * supplied ItineraryDeletionFlagger. The itineraries are not actually deleted at this point, just + * supplied RemoveItineraryFlagger. The itineraries are not actually deleted at this point, just * flagged. They are typically deleted later if debug mode is disabled. */ public class RemoveFilter implements ItineraryListFilter { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java index f1df247f296..4df14c7f5ab 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryDecorator.java @@ -7,7 +7,7 @@ */ public interface ItineraryDecorator { /** - * Implement this do decorate each itinerary in the result. + * Implement this to decorate each itinerary in the result. */ void decorate(Itinerary itinerary); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md index ed8ca0d4d7b..3ea8ceb54c8 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/package.md @@ -51,15 +51,15 @@ Here is an overview of the packages and their responsibilities. ``` filterchain ├── api Request parameters passed into the filter chain -├── filters Concreate filter implementations +├── filters Concrete filter implementations │ ├── street For decorating/filtering street itineraries │ ├── system Mainly support for otp features like paging and search-window crop │ └── transit For decorating/filtering itineraries with transit │ └── group Transit group filters ├── framework Generic filter chain implementation │ ├── filter Filter implementation -│ ├── filterchain Domain logic used by the `FilterChain` (agreagate root). -│ ├── groupids Generic groupId implementations. These can be used to as lego to build specific group-by filters. +│ ├── filterchain Domain logic used by the `FilterChain` (aggregate root). +│ ├── groupids Generic groupId implementations. These can be used as lego to build specific group-by filters. │ ├── sort Sorting implementation │ └── spi The interfaces to extend to plug into the filter-chain └── images Images used in the doc diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java index 9ae8e0da7df..7439acd6d12 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/framework/filter/DecorateFilterTest.java @@ -38,7 +38,7 @@ public void decorate(Itinerary itinerary) { @Test void filterEmptyList() { - // Make sure the filter does nothing and do not crash on empty lists + // Make sure the filter does nothing and does not crash on empty lists new DecorateFilter(this).filter(List.of()); } From 5fa7d6100f17daac91563350f544546f72b1dd56 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Sun, 14 Jan 2024 03:22:13 +0100 Subject: [PATCH 180/356] fix: Follow dash notation for filter names in SameFirstOrLastTripFilter --- .../transit/group/RemoveIfFirstOrLastTripIsTheSame.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java index f076586f487..bc72aada043 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveIfFirstOrLastTripIsTheSame.java @@ -8,15 +8,14 @@ /** * This filter ensures that no more than one itinerary begins or ends with the same trip. - * It loops through itineraries from top to bottom. If itinerary matches with any other itinerary - * from above, it is removed from list. - * Uses {@link GroupBySameFirstOrLastTrip}. + * It loops through itineraries from top to bottom. If an itinerary matches another itinerary, then + * it is removed from the list. Uses {@link GroupBySameFirstOrLastTrip}. */ public class RemoveIfFirstOrLastTripIsTheSame implements RemoveItineraryFlagger { @Override public String name() { - return "SameFirstOrLastTripFilter"; + return "same-first-or-last-trip-filter"; } @Override From c52680e0b272477fe8fcbdd8bafb9d1b8fea5fb8 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Thu, 18 Jan 2024 18:45:47 +0100 Subject: [PATCH 181/356] review: Fix JavaDoc refs and language --- .../TransitGeneralizedCostFilterParams.java | 4 +- ...veOtherThanSameLegsMaxGeneralizedCost.java | 5 +- .../framework/spi/ItineraryListFilter.java | 7 +- .../ItineraryListFilterChain.excalidraw | 228 +++++++++--------- .../images/ItineraryListFilterChain.svg | 2 +- 5 files changed, 122 insertions(+), 124 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java index c909ff00db0..a173f6b454b 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/api/TransitGeneralizedCostFilterParams.java @@ -1,11 +1,11 @@ package org.opentripplanner.routing.algorithm.filterchain.api; import org.opentripplanner.framework.lang.DoubleUtils; -import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** - * Input parameters for {@link TransitGeneralizedCostFilter} + * Input parameters for + * {@link org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter} * * @param costLimitFunction Describes the function to calculate the limit for an itinerary based * on the generalized cost diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java index becac712445..0194cfa2bbc 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java @@ -7,7 +7,6 @@ import java.util.stream.Collectors; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.filter.GroupByFilter; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; import org.opentripplanner.transit.model.timetable.Trip; @@ -15,8 +14,8 @@ /** * This filter remove itineraries, which use the same trips for most of their legs, but where some * itineraries have a much higher cost for the other legs. This is similar to {@link - * TransitGeneralizedCostFilter}, but is used together with {@link GroupByFilter} to filter within - * the groups. + * org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter}, + * but is used together with {@link GroupByFilter} to filter within the groups. */ public class RemoveOtherThanSameLegsMaxGeneralizedCost implements RemoveItineraryFlagger { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java index b0a67ab147f..7d795e6c7fb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/spi/ItineraryListFilter.java @@ -2,7 +2,6 @@ import java.util.List; import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimit; /** * Filter, sort or decorate itineraries. A filter can modify the elements in the list, but not the @@ -13,9 +12,9 @@ * in the same filter. Instead, create two filters and insert them after each other in the filter * chain. *

      - * This allows decoration of each filter and makes it easier to reuse logic. Like the {@link - * MaxLimit} is reused in - * several places. + * This allows decoration of each filter and makes it easier to reuse logic. Like the + * {@link org.opentripplanner.routing.algorithm.filterchain.framework.filter.MaxLimit} is reused + * in several places. */ public interface ItineraryListFilter { /** diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw index 76c71874be5..37e3f8de7b2 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.excalidraw @@ -5,8 +5,8 @@ "elements": [ { "type": "arrow", - "version": 2479, - "versionNonce": 2086276447, + "version": 2483, + "versionNonce": 773348709, "isDeleted": false, "id": "uTKhXBXl80XXPjGsftdJa", "fillStyle": "hachure", @@ -28,7 +28,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982418479, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": { @@ -57,8 +57,8 @@ }, { "type": "ellipse", - "version": 964, - "versionNonce": 465602847, + "version": 968, + "versionNonce": 607278955, "isDeleted": false, "id": "oV4YIjz-w-0HS_dvr7ZoB", "fillStyle": "hachure", @@ -83,14 +83,14 @@ "id": "uTKhXBXl80XXPjGsftdJa" } ], - "updated": 1704982418479, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "ellipse", - "version": 139, - "versionNonce": 297704337, + "version": 143, + "versionNonce": 810641605, "isDeleted": false, "id": "iXHhu1-MD9tXNfoZZ8Rcq", "fillStyle": "hachure", @@ -115,14 +115,14 @@ "id": "i6hMn3CPVbRxyPcniV7yb" } ], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "arrow", - "version": 363, - "versionNonce": 1672962559, + "version": 367, + "versionNonce": 1181364747, "isDeleted": false, "id": "i6hMn3CPVbRxyPcniV7yb", "fillStyle": "hachure", @@ -144,7 +144,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": { @@ -173,8 +173,8 @@ }, { "type": "text", - "version": 108, - "versionNonce": 2108178065, + "version": 114, + "versionNonce": 1376913445, "isDeleted": false, "id": "nJRU39yv_4LYhT-kVxv_t", "fillStyle": "hachure", @@ -194,7 +194,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982458252, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -209,8 +209,8 @@ }, { "type": "text", - "version": 260, - "versionNonce": 1872284191, + "version": 267, + "versionNonce": 369997995, "isDeleted": false, "id": "D8AYLA3h4ksepFAEqkC7G", "fillStyle": "hachure", @@ -219,18 +219,18 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 592.552734375, + "x": 592.4027938842773, "y": 214.466796875, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 125, + "width": 125.29988098144531, "height": 50, "seed": 1478178009, "groupIds": [], "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -245,8 +245,8 @@ }, { "type": "arrow", - "version": 590, - "versionNonce": 180857681, + "version": 594, + "versionNonce": 1699199877, "isDeleted": false, "id": "abNnvFw7GnSsRXaqnRUYs", "fillStyle": "hachure", @@ -268,7 +268,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": { @@ -297,8 +297,8 @@ }, { "type": "rectangle", - "version": 180, - "versionNonce": 660090431, + "version": 184, + "versionNonce": 1086810955, "isDeleted": false, "id": "bA4uoIjQQ5b7VTjNXnYCH", "fillStyle": "hachure", @@ -323,14 +323,14 @@ "id": "abNnvFw7GnSsRXaqnRUYs" } ], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "text", - "version": 139, - "versionNonce": 1010309425, + "version": 146, + "versionNonce": 573571813, "isDeleted": false, "id": "A4ZjgRaXH3lARCAtxxyGH", "fillStyle": "hachure", @@ -343,14 +343,14 @@ "y": 200.08984375, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 10, + "width": 10.319992065429688, "height": 25, "seed": 770881047, "groupIds": [], "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -365,8 +365,8 @@ }, { "type": "line", - "version": 131, - "versionNonce": 1440091743, + "version": 135, + "versionNonce": 1525795307, "isDeleted": false, "id": "xPF7fs9PPAG3FCbgCedlx", "fillStyle": "hachure", @@ -388,7 +388,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": null, @@ -409,8 +409,8 @@ }, { "type": "freedraw", - "version": 166, - "versionNonce": 622840593, + "version": 170, + "versionNonce": 1566072389, "isDeleted": false, "id": "v7Du5WLNb590wL5Uam6Ta", "fillStyle": "hachure", @@ -432,7 +432,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "points": [ @@ -680,8 +680,8 @@ }, { "type": "rectangle", - "version": 214, - "versionNonce": 367192703, + "version": 218, + "versionNonce": 160912523, "isDeleted": false, "id": "bXMUStvEb709SPfYF07CW", "fillStyle": "hachure", @@ -710,14 +710,14 @@ "id": "hhODwDUSnKDNHxeWgdBRh" } ], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "arrow", - "version": 639, - "versionNonce": 1576419569, + "version": 643, + "versionNonce": 2107526565, "isDeleted": false, "id": "hhODwDUSnKDNHxeWgdBRh", "fillStyle": "hachure", @@ -739,7 +739,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": { @@ -776,8 +776,8 @@ }, { "type": "text", - "version": 120, - "versionNonce": 1413431967, + "version": 127, + "versionNonce": 1819446059, "isDeleted": false, "id": "svSoLS4U9UhcZVccLd8Kz", "fillStyle": "hachure", @@ -786,11 +786,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 954.3359375, + "x": 954.5559997558594, "y": 483.53125, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 133, + "width": 132.55987548828125, "height": 75, "seed": 736680902, "groupIds": [], @@ -802,7 +802,7 @@ "id": "hhODwDUSnKDNHxeWgdBRh" } ], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -817,8 +817,8 @@ }, { "type": "ellipse", - "version": 234, - "versionNonce": 71498449, + "version": 238, + "versionNonce": 841961733, "isDeleted": false, "id": "1H3J1TVatGqsTmeb03PzM", "fillStyle": "hachure", @@ -838,14 +838,14 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "text", - "version": 542, - "versionNonce": 295409343, + "version": 549, + "versionNonce": 1206775243, "isDeleted": false, "id": "eMUtrGSf4_tdjT-SgVl6r", "fillStyle": "hachure", @@ -858,14 +858,14 @@ "y": 216.8515625, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 128, + "width": 127.57986450195312, "height": 25, "seed": 276931526, "groupIds": [], "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -880,8 +880,8 @@ }, { "type": "text", - "version": 200, - "versionNonce": 412973233, + "version": 207, + "versionNonce": 1753802853, "isDeleted": false, "id": "I00FPxjJzkybs748xvxYQ", "fillStyle": "hachure", @@ -894,14 +894,14 @@ "y": 210.4375, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 10, + "width": 10.319992065429688, "height": 25, "seed": 654279366, "groupIds": [], "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135037, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -916,8 +916,8 @@ }, { "type": "text", - "version": 116, - "versionNonce": 1687709407, + "version": 125, + "versionNonce": 247892555, "isDeleted": false, "id": "MNcWXxi6VbZaulu3K670q", "fillStyle": "hachure", @@ -926,34 +926,34 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 901.361328125, + "x": 902.5613327026367, "y": 215.78125, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 89, + "width": 86.77992248535156, "height": 75, "seed": 1687297177, "groupIds": [], "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135038, + "updated": 1705598138238, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, - "text": "Itinarary\nList\nFilter", + "text": "Itinerary\nList\nFilter", "textAlign": "center", "verticalAlign": "middle", "containerId": null, - "originalText": "Itinarary\nList\nFilter", + "originalText": "Itinerary\nList\nFilter", "lineHeight": 1.25, "baseline": 68 }, { "type": "rectangle", - "version": 496, - "versionNonce": 481114769, + "version": 500, + "versionNonce": 41456581, "isDeleted": false, "id": "gL_hDnXZ2lRjaViYaG2rV", "fillStyle": "hachure", @@ -978,14 +978,14 @@ "id": "hhODwDUSnKDNHxeWgdBRh" } ], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "line", - "version": 120, - "versionNonce": 1002844927, + "version": 124, + "versionNonce": 1843345163, "isDeleted": false, "id": "gF_BvGrwKBQV_s0LLt7II", "fillStyle": "hachure", @@ -1007,7 +1007,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": null, @@ -1028,8 +1028,8 @@ }, { "type": "line", - "version": 90, - "versionNonce": 1898561649, + "version": 94, + "versionNonce": 1276891941, "isDeleted": false, "id": "6V31n7Wzh9bRD4MWf72QE", "fillStyle": "hachure", @@ -1051,7 +1051,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": null, @@ -1072,8 +1072,8 @@ }, { "type": "line", - "version": 152, - "versionNonce": 1604680479, + "version": 156, + "versionNonce": 1922702763, "isDeleted": false, "id": "jItuiRV-cqbnZuN1BUg5k", "fillStyle": "hachure", @@ -1095,7 +1095,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": null, @@ -1116,8 +1116,8 @@ }, { "type": "line", - "version": 123, - "versionNonce": 1943702097, + "version": 127, + "versionNonce": 836773509, "isDeleted": false, "id": "YXFr7rhGIICmJAWKZ5eUK", "fillStyle": "hachure", @@ -1139,7 +1139,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false, "startBinding": null, @@ -1160,8 +1160,8 @@ }, { "type": "rectangle", - "version": 356, - "versionNonce": 883343167, + "version": 360, + "versionNonce": 2021601355, "isDeleted": false, "id": "M76RD0PeJrkYP9LuS_Kxu", "fillStyle": "hachure", @@ -1186,14 +1186,14 @@ "id": "uTKhXBXl80XXPjGsftdJa" } ], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "rectangle", - "version": 133, - "versionNonce": 1570183217, + "version": 137, + "versionNonce": 914558437, "isDeleted": false, "id": "NLnBzR8OLk5gbeRQGwI9f", "fillStyle": "hachure", @@ -1218,14 +1218,14 @@ "id": "i6hMn3CPVbRxyPcniV7yb" } ], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false }, { "type": "text", - "version": 80, - "versionNonce": 448341841, + "version": 86, + "versionNonce": 828960491, "isDeleted": false, "id": "QxjDVUdnC9uReskEwKjsd", "fillStyle": "hachure", @@ -1250,7 +1250,7 @@ "type": "arrow" } ], - "updated": 1704982138417, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -1265,8 +1265,8 @@ }, { "type": "text", - "version": 80, - "versionNonce": 1615260177, + "version": 86, + "versionNonce": 689047877, "isDeleted": false, "id": "zcbS0wgQbYVDRmrAUTDaV", "fillStyle": "hachure", @@ -1286,7 +1286,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960293, "link": null, "locked": false, "fontSize": 20, @@ -1301,8 +1301,8 @@ }, { "type": "rectangle", - "version": 226, - "versionNonce": 832812785, + "version": 230, + "versionNonce": 803330443, "isDeleted": false, "id": "sVoxOi_goA0Vz9JvN_EuG", "fillStyle": "hachure", @@ -1327,14 +1327,14 @@ "type": "arrow" } ], - "updated": 1704982142587, + "updated": 1705593960294, "link": null, "locked": false }, { "type": "text", - "version": 72, - "versionNonce": 81887217, + "version": 79, + "versionNonce": 451582117, "isDeleted": false, "id": "5bXiMRSAbkBVDNzuMHYjg", "fillStyle": "hachure", @@ -1347,14 +1347,14 @@ "y": 500.25, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 119, + "width": 118.83987426757812, "height": 25, "seed": 926646726, "groupIds": [], "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960294, "link": null, "locked": false, "fontSize": 20, @@ -1369,8 +1369,8 @@ }, { "type": "line", - "version": 155, - "versionNonce": 1407939487, + "version": 159, + "versionNonce": 1361342507, "isDeleted": false, "id": "Ugnzj7K6hXFkke4frMlUY", "fillStyle": "hachure", @@ -1392,7 +1392,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982135038, + "updated": 1705593960294, "link": null, "locked": false, "startBinding": null, @@ -1413,8 +1413,8 @@ }, { "type": "text", - "version": 681, - "versionNonce": 1609777361, + "version": 687, + "versionNonce": 364526597, "isDeleted": false, "id": "5pmOYWhziuLQ_DZANfOzI", "fillStyle": "hachure", @@ -1434,7 +1434,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982452010, + "updated": 1705593960294, "link": null, "locked": false, "fontSize": 19.409722222222214, @@ -1449,8 +1449,8 @@ }, { "type": "ellipse", - "version": 377, - "versionNonce": 1136001105, + "version": 381, + "versionNonce": 1729835723, "isDeleted": false, "id": "-Wb1113k5o16q_0IwIAB8", "fillStyle": "hachure", @@ -1475,14 +1475,14 @@ "id": "3FvznihDEqVpPp0WjjZ26" } ], - "updated": 1704982236097, + "updated": 1705593960294, "link": null, "locked": false }, { "type": "arrow", - "version": 907, - "versionNonce": 1010622481, + "version": 911, + "versionNonce": 293499749, "isDeleted": false, "id": "3FvznihDEqVpPp0WjjZ26", "fillStyle": "hachure", @@ -1504,7 +1504,7 @@ "type": 2 }, "boundElements": [], - "updated": 1704982236097, + "updated": 1705593960294, "link": null, "locked": false, "startBinding": { @@ -1533,8 +1533,8 @@ }, { "type": "text", - "version": 396, - "versionNonce": 8009937, + "version": 402, + "versionNonce": 576758123, "isDeleted": false, "id": "mO-wquP1JTkteitq9b6D4", "fillStyle": "hachure", @@ -1554,7 +1554,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1704982474848, + "updated": 1705593960294, "link": null, "locked": false, "fontSize": 20, diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg index 087866ea971..6cf23afb7a3 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/images/ItineraryListFilterChain.svg @@ -18,4 +18,4 @@ - Comparator<Itinerary>ItineraryListFilterChain*GroupByFilter<GroupId>nestedFilters*ItinararyListFilterDecorateFilterRemoveFilterSortingFilterRemoveItineraryFlagger---name()shouldBeFlaggedForRemoval()skipAlreadyFlaggedItineraries()ItineraryDecorator---decorate(Itinerary) \ No newline at end of file + Comparator<Itinerary>ItineraryListFilterChain*GroupByFilter<GroupId>nestedFilters*ItineraryListFilterDecorateFilterRemoveFilterSortingFilterRemoveItineraryFlagger---name()shouldBeFlaggedForRemoval()skipAlreadyFlaggedItineraries()ItineraryDecorator---decorate(Itinerary) \ No newline at end of file From 88955a789e8e21e73e760722a833849b9fe63a98 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 18 Jan 2024 19:19:40 +0100 Subject: [PATCH 182/356] Fix computation of accessibility score [ci skip] --- .../ext/accessibilityscore/AccessibilityScoreFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java b/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java index 46862b020d5..d31d30e29fa 100644 --- a/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java +++ b/src/ext/java/org/opentripplanner/ext/accessibilityscore/AccessibilityScoreFilter.java @@ -37,7 +37,7 @@ public static Float compute(List legs) { public static float compute(ScheduledTransitLeg leg) { var fromStop = leg.getFrom().stop.getWheelchairAccessibility(); - var toStop = leg.getFrom().stop.getWheelchairAccessibility(); + var toStop = leg.getTo().stop.getWheelchairAccessibility(); var trip = leg.getTripWheelchairAccessibility(); var values = List.of(trip, fromStop, toStop); From dcd0a5e4ae927a7b8e8c2a1513e3660d96ad8393 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 18 Jan 2024 20:52:15 +0000 Subject: [PATCH 183/356] Add changelog entry for #5582 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 4af1393c748..97561c64ec2 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -76,6 +76,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Add stop layer to new Debug UI [#5602](https://github.com/opentripplanner/OpenTripPlanner/pull/5602) - Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652) - Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581) +- Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 1832b6740b3c507144d3f928650647db5f5710bd Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Thu, 18 Jan 2024 20:52:38 +0000 Subject: [PATCH 184/356] Bump serialization version id for #5582 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c3f7392bb42..34b5a9c7d79 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 136 + 137 30.1 2.50 From 86cffd6d492c61f42dba31f3ec9b91a1be0ee412 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 18 Jan 2024 20:53:22 +0000 Subject: [PATCH 185/356] Add changelog entry for #5629 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 97561c64ec2..6f27f60d947 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -77,6 +77,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652) - Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581) - Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582) +- Revert REST API spelling change of real-time [#5629](https://github.com/opentripplanner/OpenTripPlanner/pull/5629) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 323df422b8b29f639887857dbee8600122951ddc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 00:05:13 +0000 Subject: [PATCH 186/356] Update dependency com.hubspot.maven.plugins:prettier-maven-plugin to v0.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34b5a9c7d79..34f4365b580 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ When running `mvn jacoco:prepare-agent test` argLine is replaced with the one activating the agent. --> - 0.21 + 0.22 write From b7f02fc9a6f9c9c4fc6e491f98b2a4da831b124d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jan 2024 10:20:27 +0100 Subject: [PATCH 187/356] Update docs --- docs/sandbox/MapboxVectorTilesApi.md | 9 +++++---- .../standalone/config/routerconfig/VectorTileConfig.java | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index cfb9a634129..92cd867ecce 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -169,11 +169,12 @@ The path of the vector tile source URLs in `tilejson.json`. This is useful if you have a proxy setup and rewrite the path that is passed to OTP. If you don't configure this optional value then the path returned in `tilejson.json` is -`/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you set a value of -`/otp_test/tiles` then the returned path changes to `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. +`/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you, for example, set +a value of `/otp_test/tiles` then the returned path changes to +`/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. -The protocol and host are read from the incoming HTTP request. If you run OTP behind a proxy -then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP +The protocol and host are always read from the incoming HTTP request. If you run OTP behind +a proxy then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP return the protocol and host for the original request and not the proxied one. diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 67fd2496e3c..0abc046282d 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -58,11 +58,12 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String This is useful if you have a proxy setup and rewrite the path that is passed to OTP. If you don't configure this optional value then the path returned in `tilejson.json` is - `/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you set a value of - `/otp_test/tiles` then the returned path changes to `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. + `/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you, for example, set + a value of `/otp_test/tiles` then the returned path changes to + `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. - The protocol and host are read from the incoming HTTP request. If you run OTP behind a proxy - then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP + The protocol and host are always read from the incoming HTTP request. If you run OTP behind + a proxy then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP return the protocol and host for the original request and not the proxied one. """ ) From a65ff0d69c671480157eca8c0a547a84acf4fb00 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:30:07 +0200 Subject: [PATCH 188/356] Introduce vehicle walking preferences --- .../ext/restapi/resources/RequestToPreferencesMapper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index bfac498ff8c..30f834ae0bd 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -70,7 +70,6 @@ private void mapBike() { setIfNotNull( req.bikeOptimizeType, optimizeType -> bike.withOptimizeType(LegacyBicycleOptimizeType.map(optimizeType)) - ); if (req.bikeOptimizeType == LegacyBicycleOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { From 5efaaf786eb855c7cea970e41b0bbffe45e9ba2f Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 4 Jan 2024 11:49:35 +0200 Subject: [PATCH 189/356] Add scooter preferences class --- .../preference/ScooterPreferences.java | 221 ++++++++++++++++++ .../preference/ScooterPreferencesTest.java | 99 ++++++++ 2 files changed, 320 insertions(+) create mode 100644 src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java create mode 100644 src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java new file mode 100644 index 00000000000..a6a878424a6 --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java @@ -0,0 +1,221 @@ +package org.opentripplanner.routing.api.request.preference; + +import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; +import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; +import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; +import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; + +import java.io.Serializable; +import java.util.Objects; +import java.util.function.Consumer; +import org.opentripplanner.framework.model.Units; +import org.opentripplanner.framework.tostring.ToStringBuilder; +import org.opentripplanner.routing.core.BicycleOptimizeType; + +/** + * The scooter preferences contain all speed, reluctance, cost and factor preferences for scooter + * related to street and transit routing. The values are normalized(rounded) so the class can used + * as a cache key. + * + * Scooter rental is only supported currently. + *

      + * THIS CLASS IS IMMUTABLE AND THREAD-SAFE. + */ +public final class ScooterPreferences implements Serializable { + + public static final ScooterPreferences DEFAULT = new ScooterPreferences(); + + private final double speed; + private final double reluctance; + private final VehicleRentalPreferences rental; + private final BicycleOptimizeType optimizeType; + private final TimeSlopeSafetyTriangle optimizeTriangle; + private final VehicleWalkingPreferences walking; + + private ScooterPreferences() { + this.speed = 5; + this.reluctance = 2.0; + this.rental = VehicleRentalPreferences.DEFAULT; + this.optimizeType = SAFE_STREETS; + this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; + this.walking = VehicleWalkingPreferences.DEFAULT; + } + + private ScooterPreferences(Builder builder) { + this.speed = Units.speed(builder.speed); + this.reluctance = Units.reluctance(builder.reluctance); + this.rental = builder.rental; + this.optimizeType = Objects.requireNonNull(builder.optimizeType); + this.optimizeTriangle = Objects.requireNonNull(builder.optimizeTriangle); + this.walking = builder.walking; + } + + public static ScooterPreferences.Builder of() { + return new Builder(DEFAULT); + } + + public ScooterPreferences.Builder copyOf() { + return new Builder(this); + } + + /** + * Default: 5 m/s, ~11 mph, a random scooter speed + */ + public double speed() { + return speed; + } + + public double reluctance() { + return reluctance; + } + + /** Rental preferences that can be different per request */ + public VehicleRentalPreferences rental() { + return rental; + } + + /** + * The set of characteristics that the user wants to optimize for -- defaults to SAFE_STREETS. + */ + public BicycleOptimizeType optimizeType() { + return optimizeType; + } + + public TimeSlopeSafetyTriangle optimizeTriangle() { + return optimizeTriangle; + } + + /** Scooter walking preferences that can be different per request */ + public VehicleWalkingPreferences walking() { + return walking; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ScooterPreferences that = (ScooterPreferences) o; + return ( + doubleEquals(that.speed, speed) && + doubleEquals(that.reluctance, reluctance) && + Objects.equals(rental, that.rental) && + optimizeType == that.optimizeType && + optimizeTriangle.equals(that.optimizeTriangle) && + Objects.equals(walking, that.walking) + ); + } + + @Override + public int hashCode() { + return Objects.hash(speed, reluctance, rental, optimizeType, optimizeTriangle, walking); + } + + @Override + public String toString() { + return ToStringBuilder + .of(ScooterPreferences.class) + .addNum("speed", speed, DEFAULT.speed) + .addNum("reluctance", reluctance, DEFAULT.reluctance) + .addObj("rental", rental, DEFAULT.rental) + .addEnum("optimizeType", optimizeType, DEFAULT.optimizeType) + .addObj("optimizeTriangle", optimizeTriangle, DEFAULT.optimizeTriangle) + .addObj("walking", walking, DEFAULT.walking) + .toString(); + } + + @SuppressWarnings("UnusedReturnValue") + public static class Builder { + + private final ScooterPreferences original; + private double speed; + private double reluctance; + private VehicleRentalPreferences rental; + private BicycleOptimizeType optimizeType; + private TimeSlopeSafetyTriangle optimizeTriangle; + + public VehicleWalkingPreferences walking; + + public Builder(ScooterPreferences original) { + this.original = original; + this.speed = original.speed; + this.reluctance = original.reluctance; + this.rental = original.rental; + this.optimizeType = original.optimizeType; + this.optimizeTriangle = original.optimizeTriangle; + this.walking = original.walking; + } + + public ScooterPreferences original() { + return original; + } + + public double speed() { + return speed; + } + + public Builder withSpeed(double speed) { + this.speed = speed; + return this; + } + + public double reluctance() { + return reluctance; + } + + public Builder withReluctance(double reluctance) { + this.reluctance = reluctance; + return this; + } + + public Builder withRental(Consumer body) { + this.rental = ifNotNull(this.rental, original.rental).copyOf().apply(body).build(); + return this; + } + + public BicycleOptimizeType optimizeType() { + return optimizeType; + } + + public Builder withOptimizeType(BicycleOptimizeType optimizeType) { + this.optimizeType = optimizeType; + return this; + } + + public TimeSlopeSafetyTriangle optimizeTriangle() { + return optimizeTriangle; + } + + /** This also sets the optimization type as TRIANGLE if triangle parameters are defined */ + public Builder withForcedOptimizeTriangle(Consumer body) { + var builder = TimeSlopeSafetyTriangle.of(); + body.accept(builder); + this.optimizeTriangle = builder.buildOrDefault(this.optimizeTriangle); + if (!builder.isEmpty()) { + this.optimizeType = TRIANGLE; + } + return this; + } + + public Builder withOptimizeTriangle(Consumer body) { + var builder = TimeSlopeSafetyTriangle.of(); + body.accept(builder); + this.optimizeTriangle = builder.buildOrDefault(this.optimizeTriangle); + return this; + } + + public Builder withWalking(Consumer body) { + this.walking = ifNotNull(this.walking, original.walking).copyOf().apply(body).build(); + return this; + } + + public Builder apply(Consumer body) { + body.accept(this); + return this; + } + + public ScooterPreferences build() { + var value = new ScooterPreferences(this); + return original.equals(value) ? original : value; + } + } +} diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java new file mode 100644 index 00000000000..11ec7f3be79 --- /dev/null +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java @@ -0,0 +1,99 @@ +package org.opentripplanner.routing.api.request.preference; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; + +import org.junit.jupiter.api.Test; +import org.opentripplanner.routing.core.BicycleOptimizeType; + +class ScooterPreferencesTest { + + public static final double SPEED = 2.0; + public static final double RELUCTANCE = 1.2; + public static final TimeSlopeSafetyTriangle TRIANGLE = TimeSlopeSafetyTriangle + .of() + .withSlope(1) + .build(); + public static final BicycleOptimizeType OPTIMIZE_TYPE = BicycleOptimizeType.TRIANGLE; + + private final ScooterPreferences subject = ScooterPreferences + .of() + .withSpeed(SPEED) + .withReluctance(RELUCTANCE) + .withOptimizeType(OPTIMIZE_TYPE) + .withOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + + @Test + void speed() { + assertEquals(SPEED, subject.speed()); + } + + @Test + void reluctance() { + assertEquals(RELUCTANCE, subject.reluctance()); + } + + @Test + void optimizeType() { + assertEquals(OPTIMIZE_TYPE, subject.optimizeType()); + } + + @Test + void optimizeTriangle() { + assertEquals(TRIANGLE, subject.optimizeTriangle()); + } + + @Test + void testOfAndCopyOf() { + // Return same object if no value is set + assertSame(ScooterPreferences.DEFAULT, ScooterPreferences.of().build()); + assertSame(subject, subject.copyOf().build()); + } + + @Test + void testCopyOfEqualsAndHashCode() { + // Create a copy, make a change and set it back again to force creating a new object + var other = subject.copyOf().withSpeed(0.7).build(); + var same = other.copyOf().withSpeed(SPEED).build(); + assertEqualsAndHashCode(subject, other, same); + } + + @Test + void testToString() { + assertEquals("ScooterPreferences{}", ScooterPreferences.DEFAULT.toString()); + assertEquals( + "ScooterPreferences{" + + "speed: 2.0, " + + "reluctance: 1.2, " + + "optimizeType: TRIANGLE, " + + "optimizeTriangle: TimeSlopeSafetyTriangle[time=0.0, slope=1.0, safety=0.0]" + + "}", + subject.toString() + ); + } + + @Test + void testForcedTriangleOptimization() { + var trianglePreferences = ScooterPreferences + .of() + .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + assertEquals(BicycleOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); + + var conflictingPreferences = ScooterPreferences + .of() + .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + assertEquals(BicycleOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); + + var emptyTrianglePreferences = ScooterPreferences + .of() + .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withForcedOptimizeTriangle(it -> it.build()) + .build(); + assertEquals(BicycleOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); + } +} From 04b87514467e07829c561562598f93379313dc2d Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 4 Jan 2024 12:02:25 +0200 Subject: [PATCH 190/356] Rename optimization type and update comments --- .../mapping/LegacyBicycleOptimizeType.java | 24 ------------------ .../resources/RequestToPreferencesMapper.java | 7 +++--- .../restapi/resources/RoutingResource.java | 10 +++----- .../LegacyVehicleRoutingOptimizeType.java | 25 +++++++++++++++++++ .../gtfs/mapping/OptimizationTypeMapper.java | 14 +++++------ .../apis/gtfs/mapping/RouteRequestMapper.java | 4 +-- .../preferences/BikePreferencesMapper.java | 4 +-- .../apis/transmodel/model/EnumTypes.java | 12 ++++----- .../apis/transmodel/model/plan/TripQuery.java | 7 ++++-- .../request/preference/BikePreferences.java | 16 ++++++------ .../preference/ScooterPreferences.java | 16 ++++++------ .../preference/TimeSlopeSafetyTriangle.java | 17 +++++++------ ...e.java => VehicleRoutingOptimizeType.java} | 12 ++++----- .../visualizer/GraphVisualizer.java | 14 +++++------ .../gtfs/mapping/RouteRequestMapperTest.java | 4 +-- .../mapping/TripRequestMapperTest.java | 12 ++++----- .../BikePreferencesMapperTest.java | 6 ++--- .../mapping/ElevationSnapshotTest.java | 4 +-- .../preference/BikePreferencesTest.java | 15 +++++------ .../preference/ScooterPreferencesTest.java | 15 +++++------ .../integration/BicycleRoutingTest.java | 4 +-- .../street/model/edge/StreetEdgeTest.java | 4 +-- 22 files changed, 126 insertions(+), 120 deletions(-) delete mode 100644 src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java create mode 100644 src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java rename src/main/java/org/opentripplanner/routing/core/{BicycleOptimizeType.java => VehicleRoutingOptimizeType.java} (52%) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java deleted file mode 100644 index ff50a03534b..00000000000 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.opentripplanner.ext.restapi.mapping; - -import org.opentripplanner.routing.core.BicycleOptimizeType; - -/** - * Bicycle optimization types that are only meant to be used by the REST API. Related to {@link org.opentripplanner.routing.core.BicycleOptimizeType} - */ -public enum LegacyBicycleOptimizeType { - QUICK, - SAFE, - FLAT, - GREENWAYS, - TRIANGLE; - - public static BicycleOptimizeType map(LegacyBicycleOptimizeType type) { - return switch (type) { - case QUICK -> BicycleOptimizeType.SHORTEST_DURATION; - case FLAT -> BicycleOptimizeType.FLAT_STREETS; - case SAFE -> BicycleOptimizeType.SAFE_STREETS; - case GREENWAYS -> BicycleOptimizeType.SAFEST_STREETS; - case TRIANGLE -> BicycleOptimizeType.TRIANGLE; - }; - } -} diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index 30f834ae0bd..2208ec13a14 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -2,7 +2,7 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; -import org.opentripplanner.ext.restapi.mapping.LegacyBicycleOptimizeType; +import org.opentripplanner.api.mapping.LegacyVehicleRoutingOptimizeType; import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; @@ -69,9 +69,10 @@ private void mapBike() { setIfNotNull(req.bikeBoardCost, bike::withBoardCost); setIfNotNull( req.bikeOptimizeType, - optimizeType -> bike.withOptimizeType(LegacyBicycleOptimizeType.map(optimizeType)) + optimizeType -> bike.withOptimizeType(LegacyVehicleRoutingOptimizeType.map(optimizeType)) + ); - if (req.bikeOptimizeType == LegacyBicycleOptimizeType.TRIANGLE) { + if (req.bikeOptimizeType == LegacyVehicleRoutingOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { setIfNotNull(req.triangleTimeFactor, triangle::withTime); setIfNotNull(req.triangleSlopeFactor, triangle::withSlope); diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 1c234e3ff9e..53464940a9e 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -18,9 +18,9 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; +import org.opentripplanner.api.mapping.LegacyVehicleRoutingOptimizeType; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; -import org.opentripplanner.ext.restapi.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; @@ -239,17 +239,15 @@ public abstract class RoutingResource { protected Double triangleTimeFactor; /** - * The set of characteristics that the user wants to optimize for. @See OptimizeType. + * The set of characteristics that the user wants to optimize for in bicycle and scooter routing. + * @See OptimizeType. * * @deprecated TODO OTP2 this should be completely removed and done only with individual cost * parameters - * Also: apparently OptimizeType only affects BICYCLE mode traversal of - * street segments. If this is the case it should be very well - * documented and carried over into the Enum name. */ @Deprecated @QueryParam("optimize") - protected LegacyBicycleOptimizeType bikeOptimizeType; + protected LegacyVehicleRoutingOptimizeType bikeOptimizeType; /** * The set of modes that a user is willing to use, with qualifiers stating whether vehicles should diff --git a/src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java b/src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java new file mode 100644 index 00000000000..0cb2ae38bcc --- /dev/null +++ b/src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java @@ -0,0 +1,25 @@ +package org.opentripplanner.api.mapping; + +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; + +/** + * Bicycle and scooter optimization types that are only meant to be used by the REST API. Related to + * {@link VehicleRoutingOptimizeType} + */ +public enum LegacyVehicleRoutingOptimizeType { + QUICK, + SAFE, + FLAT, + GREENWAYS, + TRIANGLE; + + public static VehicleRoutingOptimizeType map(LegacyVehicleRoutingOptimizeType type) { + return switch (type) { + case QUICK -> VehicleRoutingOptimizeType.SHORTEST_DURATION; + case FLAT -> VehicleRoutingOptimizeType.FLAT_STREETS; + case SAFE -> VehicleRoutingOptimizeType.SAFE_STREETS; + case GREENWAYS -> VehicleRoutingOptimizeType.SAFEST_STREETS; + case TRIANGLE -> VehicleRoutingOptimizeType.TRIANGLE; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java index 1f53652f7b7..7f4f5200256 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java @@ -2,18 +2,18 @@ import javax.annotation.Nonnull; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; public final class OptimizationTypeMapper { @Nonnull - public static BicycleOptimizeType map(GraphQLTypes.GraphQLOptimizeType optimizeType) { + public static VehicleRoutingOptimizeType map(GraphQLTypes.GraphQLOptimizeType optimizeType) { return switch (optimizeType) { - case QUICK -> BicycleOptimizeType.SHORTEST_DURATION; - case FLAT -> BicycleOptimizeType.FLAT_STREETS; - case SAFE -> BicycleOptimizeType.SAFE_STREETS; - case GREENWAYS -> BicycleOptimizeType.SAFEST_STREETS; - case TRIANGLE -> BicycleOptimizeType.TRIANGLE; + case QUICK -> VehicleRoutingOptimizeType.SHORTEST_DURATION; + case FLAT -> VehicleRoutingOptimizeType.FLAT_STREETS; + case SAFE -> VehicleRoutingOptimizeType.SAFE_STREETS; + case GREENWAYS -> VehicleRoutingOptimizeType.SAFEST_STREETS; + case TRIANGLE -> VehicleRoutingOptimizeType.TRIANGLE; }; } } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index 212bfbcf380..5cdae33850f 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -28,7 +28,7 @@ import org.opentripplanner.routing.api.request.preference.VehicleWalkingPreferences; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.transit.model.basic.MainAndSubMode; import org.opentripplanner.transit.model.basic.TransitMode; @@ -79,7 +79,7 @@ public static RouteRequest toRouteRequest( ) ); } - if (bike.optimizeType() == BicycleOptimizeType.TRIANGLE) { + if (bike.optimizeType() == VehicleRoutingOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { callWith.argument("triangle.timeFactor", triangle::withTime); callWith.argument("triangle.slopeFactor", triangle::withSlope); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java index 1179c034e93..76826d31e2d 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java @@ -4,7 +4,7 @@ import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; import org.opentripplanner.routing.api.request.preference.BikePreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; public class BikePreferencesMapper { @@ -37,7 +37,7 @@ public static void mapBikePreferences( // bike.withWalkingReluctance(WALK_BIKE_RELATIVE_RELUCTANCE * (double)r ); //}); - if (bike.optimizeType() == BicycleOptimizeType.TRIANGLE) { + if (bike.optimizeType() == VehicleRoutingOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { callWith.argument("triangleFactors.time", triangle::withTime); callWith.argument("triangleFactors.slope", triangle::withSlope); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java index e2897d868c9..b85d4ce19b9 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java @@ -17,7 +17,7 @@ import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.response.InputField; import org.opentripplanner.routing.api.response.RoutingErrorCode; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.basic.Accessibility; @@ -64,11 +64,11 @@ public class EnumTypes { public static final GraphQLEnumType BICYCLE_OPTIMISATION_METHOD = GraphQLEnumType .newEnum() .name("BicycleOptimisationMethod") - .value("quick", BicycleOptimizeType.SHORTEST_DURATION) - .value("safe", BicycleOptimizeType.SAFE_STREETS) - .value("flat", BicycleOptimizeType.FLAT_STREETS) - .value("greenways", BicycleOptimizeType.SAFEST_STREETS) - .value("triangle", BicycleOptimizeType.TRIANGLE) + .value("quick", VehicleRoutingOptimizeType.SHORTEST_DURATION) + .value("safe", VehicleRoutingOptimizeType.SAFE_STREETS) + .value("flat", VehicleRoutingOptimizeType.FLAT_STREETS) + .value("greenways", VehicleRoutingOptimizeType.SAFEST_STREETS) + .value("triangle", VehicleRoutingOptimizeType.TRIANGLE) .build(); public static final GraphQLEnumType BIKES_ALLOWED = GraphQLEnumType diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java index abeeb187342..bf34d9928e4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripQuery.java @@ -20,7 +20,7 @@ import org.opentripplanner.apis.transmodel.model.framework.PenaltyForStreetModeType; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; public class TripQuery { @@ -371,7 +371,10 @@ public static GraphQLFieldDefinition create( "When setting the " + EnumTypes.BICYCLE_OPTIMISATION_METHOD.getName() + " to '" + - enumValAsString(EnumTypes.BICYCLE_OPTIMISATION_METHOD, BicycleOptimizeType.TRIANGLE) + + enumValAsString( + EnumTypes.BICYCLE_OPTIMISATION_METHOD, + VehicleRoutingOptimizeType.TRIANGLE + ) + "', use these values to tell the routing engine how important each of the factors is compared to the others. All values should add up to 1." ) .type(TriangleFactorsInputType.INPUT_TYPE) diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 26da1476b38..5767b74eaa8 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -2,8 +2,8 @@ import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; -import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; -import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; +import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.SAFE_STREETS; +import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.TRIANGLE; import java.io.Serializable; import java.util.Objects; @@ -11,7 +11,7 @@ import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; /** * The bike preferences contain all speed, reluctance, cost and factor preferences for biking @@ -29,7 +29,7 @@ public final class BikePreferences implements Serializable { private final Cost boardCost; private final VehicleParkingPreferences parking; private final VehicleRentalPreferences rental; - private final BicycleOptimizeType optimizeType; + private final VehicleRoutingOptimizeType optimizeType; private final TimeSlopeSafetyTriangle optimizeTriangle; private final VehicleWalkingPreferences walking; @@ -96,7 +96,7 @@ public VehicleRentalPreferences rental() { /** * The set of characteristics that the user wants to optimize for -- defaults to SAFE_STREETS. */ - public BicycleOptimizeType optimizeType() { + public VehicleRoutingOptimizeType optimizeType() { return optimizeType; } @@ -164,7 +164,7 @@ public static class Builder { private Cost boardCost; private VehicleParkingPreferences parking; private VehicleRentalPreferences rental; - private BicycleOptimizeType optimizeType; + private VehicleRoutingOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; private VehicleWalkingPreferences walking; @@ -221,11 +221,11 @@ public Builder withRental(Consumer body) { return this; } - public BicycleOptimizeType optimizeType() { + public VehicleRoutingOptimizeType optimizeType() { return optimizeType; } - public Builder withOptimizeType(BicycleOptimizeType optimizeType) { + public Builder withOptimizeType(VehicleRoutingOptimizeType optimizeType) { this.optimizeType = optimizeType; return this; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java index a6a878424a6..10b9c01e686 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java @@ -2,15 +2,15 @@ import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; -import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; -import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; +import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.SAFE_STREETS; +import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.TRIANGLE; import java.io.Serializable; import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.model.Units; import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; /** * The scooter preferences contain all speed, reluctance, cost and factor preferences for scooter @@ -28,7 +28,7 @@ public final class ScooterPreferences implements Serializable { private final double speed; private final double reluctance; private final VehicleRentalPreferences rental; - private final BicycleOptimizeType optimizeType; + private final VehicleRoutingOptimizeType optimizeType; private final TimeSlopeSafetyTriangle optimizeTriangle; private final VehicleWalkingPreferences walking; @@ -77,7 +77,7 @@ public VehicleRentalPreferences rental() { /** * The set of characteristics that the user wants to optimize for -- defaults to SAFE_STREETS. */ - public BicycleOptimizeType optimizeType() { + public VehicleRoutingOptimizeType optimizeType() { return optimizeType; } @@ -130,7 +130,7 @@ public static class Builder { private double speed; private double reluctance; private VehicleRentalPreferences rental; - private BicycleOptimizeType optimizeType; + private VehicleRoutingOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; public VehicleWalkingPreferences walking; @@ -172,11 +172,11 @@ public Builder withRental(Consumer body) { return this; } - public BicycleOptimizeType optimizeType() { + public VehicleRoutingOptimizeType optimizeType() { return optimizeType; } - public Builder withOptimizeType(BicycleOptimizeType optimizeType) { + public Builder withOptimizeType(VehicleRoutingOptimizeType optimizeType) { this.optimizeType = optimizeType; return this; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java b/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java index 99925a441fd..ae4f1039f32 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java @@ -4,13 +4,14 @@ import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; /** - * Sets the (bicycle) triangle routing parameters -- the relative importance of safety, flatness, - * and speed. These three fields should have values between 0 and 1, and should add up to 1. + * Sets the (bicycle or scooter) triangle routing parameters -- the relative importance of safety, + * flatness, and speed. These three fields should have values between 0 and 1, and should add up to + * 1. *

      * The constructor accepts any three numbers and will normalize them to add up to 1. {@code time} * and {@code slope} are rounded to the closest two decimal number, then - * {@code safety := 1.0 - (time + slope)}. This is done to make the rounding predictable and - * to allways add up to one. This allows this class to be used in an index of a cache. For example: + * {@code safety := 1.0 - (time + slope)}. This is done to make the rounding predictable and to + * allways add up to one. This allows this class to be used in an index of a cache. For example: *

        *   ( 1.0, 1.0, 1.0 ) => ( time: 0.33, slope: 0.33, safety: 0.34 )
        * 
      @@ -25,10 +26,10 @@ public record TimeSlopeSafetyTriangle(double time, double slope, double safety) public static final TimeSlopeSafetyTriangle DEFAULT = new TimeSlopeSafetyTriangle(1, 1, 1); /** - * Sets the bicycle triangle routing parameters -- the relative importance of safety, flatness, - * and speed. These three fields of the RouteRequest should have values between 0 and 1, and - * should add up to 1. This setter function accepts any three numbers and will normalize them to - * add up to 1. + * Sets the bicycle or scooter triangle routing parameters -- the relative importance of safety, + * flatness, and speed. These three fields of the RouteRequest should have values between 0 and 1, + * and should add up to 1. This setter function accepts any three numbers and will normalize them + * to add up to 1. */ public TimeSlopeSafetyTriangle(double time, double slope, double safety) { safety = positiveValueOrZero(safety); diff --git a/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java b/src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java similarity index 52% rename from src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java rename to src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java index 1d639e0af8b..cb8436b83b3 100644 --- a/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java +++ b/src/main/java/org/opentripplanner/routing/core/VehicleRoutingOptimizeType.java @@ -5,10 +5,10 @@ import java.util.Set; /** - * When planning a bicycle route what should be optimized for. Optimize types are basically - * combined presets of routing parameters, except for triangle. + * When planning a bicycle or scooter route what should be optimized for. Optimize types are + * basically combined presets of routing parameters, except for triangle. */ -public enum BicycleOptimizeType { +public enum VehicleRoutingOptimizeType { /** This was previously called QUICK */ SHORTEST_DURATION, /** This was previously called SAFE */ @@ -19,14 +19,14 @@ public enum BicycleOptimizeType { SAFEST_STREETS, TRIANGLE; - private static final Set NON_TRIANGLE_VALUES = Collections.unmodifiableSet( + private static final Set NON_TRIANGLE_VALUES = Collections.unmodifiableSet( EnumSet.complementOf(EnumSet.of(TRIANGLE)) ); /** - * Return all values that are not {@link BicycleOptimizeType#TRIANGLE}. + * Return all values that are not {@link VehicleRoutingOptimizeType#TRIANGLE}. */ - public static Set nonTriangleValues() { + public static Set nonTriangleValues() { return NON_TRIANGLE_VALUES; } } diff --git a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java index f15aff9048b..338423df961 100644 --- a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java +++ b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java @@ -64,7 +64,7 @@ import org.opentripplanner.astar.spi.TraverseVisitor; import org.opentripplanner.graph_builder.issue.api.DataImportIssue; import org.opentripplanner.routing.api.request.RouteRequest; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.impl.GraphPathFinder; import org.opentripplanner.street.model.edge.Edge; @@ -547,20 +547,20 @@ protected void route(String from, String to) { } } - BicycleOptimizeType getSelectedOptimizeType() { + VehicleRoutingOptimizeType getSelectedOptimizeType() { if (opQuick.isSelected()) { - return BicycleOptimizeType.SHORTEST_DURATION; + return VehicleRoutingOptimizeType.SHORTEST_DURATION; } if (opSafe.isSelected()) { - return BicycleOptimizeType.SAFE_STREETS; + return VehicleRoutingOptimizeType.SAFE_STREETS; } if (opFlat.isSelected()) { - return BicycleOptimizeType.FLAT_STREETS; + return VehicleRoutingOptimizeType.FLAT_STREETS; } if (opGreenways.isSelected()) { - return BicycleOptimizeType.SAFEST_STREETS; + return VehicleRoutingOptimizeType.SAFEST_STREETS; } - return BicycleOptimizeType.SHORTEST_DURATION; + return VehicleRoutingOptimizeType.SHORTEST_DURATION; } private Container makeDiffTab() { diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java index b05dd77e2a9..92b91a141bd 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java @@ -5,8 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.params.provider.Arguments.of; -import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; -import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; +import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.SAFE_STREETS; +import static org.opentripplanner.routing.core.VehicleRoutingOptimizeType.TRIANGLE; import graphql.ExecutionInput; import graphql.execution.ExecutionId; diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java index 9a01a36cbcb..1e0d5a36f53 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java @@ -40,7 +40,7 @@ import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.preference.StreetPreferences; import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; import org.opentripplanner.service.vehiclerental.internal.DefaultVehicleRentalService; @@ -255,14 +255,14 @@ public void testMaxDirectDurationForFlexWithTooLongDuration() { public void testBikeTriangleFactors() { Map arguments = Map.of( "bicycleOptimisationMethod", - BicycleOptimizeType.TRIANGLE, + VehicleRoutingOptimizeType.TRIANGLE, "triangleFactors", Map.of("safety", 0.1, "slope", 0.1, "time", 0.8) ); var req1 = TripRequestMapper.createRequest(executionContext(arguments)); - assertEquals(BicycleOptimizeType.TRIANGLE, req1.preferences().bike().optimizeType()); + assertEquals(VehicleRoutingOptimizeType.TRIANGLE, req1.preferences().bike().optimizeType()); assertEquals( new TimeSlopeSafetyTriangle(0.8, 0.1, 0.1), req1.preferences().bike().optimizeTriangle() @@ -272,18 +272,18 @@ public void testBikeTriangleFactors() { @Test void testDefaultTriangleFactors() { var req2 = TripRequestMapper.createRequest(executionContext(Map.of())); - assertEquals(BicycleOptimizeType.SAFE_STREETS, req2.preferences().bike().optimizeType()); + assertEquals(VehicleRoutingOptimizeType.SAFE_STREETS, req2.preferences().bike().optimizeType()); assertEquals(TimeSlopeSafetyTriangle.DEFAULT, req2.preferences().bike().optimizeTriangle()); } - static Stream noTriangleCases = BicycleOptimizeType + static Stream noTriangleCases = VehicleRoutingOptimizeType .nonTriangleValues() .stream() .map(Arguments::of); @ParameterizedTest @VariableSource("noTriangleCases") - public void testBikeTriangleFactorsHasNoEffect(BicycleOptimizeType bot) { + public void testBikeTriangleFactorsHasNoEffect(VehicleRoutingOptimizeType bot) { Map arguments = Map.of( "bicycleOptimisationMethod", bot, diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java index a72fd25cbfa..786ddc5c198 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.apis.transmodel._support.TestDataFetcherDecorator; import org.opentripplanner.routing.api.request.preference.BikePreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; class BikePreferencesMapperTest { @@ -23,7 +23,7 @@ static List mapBikePreferencesTestCases() { Arguments.of("bikeSpeed", 10.0, "BikePreferences{speed: 10.0}"), Arguments.of( "bicycleOptimisationMethod", - BicycleOptimizeType.TRIANGLE, + VehicleRoutingOptimizeType.TRIANGLE, "BikePreferences{optimizeType: TRIANGLE}" ), // No effect unless BicycleOptimize is TRIANGLE @@ -64,7 +64,7 @@ static List mapBikePreferencesOptimizeTriangleTestCases() { @ParameterizedTest @MethodSource("mapBikePreferencesOptimizeTriangleTestCases") void testMapBikePreferencesOptimizeTriangle(String field, Object value, String expected) { - var preferences = BikePreferences.of().withOptimizeType(BicycleOptimizeType.TRIANGLE); + var preferences = BikePreferences.of().withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE); mapBikePreferences(preferences, TestDataFetcherDecorator.of(field, value)); assertEquals( "BikePreferences{optimizeType: TRIANGLE, optimizeTriangle: " + expected + "}", diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java index 9027b0a0dd5..677edfcbabf 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/ElevationSnapshotTest.java @@ -19,7 +19,7 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.error.RoutingValidationException; @ExtendWith(SnapshotExtension.class) @@ -98,7 +98,7 @@ public void directBike() { request.withPreferences(pref -> pref.withBike(bike -> bike - .withOptimizeType(BicycleOptimizeType.TRIANGLE) + .withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE) .withOptimizeTriangle(b -> b.withTime(0.3).withSlope(0.4).withSafety(0.3)) ) ); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 8a6ac3f4f45..3bbaf0105e5 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -5,7 +5,7 @@ import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; import org.junit.jupiter.api.Test; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; class BikePreferencesTest { @@ -16,7 +16,8 @@ class BikePreferencesTest { .of() .withSlope(1) .build(); - public static final BicycleOptimizeType OPTIMIZE_TYPE = BicycleOptimizeType.TRIANGLE; + public static final VehicleRoutingOptimizeType OPTIMIZE_TYPE = + VehicleRoutingOptimizeType.TRIANGLE; public static final int RENTAL_PICKUP_TIME = 30; public static final int PARK_COST = 30; @@ -106,20 +107,20 @@ void testForcedTriangleOptimization() { .of() .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) .build(); - assertEquals(BicycleOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); + assertEquals(VehicleRoutingOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); var conflictingPreferences = BikePreferences .of() - .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withOptimizeType(VehicleRoutingOptimizeType.SAFE_STREETS) .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) .build(); - assertEquals(BicycleOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); + assertEquals(VehicleRoutingOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); var emptyTrianglePreferences = BikePreferences .of() - .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withOptimizeType(VehicleRoutingOptimizeType.SAFE_STREETS) .withForcedOptimizeTriangle(it -> it.build()) .build(); - assertEquals(BicycleOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); + assertEquals(VehicleRoutingOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); } } diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java index 11ec7f3be79..4b6554cbe07 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java @@ -5,7 +5,7 @@ import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; import org.junit.jupiter.api.Test; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; class ScooterPreferencesTest { @@ -15,7 +15,8 @@ class ScooterPreferencesTest { .of() .withSlope(1) .build(); - public static final BicycleOptimizeType OPTIMIZE_TYPE = BicycleOptimizeType.TRIANGLE; + public static final VehicleRoutingOptimizeType OPTIMIZE_TYPE = + VehicleRoutingOptimizeType.TRIANGLE; private final ScooterPreferences subject = ScooterPreferences .of() @@ -80,20 +81,20 @@ void testForcedTriangleOptimization() { .of() .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) .build(); - assertEquals(BicycleOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); + assertEquals(VehicleRoutingOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); var conflictingPreferences = ScooterPreferences .of() - .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withOptimizeType(VehicleRoutingOptimizeType.SAFE_STREETS) .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) .build(); - assertEquals(BicycleOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); + assertEquals(VehicleRoutingOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); var emptyTrianglePreferences = ScooterPreferences .of() - .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withOptimizeType(VehicleRoutingOptimizeType.SAFE_STREETS) .withForcedOptimizeTriangle(it -> it.build()) .build(); - assertEquals(BicycleOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); + assertEquals(VehicleRoutingOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); } } diff --git a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java b/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java index d5b7733f3e8..db937ff2a6e 100644 --- a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.routing.algorithm.mapping.GraphPathToItineraryMapper; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.impl.GraphPathFinder; import org.opentripplanner.street.search.TemporaryVerticesContainer; @@ -76,7 +76,7 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic request.setFrom(from); request.setTo(to); request.withPreferences(p -> - p.withBike(it -> it.withOptimizeType(BicycleOptimizeType.SHORTEST_DURATION)) + p.withBike(it -> it.withOptimizeType(VehicleRoutingOptimizeType.SHORTEST_DURATION)) ); request.journey().direct().setMode(StreetMode.BIKE); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index 42d841b9fa3..60e8cf58952 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -18,7 +18,7 @@ import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; import org.opentripplanner.routing.api.request.StreetMode; -import org.opentripplanner.routing.core.BicycleOptimizeType; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.util.ElevationUtils; import org.opentripplanner.routing.util.SlopeCosts; import org.opentripplanner.street.model.StreetTraversalPermission; @@ -357,7 +357,7 @@ public void testBikeOptimizeTriangle() { .withBike(bike -> bike .withSpeed(SPEED) - .withOptimizeType(BicycleOptimizeType.TRIANGLE) + .withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE) .withOptimizeTriangle(it -> it.withTime(1)) .withReluctance(1) ) From a7c92a96caee8d18437af7a2f4ede260c731b464 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 18 Jan 2024 11:46:16 +0200 Subject: [PATCH 191/356] Use scooter preferences --- .../routing/api/request/StreetMode.java | 32 ++++++++------ .../preference/RoutingPreferences.java | 43 ++++++++++++++++--- .../street/StreetVehicleRentalLink.java | 5 ++- .../street/model/edge/StreetEdge.java | 29 +++++++------ .../edge/StreetEdgeReluctanceCalculator.java | 1 + .../model/edge/StreetTransitEntityLink.java | 14 +++--- .../street/model/edge/TemporaryFreeEdge.java | 14 +++--- .../street/search/state/StateData.java | 8 +++- .../EuclideanRemainingWeightHeuristic.java | 3 ++ 9 files changed, 102 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java b/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java index 0f5d65305b3..bb5dc4b7f04 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java +++ b/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java @@ -7,63 +7,63 @@ public enum StreetMode implements DocumentedEnum { * No street mode is set. This option is used if we do not want street routing at all in this part * of the search. */ - NOT_SET(true, true, true, false, false, false, false, false, false), + NOT_SET(true, true, true, false, false, false, false, false, false, false), /** * Walk only */ - WALK(true, true, true, true, false, false, false, false, false), + WALK(true, true, true, true, false, false, false, false, false, false), /** * Bike only */ - BIKE(true, true, true, false, true, false, false, false, false), + BIKE(true, true, true, false, true, false, false, false, false, false), /** * Bike to a bike parking area, then walk the rest of the way. *

      * Direct mode and access mode only. */ - BIKE_TO_PARK(true, false, false, true, true, false, false, true, false), + BIKE_TO_PARK(true, false, false, true, true, false, false, false, true, false), /** * Walk to a bike rental point, bike to a bike rental drop-off point, and walk the rest of the * way. This can include bike rental at fixed locations or free-floating services. */ - BIKE_RENTAL(true, true, true, true, true, false, true, false, false), + BIKE_RENTAL(true, true, true, true, true, false, false, true, false, false), /** * Walk to a scooter rental point, ride a scooter to a scooter rental drop-off point, and walk the * rest of the way. This can include scooter rental at fixed locations or free-floating services. */ - SCOOTER_RENTAL(true, true, true, true, true, false, true, false, false), + SCOOTER_RENTAL(true, true, true, true, false, false, true, true, false, false), /** * Car only *

      * Direct mode only. */ - CAR(true, false, false, false, false, true, false, false, false), + CAR(true, false, false, false, false, true, false, false, false, false), /** * Start in the car, drive to a parking area, and walk the rest of the way. *

      * Direct mode and access mode only. */ - CAR_TO_PARK(true, false, false, true, false, true, false, true, false), + CAR_TO_PARK(true, false, false, true, false, true, false, false, true, false), /** * Walk to a pickup point along the road, drive to a drop-off point along the road, and walk the * rest of the way. This can include various taxi-services or kiss & ride. */ - CAR_PICKUP(true, false, true, true, false, true, false, false, true), + CAR_PICKUP(true, false, true, true, false, true, false, false, false, true), /** * Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. * This can include car rental at fixed locations or free-floating services. */ - CAR_RENTAL(true, true, true, true, false, true, true, false, false), + CAR_RENTAL(true, true, true, true, false, true, false, true, false, false), /** * Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination. */ - CAR_HAILING(true, false, true, false, false, true, false, false, true), + CAR_HAILING(true, false, true, false, false, true, false, false, false, true), /** * Encompasses all types of on-demand and flexible transportation. */ - FLEXIBLE(true, false, true, true, false, false, false, false, false); + FLEXIBLE(true, false, true, true, false, false, false, false, false, false); final boolean access; @@ -77,6 +77,8 @@ public enum StreetMode implements DocumentedEnum { final boolean includesDriving; + final boolean includesScooter; + final boolean includesRenting; final boolean includesParking; @@ -90,6 +92,7 @@ public enum StreetMode implements DocumentedEnum { boolean includesWalking, boolean includesBiking, boolean includesDriving, + boolean includesScooter, boolean includesRenting, boolean includesParking, boolean includesPickup @@ -100,6 +103,7 @@ public enum StreetMode implements DocumentedEnum { this.includesWalking = includesWalking; this.includesBiking = includesBiking; this.includesDriving = includesDriving; + this.includesScooter = includesScooter; this.includesRenting = includesRenting; this.includesParking = includesParking; this.includesPickup = includesPickup; @@ -117,6 +121,10 @@ public boolean includesDriving() { return includesDriving; } + public boolean includesScooter() { + return includesScooter; + } + public boolean includesRenting() { return includesRenting; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java index d3d22160935..3fec7a9e46e 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java @@ -7,6 +7,7 @@ import java.util.Objects; import java.util.function.Consumer; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.street.search.TraverseMode; @@ -23,6 +24,7 @@ public final class RoutingPreferences implements Serializable { private final WheelchairPreferences wheelchair; private final BikePreferences bike; private final CarPreferences car; + private final ScooterPreferences scooter; private final SystemPreferences system; private final ItineraryFilterPreferences itineraryFilter; @@ -34,6 +36,7 @@ public RoutingPreferences() { this.wheelchair = WheelchairPreferences.DEFAULT; this.bike = BikePreferences.DEFAULT; this.car = CarPreferences.DEFAULT; + this.scooter = ScooterPreferences.DEFAULT; this.system = SystemPreferences.DEFAULT; this.itineraryFilter = ItineraryFilterPreferences.DEFAULT; } @@ -46,6 +49,7 @@ private RoutingPreferences(Builder builder) { this.street = requireNonNull(builder.street()); this.bike = requireNonNull(builder.bike()); this.car = requireNonNull(builder.car()); + this.scooter = requireNonNull(builder.scooter()); this.system = requireNonNull(builder.system()); this.itineraryFilter = requireNonNull(builder.itineraryFilter()); } @@ -90,6 +94,10 @@ public CarPreferences car() { return car; } + public ScooterPreferences scooter() { + return scooter; + } + /** * Get parking preferences for the traverse mode. Note, only car and bike are supported. */ @@ -99,20 +107,28 @@ public VehicleParkingPreferences parking(TraverseMode mode) { /** * Get rental preferences for the traverse mode. Note, only car, scooter and bike are supported. - * - * TODO make scooter preferences independent of bike */ + @Nonnull public VehicleRentalPreferences rental(TraverseMode mode) { - return mode == TraverseMode.CAR ? car.rental() : bike.rental(); + return switch (mode) { + case BICYCLE -> bike.rental(); + case CAR -> car.rental(); + case SCOOTER -> scooter.rental(); + default -> throw new IllegalArgumentException("rental(): Invalid mode " + mode); + }; } /** * Get rental preferences for the traverse mode. Note, only car, scooter and bike are supported. - * - * TODO make scooter preferences independent of bike */ + @Nullable public VehicleRentalPreferences rental(StreetMode mode) { - return mode == StreetMode.CAR_RENTAL ? car.rental() : bike.rental(); + return switch (mode) { + case BIKE_RENTAL -> bike.rental(); + case CAR_RENTAL -> car.rental(); + case SCOOTER_RENTAL -> scooter.rental(); + default -> null; + }; } @Nonnull @@ -126,12 +142,15 @@ public SystemPreferences system() { /** * The road speed for a specific traverse mode. + * + * NOTE, this is only used for tests and doesn't support scooter walking */ public double getSpeed(TraverseMode mode, boolean walkingBike) { return switch (mode) { case WALK -> walkingBike ? bike.walking().speed() : walk.speed(); case BICYCLE -> bike.speed(); case CAR -> car.speed(); + case SCOOTER -> scooter.speed(); default -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + mode); }; } @@ -149,6 +168,7 @@ public boolean equals(Object o) { Objects.equals(wheelchair, that.wheelchair) && Objects.equals(bike, that.bike) && Objects.equals(car, that.car) && + Objects.equals(scooter, that.scooter) && Objects.equals(system, that.system) && Objects.equals(itineraryFilter, that.itineraryFilter) ); @@ -164,6 +184,7 @@ public int hashCode() { wheelchair, bike, car, + scooter, system, itineraryFilter ); @@ -179,6 +200,7 @@ public static class Builder { private WheelchairPreferences wheelchair = null; private BikePreferences bike = null; private CarPreferences car = null; + private ScooterPreferences scooter = null; private SystemPreferences system = null; private ItineraryFilterPreferences itineraryFilter = null; @@ -259,6 +281,15 @@ public Builder withCar(Consumer body) { return this; } + public ScooterPreferences scooter() { + return scooter == null ? original.scooter : scooter; + } + + public Builder withScooter(Consumer body) { + this.scooter = ifNotNull(this.scooter, original.scooter).copyOf().apply(body).build(); + return this; + } + public SystemPreferences system() { return system == null ? original.system : system; } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java b/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java index 4a18aae03c2..385b347d24a 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java +++ b/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java @@ -53,7 +53,10 @@ public State[] traverse(State s0) { } var preferences = s0.getPreferences().rental(s0.getRequest().mode()); - if (vehicleRentalPlaceVertex.getStation().networkIsNotAllowed(preferences)) { + // preferences will be null while finding nearest places with WALK mode + if ( + preferences != null && vehicleRentalPlaceVertex.getStation().networkIsNotAllowed(preferences) + ) { return State.empty(); } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index 1e3594ee04b..ca33396b0a3 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -234,8 +234,9 @@ public double calculateSpeed( case WALK -> walkingBike ? preferences.bike().walking().speed() : preferences.walk().speed(); - case BICYCLE, SCOOTER -> preferences.bike().speed(); + case BICYCLE -> preferences.bike().speed(); case CAR -> getCarSpeed(); + case SCOOTER -> preferences.scooter().speed(); case FLEX -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + traverseMode); }; @@ -1098,7 +1099,7 @@ private StateEditor doTraverse(State s0, TraverseMode traverseMode, boolean walk var traversalCosts = switch (traverseMode) { - case BICYCLE, SCOOTER -> bicycleTraversalCost(preferences, speed); + case BICYCLE, SCOOTER -> bicycleOrScooterTraversalCost(preferences, traverseMode, speed); case WALK -> walkingTraversalCosts( preferences, traverseMode, @@ -1213,10 +1214,17 @@ private TraversalCosts otherTraversalCosts( } @Nonnull - private TraversalCosts bicycleTraversalCost(RoutingPreferences pref, double speed) { + private TraversalCosts bicycleOrScooterTraversalCost( + RoutingPreferences pref, + TraverseMode mode, + double speed + ) { double time = getEffectiveBikeDistance() / speed; double weight; - switch (pref.bike().optimizeType()) { + var optimizeType = mode == TraverseMode.BICYCLE + ? pref.bike().optimizeType() + : pref.scooter().optimizeType(); + switch (optimizeType) { case SAFEST_STREETS -> { weight = bicycleSafetyFactor * getDistanceMeters() / speed; if (bicycleSafetyFactor <= SAFEST_STREETS_SAFETY_FACTOR) { @@ -1232,20 +1240,17 @@ private TraversalCosts bicycleTraversalCost(RoutingPreferences pref, double spee double quick = getEffectiveBikeDistance(); double safety = getEffectiveBicycleSafetyDistance(); double slope = getEffectiveBikeDistanceForWorkCost(); - weight = - quick * - pref.bike().optimizeTriangle().time() + - slope * - pref.bike().optimizeTriangle().slope() + - safety * - pref.bike().optimizeTriangle().safety(); + var triangle = mode == TraverseMode.BICYCLE + ? pref.bike().optimizeTriangle() + : pref.scooter().optimizeTriangle(); + weight = quick * triangle.time() + slope * triangle.slope() + safety * triangle.safety(); weight /= speed; } default -> weight = getDistanceMeters() / speed; } var reluctance = StreetEdgeReluctanceCalculator.computeReluctance( pref, - TraverseMode.BICYCLE, + mode, false, isStairs() ); diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java index ee2f3d833ee..a6fdf4ce6f1 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java @@ -25,6 +25,7 @@ static double computeReluctance( case WALK -> walkingBike ? pref.bike().walking().reluctance() : pref.walk().reluctance(); case BICYCLE -> pref.bike().reluctance(); case CAR -> pref.car().reluctance(); + case SCOOTER -> pref.scooter().reluctance(); default -> throw new IllegalArgumentException( "getReluctance(): Invalid mode " + traverseMode ); diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index df5b24a5928..dabd70bf28d 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -137,13 +137,13 @@ else if ( @Nonnull private State[] buildState(State s0, StateEditor s1, RoutingPreferences pref) { - var rentalPreferences = s0.getRequest().preferences().rental(s0.getRequest().mode()); - if ( - s0.isRentingVehicleFromStation() && - s0.mayKeepRentedVehicleAtDestination() && - rentalPreferences.allowArrivingInRentedVehicleAtDestination() - ) { - s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds()); + if (s0.isRentingVehicleFromStation() && s0.mayKeepRentedVehicleAtDestination()) { + var rentalPreferences = s0.getRequest().preferences().rental(s0.getRequest().mode()); + if (rentalPreferences.allowArrivingInRentedVehicleAtDestination()) { + s1.incrementWeight( + rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds() + ); + } } s1.setBackMode(null); diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java index d825a8fcbea..e93c6523d89 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java @@ -42,13 +42,13 @@ public State[] traverse(State s0) { s1.incrementWeight(1); s1.setBackMode(null); - var rentalPreferences = s0.getPreferences().rental(s0.getRequest().mode()); - if ( - s0.isRentingVehicleFromStation() && - s0.mayKeepRentedVehicleAtDestination() && - rentalPreferences.allowArrivingInRentedVehicleAtDestination() - ) { - s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds()); + if (s0.isRentingVehicleFromStation() && s0.mayKeepRentedVehicleAtDestination()) { + var rentalPreferences = s0.getPreferences().rental(s0.getRequest().mode()); + if (rentalPreferences.allowArrivingInRentedVehicleAtDestination()) { + s1.incrementWeight( + rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds() + ); + } } return s1.makeStateArray(); diff --git a/src/main/java/org/opentripplanner/street/search/state/StateData.java b/src/main/java/org/opentripplanner/street/search/state/StateData.java index cc2bfa5a57a..d1db14d91f4 100644 --- a/src/main/java/org/opentripplanner/street/search/state/StateData.java +++ b/src/main/java/org/opentripplanner/street/search/state/StateData.java @@ -87,7 +87,9 @@ public static List getInitialStateDatas( return getInitialStateDatas( request.mode(), request.arriveBy(), - rentalPreferences.allowArrivingInRentedVehicleAtDestination(), + rentalPreferences != null + ? rentalPreferences.allowArrivingInRentedVehicleAtDestination() + : false, stateDataConstructor ); } @@ -102,7 +104,9 @@ public static StateData getBaseCaseStateData(StreetSearchRequest request) { var stateDatas = getInitialStateDatas( request.mode(), request.arriveBy(), - rentalPreferences.allowArrivingInRentedVehicleAtDestination(), + rentalPreferences != null + ? rentalPreferences.allowArrivingInRentedVehicleAtDestination() + : false, StateData::new ); diff --git a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java b/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java index e43278901d4..7bccdbb94df 100644 --- a/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java +++ b/src/main/java/org/opentripplanner/street/search/strategy/EuclideanRemainingWeightHeuristic.java @@ -55,6 +55,9 @@ private double getStreetSpeedUpperBound(RoutingPreferences preferences, StreetMo if (streetMode.includesBiking()) { return preferences.bike().speed(); } + if (streetMode.includesScooter()) { + return preferences.scooter().speed(); + } return preferences.walk().speed(); } From 07f9c170422760418d6fc7472994e38cd21c390c Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 18 Jan 2024 11:46:38 +0200 Subject: [PATCH 192/356] Add scooter preferences to router-config --- docs/RouteRequest.md | 108 ++++++++++++++++++ docs/RouterConfiguration.md | 18 +++ .../routerequest/RouteRequestConfig.java | 38 ++++++ .../standalone/config/router-config.json | 18 +++ 4 files changed, 182 insertions(+) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 199eda8a332..0bdae72fd30 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -125,6 +125,30 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [costLimitFunction](#rd_if_transitGeneralizedCostLimit_costLimitFunction) | `cost-linear-function` | The base function used by the filter. | *Optional* | `"15m + 1.50 t"` | 2.2 | |       [intervalRelaxFactor](#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor) | `double` | How much the filter should be relaxed for itineraries that do not overlap in time. | *Optional* | `0.4` | 2.2 | | [maxDirectStreetDurationForMode](#rd_maxDirectStreetDurationForMode) | `enum map of duration` | Limit direct route duration per street mode. | *Optional* | | 2.2 | +| scooter | `object` | Scooter preferences. | *Optional* | | 2.5 | +|    [optimization](#rd_scooter_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | +|    reluctance | `double` | A multiplier for how bad scooter travel is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max scooter speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_scooter_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_scooter_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | +|    [triangle](#rd_scooter_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | +|       [safety](#rd_scooter_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | +|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | +|    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | +|       [hopCost](#rd_scooter_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [hopTime](#rd_scooter_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | +|       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | +|       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | | [transferOptimization](#rd_transferOptimization) | `object` | Optimize where a transfer between to trip happens. | *Optional* | | 2.1 | |    [backTravelWaitTimeFactor](#rd_to_backTravelWaitTimeFactor) | `double` | To reduce back-travel we favor waiting, this reduces the cost of waiting. | *Optional* | `1.0` | 2.1 | |    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | @@ -827,6 +851,72 @@ Override the settings in `maxDirectStreetDuration` for specific street modes. Th done because some street modes searches are much more resource intensive than others. +

      optimization

      + +**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe-streets"` +**Path:** /routingDefaults/scooter +**Enum values:** `shortest-duration` | `safe-streets` | `flat-streets` | `safest-streets` | `triangle` + +The set of characteristics that the user wants to optimize for. + +If the triangle optimization is used, it's enough to just define the triangle parameters + +

      allowedNetworks

      + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/scooter/rental + +The vehicle rental networks which may be used. If empty all networks may be used. + +

      bannedNetworks

      + +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/scooter/rental + +The vehicle rental networks which may not be used. If empty, no networks are banned. + +

      triangle

      + +**Since version:** `2.5` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/scooter + +Triangle optimization criteria. + +Optimization type doesn't need to be defined if these values are defined. + +

      safety

      + +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.0` +**Path:** /routingDefaults/scooter/triangle + +Relative importance of safety (range 0-1). + +This factor can also include other concerns such as convenience and general cyclist +preferences by taking into account road surface etc. + + +

      hopCost

      + +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` +**Path:** /routingDefaults/scooter/walk + +The cost of hopping on or off a vehicle. + +There are different parameters for the cost of renting or parking a vehicle and this is +not meant for controlling the cost of those events. + + +

      hopTime

      + +**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` +**Path:** /routingDefaults/scooter/walk + +The time it takes the user to hop on or off a vehicle in seconds. + +Time it takes to rent or park a vehicle have their own parameters and this is not meant +for controlling the duration of those events. + +

      transferOptimization

      **Since version:** `2.1` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` @@ -1093,6 +1183,24 @@ include stairs as a last result. "cost" : 600 } }, + "scooter" : { + "speed" : 5, + "reluctance" : 5.0, + "walk" : { + "reluctance" : 10.0, + "stairsReluctance" : 150.0 + }, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : "30s", + "dropOffCost" : 30 + }, + "triangle" : { + "safety" : 0.4, + "flatness" : 0.3, + "time" : 0.3 + } + }, "walk" : { "speed" : 1.3, "reluctance" : 4.0, diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 23e2e3763d4..dfe3c3f9750 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -496,6 +496,24 @@ Used to group requests when monitoring OTP. "cost" : 600 } }, + "scooter" : { + "speed" : 5, + "reluctance" : 5.0, + "walk" : { + "reluctance" : 10.0, + "stairsReluctance" : 150.0 + }, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : "30s", + "dropOffCost" : 30 + }, + "triangle" : { + "safety" : 0.4, + "flatness" : 0.3, + "time" : 0.3 + } + }, "walk" : { "speed" : 1.3, "reluctance" : 4.0, diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 4538f6de84d..ac2a73aead4 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -24,6 +24,7 @@ import org.opentripplanner.routing.api.request.preference.BikePreferences; import org.opentripplanner.routing.api.request.preference.CarPreferences; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; +import org.opentripplanner.routing.api.request.preference.ScooterPreferences; import org.opentripplanner.routing.api.request.preference.StreetPreferences; import org.opentripplanner.routing.api.request.preference.SystemPreferences; import org.opentripplanner.routing.api.request.preference.TransitPreferences; @@ -181,6 +182,7 @@ private static void mapPreferences(NodeAdapter c, RoutingPreferences.Builder pre preferences.withBike(it -> mapBikePreferences(c, it)); preferences.withStreet(it -> mapStreetPreferences(c, it)); preferences.withCar(it -> mapCarPreferences(c, it)); + preferences.withScooter(it -> mapScooterPreferences(c, it)); preferences.withSystem(it -> mapSystemPreferences(c, it)); preferences.withTransfer(it -> mapTransferPreferences(c, it)); preferences.withWalk(it -> mapWalkPreferences(c, it)); @@ -621,6 +623,42 @@ private static void mapCarPreferences(NodeAdapter root, CarPreferences.Builder b .withRental(it -> mapRental(c, it)); } + private static void mapScooterPreferences(NodeAdapter root, ScooterPreferences.Builder builder) { + var dft = builder.original(); + NodeAdapter c = root.of("scooter").since(V2_5).summary("Scooter preferences.").asObject(); + builder + .withSpeed( + c + .of("speed") + .since(V2_0) + .summary("Max scooter speed along streets, in meters per second") + .asDouble(dft.speed()) + ) + .withReluctance( + c + .of("reluctance") + .since(V2_0) + .summary( + "A multiplier for how bad scooter travel is, compared to being in transit for equal lengths of time." + ) + .asDouble(dft.reluctance()) + ) + .withOptimizeType( + c + .of("optimization") + .since(V2_0) + .summary("The set of characteristics that the user wants to optimize for.") + .description( + "If the triangle optimization is used, it's enough to just define the triangle parameters" + ) + .asEnum(dft.optimizeType()) + ) + // triangle overrides the optimization type if defined + .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(c, it)) + .withWalking(it -> mapVehicleWalking(c, it)) + .withRental(it -> mapRental(c, it)); + } + private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builder builder) { var dft = builder.original(); builder diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 863b9bec279..0a6cb6ee831 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -57,6 +57,24 @@ "cost": 600 } }, + "scooter": { + "speed": 5, + "reluctance": 5.0, + "walk": { + "reluctance": 10.0, + "stairsReluctance": 150.0 + }, + "rental": { + "pickupCost": 120, + "dropOffTime": "30s", + "dropOffCost": 30 + }, + "triangle": { + "safety": 0.4, + "flatness": 0.3, + "time": 0.3 + } + }, "walk": { "speed": 1.3, "reluctance": 4.0, From 545315c92c94462e521291f0bf5a660277d4c7d4 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 19 Jan 2024 15:14:33 +0200 Subject: [PATCH 193/356] Remove scooter walking preferences --- docs/RouteRequest.md | 28 ------------------- .../preference/ScooterPreferences.java | 22 ++------------- .../routerequest/RouteRequestConfig.java | 1 - .../standalone/config/router-config.json | 4 --- 4 files changed, 2 insertions(+), 53 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 0bdae72fd30..70fa0d26e49 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -143,12 +143,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | |       [safety](#rd_scooter_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | |       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | -|    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | -|       [hopCost](#rd_scooter_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [hopTime](#rd_scooter_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | -|       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | -|       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | -|       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | | [transferOptimization](#rd_transferOptimization) | `object` | Optimize where a transfer between to trip happens. | *Optional* | | 2.1 | |    [backTravelWaitTimeFactor](#rd_to_backTravelWaitTimeFactor) | `double` | To reduce back-travel we favor waiting, this reduces the cost of waiting. | *Optional* | `1.0` | 2.1 | |    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | @@ -895,28 +889,6 @@ This factor can also include other concerns such as convenience and general cycl preferences by taking into account road surface etc. -

      hopCost

      - -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` -**Path:** /routingDefaults/scooter/walk - -The cost of hopping on or off a vehicle. - -There are different parameters for the cost of renting or parking a vehicle and this is -not meant for controlling the cost of those events. - - -

      hopTime

      - -**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` -**Path:** /routingDefaults/scooter/walk - -The time it takes the user to hop on or off a vehicle in seconds. - -Time it takes to rent or park a vehicle have their own parameters and this is not meant -for controlling the duration of those events. - -

      transferOptimization

      **Since version:** `2.1` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java index 10b9c01e686..7c139c08730 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java @@ -30,7 +30,6 @@ public final class ScooterPreferences implements Serializable { private final VehicleRentalPreferences rental; private final VehicleRoutingOptimizeType optimizeType; private final TimeSlopeSafetyTriangle optimizeTriangle; - private final VehicleWalkingPreferences walking; private ScooterPreferences() { this.speed = 5; @@ -38,7 +37,6 @@ private ScooterPreferences() { this.rental = VehicleRentalPreferences.DEFAULT; this.optimizeType = SAFE_STREETS; this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; - this.walking = VehicleWalkingPreferences.DEFAULT; } private ScooterPreferences(Builder builder) { @@ -47,7 +45,6 @@ private ScooterPreferences(Builder builder) { this.rental = builder.rental; this.optimizeType = Objects.requireNonNull(builder.optimizeType); this.optimizeTriangle = Objects.requireNonNull(builder.optimizeTriangle); - this.walking = builder.walking; } public static ScooterPreferences.Builder of() { @@ -85,11 +82,6 @@ public TimeSlopeSafetyTriangle optimizeTriangle() { return optimizeTriangle; } - /** Scooter walking preferences that can be different per request */ - public VehicleWalkingPreferences walking() { - return walking; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -100,14 +92,13 @@ public boolean equals(Object o) { doubleEquals(that.reluctance, reluctance) && Objects.equals(rental, that.rental) && optimizeType == that.optimizeType && - optimizeTriangle.equals(that.optimizeTriangle) && - Objects.equals(walking, that.walking) + optimizeTriangle.equals(that.optimizeTriangle) ); } @Override public int hashCode() { - return Objects.hash(speed, reluctance, rental, optimizeType, optimizeTriangle, walking); + return Objects.hash(speed, reluctance, rental, optimizeType, optimizeTriangle); } @Override @@ -119,7 +110,6 @@ public String toString() { .addObj("rental", rental, DEFAULT.rental) .addEnum("optimizeType", optimizeType, DEFAULT.optimizeType) .addObj("optimizeTriangle", optimizeTriangle, DEFAULT.optimizeTriangle) - .addObj("walking", walking, DEFAULT.walking) .toString(); } @@ -133,8 +123,6 @@ public static class Builder { private VehicleRoutingOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; - public VehicleWalkingPreferences walking; - public Builder(ScooterPreferences original) { this.original = original; this.speed = original.speed; @@ -142,7 +130,6 @@ public Builder(ScooterPreferences original) { this.rental = original.rental; this.optimizeType = original.optimizeType; this.optimizeTriangle = original.optimizeTriangle; - this.walking = original.walking; } public ScooterPreferences original() { @@ -203,11 +190,6 @@ public Builder withOptimizeTriangle(Consumer bo return this; } - public Builder withWalking(Consumer body) { - this.walking = ifNotNull(this.walking, original.walking).copyOf().apply(body).build(); - return this; - } - public Builder apply(Consumer body) { body.accept(this); return this; diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index ac2a73aead4..c0dcede55a7 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -655,7 +655,6 @@ private static void mapScooterPreferences(NodeAdapter root, ScooterPreferences.B ) // triangle overrides the optimization type if defined .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(c, it)) - .withWalking(it -> mapVehicleWalking(c, it)) .withRental(it -> mapRental(c, it)); } diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 0a6cb6ee831..a3082e0a13a 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -60,10 +60,6 @@ "scooter": { "speed": 5, "reluctance": 5.0, - "walk": { - "reluctance": 10.0, - "stairsReluctance": 150.0 - }, "rental": { "pickupCost": 120, "dropOffTime": "30s", From e28230f7d1e2113ece71e1ad6ee7202a37072885 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 19 Jan 2024 15:17:44 +0200 Subject: [PATCH 194/356] Improve tests --- .../api/request/preference/ScooterPreferencesTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java index 4b6554cbe07..01a12ef5cbb 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/ScooterPreferencesTest.java @@ -17,12 +17,14 @@ class ScooterPreferencesTest { .build(); public static final VehicleRoutingOptimizeType OPTIMIZE_TYPE = VehicleRoutingOptimizeType.TRIANGLE; + public static final int RENTAL_PICKUP_TIME = 30; private final ScooterPreferences subject = ScooterPreferences .of() .withSpeed(SPEED) .withReluctance(RELUCTANCE) .withOptimizeType(OPTIMIZE_TYPE) + .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) .withOptimizeTriangle(it -> it.withSlope(1).build()) .build(); @@ -46,6 +48,12 @@ void optimizeTriangle() { assertEquals(TRIANGLE, subject.optimizeTriangle()); } + @Test + void rental() { + var vehicleRental = VehicleRentalPreferences.of().withPickupTime(RENTAL_PICKUP_TIME).build(); + assertEquals(vehicleRental, subject.rental()); + } + @Test void testOfAndCopyOf() { // Return same object if no value is set @@ -68,6 +76,7 @@ void testToString() { "ScooterPreferences{" + "speed: 2.0, " + "reluctance: 1.2, " + + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "optimizeType: TRIANGLE, " + "optimizeTriangle: TimeSlopeSafetyTriangle[time=0.0, slope=1.0, safety=0.0]" + "}", From e2ba239751b9b4bd557804c9b393e2fd38828011 Mon Sep 17 00:00:00 2001 From: eibakke Date: Fri, 19 Jan 2024 15:07:11 +0100 Subject: [PATCH 195/356] Gets rid of instanceof in QuayType to differentiate between the types of StopLocation. This is done mainly by moving method signatures into the StopLocation interface from the implementing classes. --- .../opentripplanner/ext/flex/FlexIndex.java | 2 +- .../ext/flex/trip/ScheduledDeviatedTrip.java | 6 +- .../ext/flex/trip/UnscheduledTrip.java | 6 +- .../apis/transmodel/model/stop/QuayType.java | 83 ++++++------------- .../module/StreetLinkerModule.java | 2 +- .../netex/mapping/NetexMapper.java | 2 +- .../transit/model/site/AreaStop.java | 14 ++++ .../transit/model/site/GroupStop.java | 21 ++++- .../transit/model/site/GroupStopBuilder.java | 2 +- .../transit/model/site/RegularStop.java | 6 ++ .../transit/model/site/StopLocation.java | 21 +++++ .../gtfs/mapping/StopTimeMapperTest.java | 2 +- .../netex/mapping/FlexStopsMapperTest.java | 2 +- .../transit/model/site/GroupStopTest.java | 2 +- 14 files changed, 99 insertions(+), 72 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java b/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java index 5cab995d419..a875ba0f516 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java +++ b/src/ext/java/org/opentripplanner/ext/flex/FlexIndex.java @@ -33,7 +33,7 @@ public FlexIndex(TransitModel transitModel) { tripById.put(flexTrip.getTrip().getId(), flexTrip); for (StopLocation stop : flexTrip.getStops()) { if (stop instanceof GroupStop groupStop) { - for (StopLocation stopElement : groupStop.getLocations()) { + for (StopLocation stopElement : groupStop.getChildLocations()) { flexTripsByStop.put(stopElement, flexTrip); } } else { diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java b/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java index edff0860933..e16e1e5e1f7 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java +++ b/src/ext/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTrip.java @@ -248,7 +248,7 @@ public TransitBuilder copy( private Collection expandStops(StopLocation stop) { return stop instanceof GroupStop groupStop - ? groupStop.getLocations() + ? groupStop.getChildLocations() : Collections.singleton(stop); } @@ -259,7 +259,7 @@ private int getFromIndex(NearbyStop accessEgress) { } StopLocation stop = stopTimes[i].stop; if (stop instanceof GroupStop groupStop) { - if (groupStop.getLocations().contains(accessEgress.stop)) { + if (groupStop.getChildLocations().contains(accessEgress.stop)) { return i; } } else { @@ -278,7 +278,7 @@ private int getToIndex(NearbyStop accessEgress) { } StopLocation stop = stopTimes[i].stop; if (stop instanceof GroupStop groupStop) { - if (groupStop.getLocations().contains(accessEgress.stop)) { + if (groupStop.getChildLocations().contains(accessEgress.stop)) { return i; } } else { diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java index 71a77eee5e7..c5968507676 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java +++ b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java @@ -300,7 +300,7 @@ public TransitBuilder copy() { private Stream expandStops(int index) { var stop = stopTimes[index].stop(); return stop instanceof GroupStop groupStop - ? groupStop.getLocations().stream().map(s -> new IndexedStopLocation(index, s)) + ? groupStop.getChildLocations().stream().map(s -> new IndexedStopLocation(index, s)) : Stream.of(new IndexedStopLocation(index, stop)); } @@ -311,7 +311,7 @@ private int getFromIndex(NearbyStop accessEgress) { } StopLocation stop = stopTimes[i].stop(); if (stop instanceof GroupStop groupStop) { - if (groupStop.getLocations().contains(accessEgress.stop)) { + if (groupStop.getChildLocations().contains(accessEgress.stop)) { return i; } } else { @@ -330,7 +330,7 @@ private int getToIndex(NearbyStop accessEgress) { } StopLocation stop = stopTimes[i].stop(); if (stop instanceof GroupStop groupStop) { - if (groupStop.getLocations().contains(accessEgress.stop)) { + if (groupStop.getChildLocations().contains(accessEgress.stop)) { return i; } } else { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index a15bf2f838e..6dd9fc5e31c 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -25,9 +25,6 @@ import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.site.AreaStop; -import org.opentripplanner.transit.model.site.GroupStop; -import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; @@ -80,11 +77,8 @@ public static GraphQLObjectType create( .type(Scalars.GraphQLString) .build() ) - .dataFetcher(environment -> - ( - ((StopLocation) environment.getSource()).getName() - .toString(GqlUtil.getLocale(environment)) - ) + .dataFetcher(env -> + (((StopLocation) env.getSource()).getName().toString(GqlUtil.getLocale(env))) ) .build() ) @@ -93,7 +87,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("latitude") .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> (((StopLocation) environment.getSource()).getLat())) + .dataFetcher(env -> (((StopLocation) env.getSource()).getLat())) .build() ) .field( @@ -101,7 +95,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("longitude") .type(Scalars.GraphQLFloat) - .dataFetcher(environment -> (((StopLocation) environment.getSource()).getLon())) + .dataFetcher(env -> (((StopLocation) env.getSource()).getLon())) .build() ) .field( @@ -109,11 +103,8 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("description") .type(Scalars.GraphQLString) - .dataFetcher(environment -> - GraphQLUtils.getTranslation( - ((StopLocation) environment.getSource()).getDescription(), - environment - ) + .dataFetcher(env -> + GraphQLUtils.getTranslation(((StopLocation) env.getSource()).getDescription(), env) ) .build() ) @@ -123,12 +114,12 @@ public static GraphQLObjectType create( .name("stopPlace") .description("The stop place to which this quay belongs to.") .type(stopPlaceType) - .dataFetcher(environment -> { - Station station = ((StopLocation) environment.getSource()).getParentStation(); + .dataFetcher(env -> { + Station station = ((StopLocation) env.getSource()).getParentStation(); if (station != null) { return new MonoOrMultiModalStation( station, - GqlUtil.getTransitService(environment).getMultiModalStationForStation(station) + GqlUtil.getTransitService(env).getMultiModalStationForStation(station) ); } else { return null; @@ -142,9 +133,9 @@ public static GraphQLObjectType create( .name("wheelchairAccessible") .type(EnumTypes.WHEELCHAIR_BOARDING) .description("Whether this quay is suitable for wheelchair boarding.") - .dataFetcher(environment -> + .dataFetcher(env -> Objects.requireNonNullElse( - (((StopLocation) environment.getSource()).getWheelchairAccessibility()), + (((StopLocation) env.getSource()).getWheelchairAccessibility()), Accessibility.NO_INFORMATION ) ) @@ -155,10 +146,8 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("timeZone") .type(Scalars.GraphQLString) - .dataFetcher(environment -> - Optional - .ofNullable(((StopLocation) environment.getSource()).getTimeZone()) - .map(ZoneId::getId) + .dataFetcher(env -> + Optional.ofNullable(((StopLocation) env.getSource()).getTimeZone()).map(ZoneId::getId) ) .build() ) @@ -170,7 +159,7 @@ public static GraphQLObjectType create( .description( "Public code used to identify this quay within the stop place. For instance a platform code." ) - .dataFetcher(environment -> (((StopLocation) environment.getSource()).getPlatformCode())) + .dataFetcher(env -> (((StopLocation) env.getSource()).getPlatformCode())) .build() ) .field( @@ -180,10 +169,10 @@ public static GraphQLObjectType create( .withDirective(gqlUtil.timingData) .description("List of lines servicing this quay") .type(new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(lineType)))) - .dataFetcher(environment -> + .dataFetcher(env -> GqlUtil - .getTransitService(environment) - .getPatternsForStop(environment.getSource(), true) + .getTransitService(env) + .getPatternsForStop(env.getSource(), true) .stream() .map(TripPattern::getRoute) .distinct() @@ -198,8 +187,8 @@ public static GraphQLObjectType create( .withDirective(gqlUtil.timingData) .description("List of journey patterns servicing this quay") .type(new GraphQLNonNull(new GraphQLList(journeyPatternType))) - .dataFetcher(environment -> - GqlUtil.getTransitService(environment).getPatternsForStop(environment.getSource(), true) + .dataFetcher(env -> + GqlUtil.getTransitService(env).getPatternsForStop(env.getSource(), true) ) .build() ) @@ -361,17 +350,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("stopType") .type(Scalars.GraphQLString) - .dataFetcher(environment -> { - StopLocation stopLocation = environment.getSource(); - if (stopLocation instanceof RegularStop) { - return "regular"; - } else if (stopLocation instanceof AreaStop) { - return "flexible_area"; - } else if (stopLocation instanceof GroupStop) { - return "flexible_group"; - } - return null; - }) + .dataFetcher(env -> ((StopLocation) env.getSource()).getStopType()) .build() ) .field( @@ -380,13 +359,11 @@ public static GraphQLObjectType create( .name("flexibleArea") .description("Geometry for flexible area.") .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) - .dataFetcher(environment -> { - if (environment.getSource() instanceof AreaStop areaStop) { - return areaStop.getGeometry().getCoordinates(); - } else if (environment.getSource() instanceof GroupStop groupStop) { - return groupStop.getEncompassingAreaGeometry().getCoordinates(); - } - return null; + .dataFetcher(env -> { + StopLocation stopLocation = env.getSource(); + return stopLocation.getEncompassingAreaGeometry() == null + ? null + : stopLocation.getEncompassingAreaGeometry().getCoordinates(); }) .build() ) @@ -396,13 +373,7 @@ public static GraphQLObjectType create( .name("flexibleGroup") .description("the Quays part of a flexible group.") .type(GraphQLList.list(REF)) - .dataFetcher(environment -> - ( - environment.getSource() instanceof GroupStop groupStop - ? groupStop.getLocations() - : null - ) - ) + .dataFetcher(env -> ((StopLocation) env.getSource()).getChildLocations()) .build() ) .field( @@ -410,7 +381,7 @@ public static GraphQLObjectType create( .newFieldDefinition() .name("tariffZones") .type(new GraphQLNonNull(new GraphQLList(tariffZoneType))) - .dataFetcher(environment -> ((StopLocation) environment.getSource()).getFareZones()) + .dataFetcher(env -> ((StopLocation) env.getSource()).getFareZones()) .build() ) .build(); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java b/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java index 7ec84763d81..37334161b0a 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java @@ -97,7 +97,7 @@ public void linkTransitStops(Graph graph, TransitModel transitModel) { .stream() .filter(GroupStop.class::isInstance) .map(GroupStop.class::cast) - .flatMap(g -> g.getLocations().stream().filter(RegularStop.class::isInstance)) + .flatMap(g -> g.getChildLocations().stream().filter(RegularStop.class::isInstance)) .toList() ); } diff --git a/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java b/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java index 30bd04eea73..c3c9ad2d0ae 100644 --- a/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java +++ b/src/main/java/org/opentripplanner/netex/mapping/NetexMapper.java @@ -374,7 +374,7 @@ private void mapFlexibleStopPlaces() { transitBuilder.stopModel().withAreaStop(areaStop); } else if (stopLocation instanceof GroupStop groupStop) { transitBuilder.stopModel().withGroupStop(groupStop); - for (var child : groupStop.getLocations()) { + for (var child : groupStop.getChildLocations()) { if (child instanceof AreaStop areaStop) { transitBuilder.stopModel().withAreaStop(areaStop); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java b/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java index c369c995f09..a398a7dae1c 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java @@ -84,6 +84,12 @@ public I18NString getUrl() { return url; } + @Nonnull + @Override + public String getStopType() { + return "flexible_area"; + } + @Override public String getFirstZoneAsString() { return zoneId; @@ -103,6 +109,14 @@ public Geometry getGeometry() { return geometry; } + /** + * Returns the geometry of area that defines the stop, in this case the same as getGeometry. + */ + @Override + public Geometry getEncompassingAreaGeometry() { + return geometry; + } + @Override public boolean isPartOfStation() { return false; diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index 2f2ddca044f..d42a1eb121d 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -63,6 +63,12 @@ public I18NString getUrl() { return null; } + @Override + @Nonnull + public String getStopType() { + return "flexible_group"; + } + @Override public String getFirstZoneAsString() { return null; @@ -86,9 +92,16 @@ public Geometry getGeometry() { } /** - * Returns the geometry of the area that encompasses the bounds of this location group. + * Returns the geometry of the area that encompasses the bounds of this StopLocation group. If the + * group is defined only as a list of stops, this will return the same as getGeometry. If on the + * other hand the group is defined as an area and the stops are inferred from that area, then this + * will return the geometry of the area. */ + @Override public Geometry getEncompassingAreaGeometry() { + if (encompassingAreaGeometry == null) { + return geometry; + } return encompassingAreaGeometry; } @@ -105,7 +118,9 @@ public boolean isPartOfSameStationAs(StopLocation alternativeStop) { /** * Returns all the locations belonging to this location group. */ - public Set getLocations() { + @Override + @Nonnull + public Set getChildLocations() { return stopLocations; } @@ -114,7 +129,7 @@ public boolean sameAs(@Nonnull GroupStop other) { return ( getId().equals(other.getId()) && Objects.equals(name, other.getName()) && - Objects.equals(stopLocations, other.getLocations()) + Objects.equals(stopLocations, other.getChildLocations()) ); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index b574eb8c9ea..0dc22d20512 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -41,7 +41,7 @@ public class GroupStopBuilder extends AbstractEntityBuilder(original.getLocations()); + this.stopLocations = new HashSet<>(original.getChildLocations()); this.geometry = (GeometryCollection) original.getGeometry(); this.centroid = original.getCoordinate(); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java b/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java index 5d5760337ff..88fafab17e8 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java @@ -81,6 +81,12 @@ public I18NString getUrl() { return url; } + @Nonnull + @Override + public String getStopType() { + return "regular"; + } + @Override @Nullable public ZoneId getTimeZone() { diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java index 84658c16be8..0d42519d663 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java @@ -3,6 +3,7 @@ import java.time.ZoneId; import java.util.Collection; import java.util.List; +import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Geometry; @@ -43,6 +44,9 @@ public interface StopLocation extends LogInfo { @Nullable I18NString getUrl(); + @Nonnull + String getStopType(); + /** * Short text or a number that identifies the location for riders. These codes are often used in * phone-based reservation systems to make it easier for riders to specify a particular location. @@ -121,6 +125,15 @@ default String getFirstZoneAsString() { @Nullable Geometry getGeometry(); + /** + * The geometry of the area that encompasses the bounds of the stop area. If the stop is defined + * as a point, this is null. + */ + @Nullable + default Geometry getEncompassingAreaGeometry() { + return null; + } + @Nullable default ZoneId getTimeZone() { return null; @@ -135,6 +148,14 @@ default StopTransferPriority getPriority() { boolean isPartOfSameStationAs(StopLocation alternativeStop); + /** + * Returns the child locations of this location, for example StopLocations within a GroupStop. + */ + @Nullable + default Set getChildLocations() { + return null; + } + @Override default String logName() { return ObjectUtils.ifNotNull(getName(), Object::toString, null); diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java b/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java index 6e082d9e98d..94c203c76ae 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java +++ b/src/test/java/org/opentripplanner/gtfs/mapping/StopTimeMapperTest.java @@ -228,6 +228,6 @@ public void testFlexLocationGroup() { assertInstanceOf(GroupStop.class, mapped.getStop()); var groupStop = (GroupStop) mapped.getStop(); - assertEquals("[RegularStop{A:1 Stop}]", groupStop.getLocations().toString()); + assertEquals("[RegularStop{A:1 Stop}]", groupStop.getChildLocations().toString()); } } diff --git a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java b/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java index b59f3c1b58a..e4bba2b729d 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java +++ b/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java @@ -258,7 +258,7 @@ private void assertGroupStopMapping(FlexibleStopPlace flexibleStopPlace) { assertNotNull(groupStop); // Only one of the stops should be inside the polygon - Set locations = groupStop.getLocations(); + Set locations = groupStop.getChildLocations(); assertEquals(1, locations.size()); assertEquals(stop1.getId(), locations.stream().findFirst().orElseThrow().getId()); } diff --git a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java b/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java index fa073404e39..17938131eef 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java +++ b/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java @@ -44,7 +44,7 @@ void copy() { assertEquals(subject, copy); assertEquals(ID, copy.getId().getId()); - assertEquals(STOP_LOCATION, copy.getLocations().iterator().next()); + assertEquals(STOP_LOCATION, copy.getChildLocations().iterator().next()); assertEquals("v2", copy.getName().toString()); } From 9ae66d363fb71354c98a7e6ed1a429a899e1f512 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 19 Jan 2024 17:26:53 +0200 Subject: [PATCH 196/356] Set scooter preferences to be equal to bike preferences in apis --- docs/RouteRequest.md | 4 -- docs/RouterConfiguration.md | 4 -- .../resources/RequestToPreferencesMapper.java | 22 ++++++ .../apis/gtfs/mapping/RouteRequestMapper.java | 22 ++++++ .../transmodel/mapping/PreferencesMapper.java | 2 + .../preferences/ScooterPreferencesMapper.java | 36 ++++++++++ .../visualizer/GraphVisualizer.java | 6 ++ .../ScooterPreferencesMapperTest.java | 70 +++++++++++++++++++ .../module/osm/TriangleInequalityTest.java | 1 + .../routing/algorithm/TurnCostTest.java | 1 + 10 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java create mode 100644 src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 70fa0d26e49..d478bb01c6e 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -1158,10 +1158,6 @@ include stairs as a last result. "scooter" : { "speed" : 5, "reluctance" : 5.0, - "walk" : { - "reluctance" : 10.0, - "stairsReluctance" : 150.0 - }, "rental" : { "pickupCost" : 120, "dropOffTime" : "30s", diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index dfe3c3f9750..abf338c44e5 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -499,10 +499,6 @@ Used to group requests when monitoring OTP. "scooter" : { "speed" : 5, "reluctance" : 5.0, - "walk" : { - "reluctance" : 10.0, - "stairsReluctance" : 150.0 - }, "rental" : { "pickupCost" : 120, "dropOffTime" : "30s", diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index 2208ec13a14..009d1c03c1f 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -32,6 +32,7 @@ void map() { mapCar(); mapWalk(); mapBike(); + mapScooter(); var boardAndAlightSlack = mapTransit(); @@ -95,6 +96,27 @@ private void mapBike() { }); } + private void mapScooter() { + preferences.withScooter(scooter -> { + setIfNotNull(req.bikeSpeed, scooter::withSpeed); + setIfNotNull(req.bikeReluctance, scooter::withReluctance); + setIfNotNull( + req.bikeOptimizeType, + optimizeType -> scooter.withOptimizeType(LegacyVehicleRoutingOptimizeType.map(optimizeType)) + ); + + if (req.bikeOptimizeType == LegacyVehicleRoutingOptimizeType.TRIANGLE) { + scooter.withOptimizeTriangle(triangle -> { + setIfNotNull(req.triangleTimeFactor, triangle::withTime); + setIfNotNull(req.triangleSlopeFactor, triangle::withSlope); + setIfNotNull(req.triangleSafetyFactor, triangle::withSafety); + }); + } + + scooter.withRental(this::mapRental); + }); + } + private BoardAndAlightSlack mapTransit() { preferences.withTransit(tr -> { setIfNotNull(req.boardSlack, tr::withDefaultBoardSlackSec); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index 5cdae33850f..d9a190ccf5d 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -98,6 +98,28 @@ public static RouteRequest toRouteRequest( car.withRental(rental -> setRentalPreferences(callWith, request, rental)); }); + preferences.withScooter(scooter -> { + callWith.argument("bikeReluctance", scooter::withReluctance); + callWith.argument("bikeSpeed", scooter::withSpeed); + + if (environment.getArgument("optimize") != null) { + scooter.withOptimizeType( + OptimizationTypeMapper.map( + GraphQLTypes.GraphQLOptimizeType.valueOf(environment.getArgument("optimize")) + ) + ); + } + if (scooter.optimizeType() == VehicleRoutingOptimizeType.TRIANGLE) { + scooter.withOptimizeTriangle(triangle -> { + callWith.argument("triangle.timeFactor", triangle::withTime); + callWith.argument("triangle.slopeFactor", triangle::withSlope); + callWith.argument("triangle.safetyFactor", triangle::withSafety); + }); + } + + scooter.withRental(rental -> setRentalPreferences(callWith, request, rental)); + }); + preferences.withWalk(b -> { callWith.argument("walkReluctance", b::withReluctance); callWith.argument("walkSpeed", b::withSpeed); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java index 846437952e4..a86193553f2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/PreferencesMapper.java @@ -3,6 +3,7 @@ import static org.opentripplanner.apis.transmodel.mapping.preferences.BikePreferencesMapper.mapBikePreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.CarPreferencesMapper.mapCarPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.ItineraryFilterPreferencesMapper.mapItineraryFilterPreferences; +import static org.opentripplanner.apis.transmodel.mapping.preferences.ScooterPreferencesMapper.mapScooterPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.StreetPreferencesMapper.mapStreetPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.TransferPreferencesMapper.mapTransferPreferences; import static org.opentripplanner.apis.transmodel.mapping.preferences.TransitPreferencesMapper.mapTransitPreferences; @@ -24,6 +25,7 @@ static void mapPreferences( preferences.withWalk(walk -> mapWalkPreferences(walk, callWith)); preferences.withBike(bike -> mapBikePreferences(bike, callWith)); preferences.withCar(car -> mapCarPreferences(car, callWith)); + preferences.withScooter(scooter -> mapScooterPreferences(scooter, callWith)); preferences.withTransfer(transfer -> mapTransferPreferences(transfer, environment, callWith)); preferences.withTransit(transit -> mapTransitPreferences(transit, environment, callWith)); preferences.withItineraryFilter(itineraryFilter -> diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java new file mode 100644 index 00000000000..d7d5c019f93 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapper.java @@ -0,0 +1,36 @@ +package org.opentripplanner.apis.transmodel.mapping.preferences; + +import static org.opentripplanner.apis.transmodel.mapping.preferences.RentalPreferencesMapper.mapRentalPreferences; + +import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator; +import org.opentripplanner.routing.api.request.preference.ScooterPreferences; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; + +public class ScooterPreferencesMapper { + + public static void mapScooterPreferences( + ScooterPreferences.Builder scooter, + DataFetcherDecorator callWith + ) { + callWith.argument("bikeSpeed", scooter::withSpeed); + callWith.argument("bicycleOptimisationMethod", scooter::withOptimizeType); + + // WALK reluctance is used for backwards compatibility, then overridden + callWith.argument( + "walkReluctance", + r -> { + scooter.withReluctance((double) r); + } + ); + + if (scooter.optimizeType() == VehicleRoutingOptimizeType.TRIANGLE) { + scooter.withOptimizeTriangle(triangle -> { + callWith.argument("triangleFactors.time", triangle::withTime); + callWith.argument("triangleFactors.slope", triangle::withSlope); + callWith.argument("triangleFactors.safety", triangle::withSafety); + }); + } + + scooter.withRental(rental -> mapRentalPreferences(rental, callWith)); + } +} diff --git a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java index 338423df961..6ab7d86917c 100644 --- a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java +++ b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java @@ -490,6 +490,12 @@ protected void route(String from, String to) { // there should be a ui element for walk distance and optimize type .withOptimizeType(getSelectedOptimizeType()) ); + preferences.withScooter(scooter -> + scooter + .withSpeed(Float.parseFloat(bikeSpeed.getText())) + // there should be a ui element for walk distance and optimize type + .withOptimizeType(getSelectedOptimizeType()) + ); }); System.out.println("--------"); diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java new file mode 100644 index 00000000000..2b5c7563ac2 --- /dev/null +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/ScooterPreferencesMapperTest.java @@ -0,0 +1,70 @@ +package org.opentripplanner.apis.transmodel.mapping.preferences; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.apis.transmodel.mapping.preferences.ScooterPreferencesMapper.mapScooterPreferences; + +import java.util.List; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.apis.transmodel._support.TestDataFetcherDecorator; +import org.opentripplanner.routing.api.request.preference.ScooterPreferences; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; + +class ScooterPreferencesMapperTest { + + static List mapScooterPreferencesTestCases() { + return List.of( + Arguments.of("walkReluctance", 10.0, "ScooterPreferences{reluctance: 10.0}"), + Arguments.of("bikeSpeed", 10.0, "ScooterPreferences{speed: 10.0}"), + Arguments.of( + "bicycleOptimisationMethod", + VehicleRoutingOptimizeType.TRIANGLE, + "ScooterPreferences{optimizeType: TRIANGLE}" + ), + // No effect unless BicycleOptimize is TRIANGLE + Arguments.of("triangleFactors.time", 0.17, "ScooterPreferences{}"), + Arguments.of("triangleFactors.slope", 0.12, "ScooterPreferences{}"), + Arguments.of("triangleFactors.safety", 0.13, "ScooterPreferences{}") + ); + } + + @ParameterizedTest + @MethodSource("mapScooterPreferencesTestCases") + void testMapScooterPreferences(String field, Object value, String expected) { + var preferences = ScooterPreferences.of(); + mapScooterPreferences(preferences, TestDataFetcherDecorator.of(field, value)); + assertEquals(expected, preferences.build().toString()); + } + + static List mapScooterPreferencesOptimizeTriangleTestCases() { + return List.of( + Arguments.of( + "triangleFactors.time", + 0.17, + "TimeSlopeSafetyTriangle[time=1.0, slope=0.0, safety=0.0]" + ), + Arguments.of( + "triangleFactors.slope", + 0.12, + "TimeSlopeSafetyTriangle[time=0.0, slope=1.0, safety=0.0]" + ), + Arguments.of( + "triangleFactors.safety", + 0.13, + "TimeSlopeSafetyTriangle[time=0.0, slope=0.0, safety=1.0]" + ) + ); + } + + @ParameterizedTest + @MethodSource("mapScooterPreferencesOptimizeTriangleTestCases") + void testMapScooterPreferencesOptimizeTriangle(String field, Object value, String expected) { + var preferences = ScooterPreferences.of().withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE); + mapScooterPreferences(preferences, TestDataFetcherDecorator.of(field, value)); + assertEquals( + "ScooterPreferences{optimizeType: TRIANGLE, optimizeTriangle: " + expected + "}", + preferences.build().toString() + ); + } +} diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java b/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java index 4cdada95e4b..52069a7a72e 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java +++ b/src/test/java/org/opentripplanner/graph_builder/module/osm/TriangleInequalityTest.java @@ -182,6 +182,7 @@ private void checkTriangleInequality(RequestModes modes, List fil .withStreet(street -> street.withTurnReluctance(1.0)) .withCar(car -> car.withSpeed(1.0).withReluctance(1.0)) .withBike(bike -> bike.withSpeed(1.0).withReluctance(1.0)) + .withScooter(scooter -> scooter.withSpeed(1.0).withReluctance(1.0)) ); if (modes != null) { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java b/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java index 53e340dcc63..dfb062226a4 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/TurnCostTest.java @@ -94,6 +94,7 @@ public void before() { preferences .withCar(it -> it.withSpeed(1.0).withReluctance(1.0)) .withBike(bike -> bike.withSpeed(1.0).withReluctance(1.0)) + .withScooter(scooter -> scooter.withSpeed(1.0).withReluctance(1.0)) .withWalk(walk -> walk.withSpeed(1.0).withStairsReluctance(1.0).withReluctance(1.0)) .withStreet(it -> it.withTurnReluctance(1.0)) ); From b22d9e406da07635bab51956149f6ee0f43f1526 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 19 Jan 2024 17:27:36 +0200 Subject: [PATCH 197/356] Disable scooter arrival to destination in access requests --- .../routing/algorithm/raptoradapter/router/TransitRouter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java index 1b5c836c832..62b655cfc18 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java @@ -232,6 +232,8 @@ private Collection fetchAccessEgresses(AccessEgressType typ accessRequest.withPreferences(p -> { p.withBike(b -> b.withRental(r -> r.withAllowArrivingInRentedVehicleAtDestination(false))); p.withCar(c -> c.withRental(r -> r.withAllowArrivingInRentedVehicleAtDestination(false))); + p.withScooter(s -> s.withRental(r -> r.withAllowArrivingInRentedVehicleAtDestination(false)) + ); }); } From dcf811e80ce793e3dba4a69cef27b8b569fe3b10 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jan 2024 16:36:27 +0100 Subject: [PATCH 198/356] Update Portland config example --- docs/examples/ibi/portland/build-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/ibi/portland/build-config.json b/docs/examples/ibi/portland/build-config.json index 4b3a232ffba..46309d21c59 100644 --- a/docs/examples/ibi/portland/build-config.json +++ b/docs/examples/ibi/portland/build-config.json @@ -6,7 +6,7 @@ "transitFeeds": [ { "type": "gtfs", - "feedId": "trimet", + "feedId": "TriMet", "source": "https://developer.trimet.org/schedule/gtfs.zip" } ] From 3d38d4a15932c58fb82bdc67882fc294d2d8b615 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 19 Jan 2024 17:40:05 +0200 Subject: [PATCH 199/356] Move class to correct package --- .../ext/restapi}/mapping/LegacyVehicleRoutingOptimizeType.java | 2 +- .../ext/restapi/resources/RequestToPreferencesMapper.java | 2 +- .../opentripplanner/ext/restapi/resources/RoutingResource.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/{main/java/org/opentripplanner/api => ext/java/org/opentripplanner/ext/restapi}/mapping/LegacyVehicleRoutingOptimizeType.java (93%) diff --git a/src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java similarity index 93% rename from src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java index 0cb2ae38bcc..675e8541048 100644 --- a/src/main/java/org/opentripplanner/api/mapping/LegacyVehicleRoutingOptimizeType.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyVehicleRoutingOptimizeType.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index 009d1c03c1f..91e7b790ba7 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -2,7 +2,7 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; -import org.opentripplanner.api.mapping.LegacyVehicleRoutingOptimizeType; +import org.opentripplanner.ext.restapi.mapping.LegacyVehicleRoutingOptimizeType; import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 53464940a9e..1d985f0e555 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -18,9 +18,9 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import org.opentripplanner.api.mapping.LegacyVehicleRoutingOptimizeType; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; +import org.opentripplanner.ext.restapi.mapping.LegacyVehicleRoutingOptimizeType; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; From 242b3fbbf694ab550985963ac14859fdaee6abea Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 19 Jan 2024 18:09:21 +0100 Subject: [PATCH 200/356] Return agencies and feed publisher in geocoding --- docs/apis/Apis.md | 2 +- docs/sandbox/GeocoderAPI.md | 8 ++--- .../ext/geocoder/LuceneIndexTest.java | 1 + .../ext/geocoder/GeocoderResource.java | 24 ++++++++------ .../ext/geocoder/LuceneIndex.java | 28 ++++++++++++---- .../ext/geocoder/StopCluster.java | 15 ++++++++- .../ext/geocoder/StopClusterMapper.java | 32 +++++++++++++++++-- .../opentripplanner/apis/APIEndpoints.java | 2 ++ .../service/DefaultTransitService.java | 5 +++ .../transit/service/TransitService.java | 2 ++ 10 files changed, 96 insertions(+), 23 deletions(-) diff --git a/docs/apis/Apis.md b/docs/apis/Apis.md index 48b530a57e1..d9f0467bbca 100644 --- a/docs/apis/Apis.md +++ b/docs/apis/Apis.md @@ -18,7 +18,7 @@ entities on a vector map. The [Actuator API](../sandbox/ActuatorAPI.md) provides endpoints for checking the health status of the OTP instance and reading live application metrics. -The [Geocoder API](../sandbox/GeocoderAPI.md) allows you to geocode street corners and stop names. +The [Geocoder API](../sandbox/GeocoderAPI.md) allows you to geocode stop names and codes. ## Legacy APIs (to be removed) diff --git a/docs/sandbox/GeocoderAPI.md b/docs/sandbox/GeocoderAPI.md index 0405724fff6..f7a1be3f293 100644 --- a/docs/sandbox/GeocoderAPI.md +++ b/docs/sandbox/GeocoderAPI.md @@ -26,7 +26,7 @@ To enable this you need to add the feature to `otp-config.json`. The required geocode API for Stop and From/To searches in the debug client. -Path: `/otp/routers/{routerId}/geocode` +Path: `/otp/geocode` It supports the following URL parameters: @@ -40,12 +40,12 @@ It supports the following URL parameters: #### Stop clusters A stop cluster is a deduplicated groups of stops. This means that for any stop that has a parent -station only the parent is returned and for stops that have identical names and are very close +station only the parent is returned and for stops that have _identical_ names and are very close to each other, only one is returned. -This is useful for a general purpose fuzzy "stop" search. +This is useful for a general purpose fuzzy stop search. -Path: `/otp/routers/{routerId}/geocode/stopClusters` +Path: `/otp/geocode/stopClusters` It supports the following URL parameters: diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 371bcb249b6..178b8b6fd67 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -105,6 +105,7 @@ static void setup() { .of(ALEXANDERPLATZ_STATION, BERLIN_HAUPTBAHNHOF_STATION, FIVE_POINTS_STATION) .forEach(stopModel::withStation); var transitModel = new TransitModel(stopModel.build(), new Deduplicator()); + transitModel.index(); var transitService = new DefaultTransitService(transitModel) { private final Multimap modes = ImmutableMultimap .builder() diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java index 39ed6da297c..f5d1f950632 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/GeocoderResource.java @@ -21,24 +21,30 @@ /** * OTP simple built-in geocoder used by the debug client. */ -@Path("/routers/{ignoreRouterId}/geocode") +@Path("/geocode") @Produces(MediaType.APPLICATION_JSON) public class GeocoderResource { private final OtpServerRequestContext serverContext; - /** - * @deprecated The support for multiple routers are removed from OTP2. See - * https://github.com/opentripplanner/OpenTripPlanner/issues/2760 - */ - @Deprecated - @PathParam("ignoreRouterId") - private String ignoreRouterId; - public GeocoderResource(@Context OtpServerRequestContext requestContext) { serverContext = requestContext; } + /** + * This class is only here for backwards-compatibility. It will be removed in the future. + */ + @Path("/routers/{ignoreRouterId}/geocode") + public static class GeocoderResourceOldPath extends GeocoderResource { + + public GeocoderResourceOldPath( + @Context OtpServerRequestContext serverContext, + @PathParam("ignoreRouterId") String ignore + ) { + super(serverContext); + } + } + /** * Geocode using data using the OTP graph for stops, clusters and street names * diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 71b0cf67b34..e390c900377 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -42,7 +42,6 @@ import org.apache.lucene.store.ByteBuffersDirectory; import org.opentripplanner.ext.geocoder.StopCluster.Coordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.StopLocation; @@ -67,6 +66,7 @@ public class LuceneIndex implements Serializable { public LuceneIndex(TransitService transitService) { this.transitService = transitService; + var stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -80,7 +80,6 @@ public LuceneIndex(TransitService transitService) { var directory = new ByteBuffersDirectory(); - var stopClusterMapper = new StopClusterMapper(transitService); try { try ( var directoryWriter = new IndexWriter( @@ -128,7 +127,7 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopCluster.class, stopCluster.id().toString(), - new NonLocalizedString(stopCluster.name()), + I18NString.of(stopCluster.name()), stopCluster.code(), stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), @@ -176,17 +175,34 @@ public Stream queryStopLocationGroups(String query, boolean * one of those is chosen at random and returned. */ public Stream queryStopClusters(String query) { - return matchingDocuments(StopCluster.class, query, false).map(LuceneIndex::toStopCluster); + return matchingDocuments(StopCluster.class, query, false).map(this::toStopCluster); } - private static StopCluster toStopCluster(Document document) { + private StopCluster toStopCluster(Document document) { var id = FeedScopedId.parse(document.get(ID)); var name = document.get(NAME); var code = document.get(CODE); var lat = document.getField(LAT).numericValue().doubleValue(); var lon = document.getField(LON).numericValue().doubleValue(); var modes = Arrays.asList(document.getValues(MODE)); - return new StopCluster(id, code, name, new Coordinate(lat, lon), modes); + var stopLocation = transitService.getStopLocation(id); + var agencies = transitService + .getAgenciesForStopLocation(stopLocation) + .stream() + .map(StopClusterMapper::toAgency) + .toList(); + var feedPublisher = StopClusterMapper.toFeedPublisher( + transitService.getFeedInfo(id.getFeedId()) + ); + return new StopCluster( + id, + code, + name, + new Coordinate(lat, lon), + modes, + agencies, + feedPublisher + ); } static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java index afb60960ed4..8ffd44511fd 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java @@ -1,6 +1,7 @@ package org.opentripplanner.ext.geocoder; import java.util.Collection; +import java.util.List; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -18,10 +19,22 @@ record StopCluster( @Nullable String code, String name, Coordinate coordinate, - Collection modes + Collection modes, + List agencies, + @Nullable FeedPublisher feedPublisher ) { /** * Easily serializable version of a coordinate */ public record Coordinate(double lat, double lon) {} + + /** + * Easily serializable version of an agency + */ + public record Agency(FeedScopedId id, String name) {} + + /** + * Easily serializable version of a feed publisher + */ + public record FeedPublisher(String name) {} } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index bc2f4f7022b..186d6d6b57e 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -6,6 +6,8 @@ import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; import org.opentripplanner.transit.service.TransitService; @@ -62,7 +64,15 @@ StopCluster map(StopLocationsGroup g) { null, g.getName().toString(), toCoordinate(g.getCoordinate()), - modes + modes, + g + .getChildStops() + .stream() + .flatMap(sl -> transitService.getAgenciesForStopLocation(sl).stream()) + .distinct() + .map(StopClusterMapper::toAgency) + .toList(), + toFeedPublisher(transitService.getFeedInfo(g.getId().getFeedId())) ); } @@ -76,7 +86,13 @@ Optional map(StopLocation sl) { sl.getCode(), name.toString(), toCoordinate(sl.getCoordinate()), - modes + modes, + transitService + .getAgenciesForStopLocation(sl) + .stream() + .map(StopClusterMapper::toAgency) + .toList(), + toFeedPublisher(transitService.getFeedInfo(sl.getId().getFeedId())) ); }); } @@ -85,5 +101,17 @@ private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { return new StopCluster.Coordinate(c.latitude(), c.longitude()); } + static StopCluster.Agency toAgency(Agency a) { + return new StopCluster.Agency(a.getId(), a.getName()); + } + + static StopCluster.FeedPublisher toFeedPublisher(FeedInfo fi) { + if (fi == null) { + return null; + } else { + return new StopCluster.FeedPublisher(fi.getPublisherName()); + } + } + private record DeduplicationKey(I18NString name, WgsCoordinate coordinate) {} } diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java index 68f6bda3d3a..555ea1659f1 100644 --- a/src/main/java/org/opentripplanner/apis/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -61,6 +61,8 @@ private APIEndpoints() { addIfEnabled(SandboxAPIMapboxVectorTilesApi, VectorTilesResource.class); addIfEnabled(SandboxAPIParkAndRideApi, ParkAndRideResource.class); addIfEnabled(SandboxAPIGeocoder, GeocoderResource.class); + // scheduled to be removed and only here for backwards compatibility + addIfEnabled(SandboxAPIGeocoder, GeocoderResource.GeocoderResourceOldPath.class); addIfEnabled(SandboxAPITravelTime, TravelTimeResource.class); // scheduled to be removed diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 0d08bcf34b2..91d129e0a0c 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -572,6 +572,11 @@ public List getModesOfStopLocation(StopLocation stop) { return sortByOccurrenceAndReduce(getPatternModesOfStop(stop)).toList(); } + @Override + public List getAgenciesForStopLocation(StopLocation stop) { + return getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); + } + /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index d0664aa292d..5006ed93f30 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -215,4 +215,6 @@ List stopTimesForPatternAtStop( * So, if more patterns of mode BUS than RAIL visit the stop, the result will be [BUS,RAIL]. */ List getModesOfStopLocation(StopLocation stop); + + List getAgenciesForStopLocation(StopLocation stop); } From d4d7c5518f04318c0770d0d96924c49478c2e583 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 20 Jan 2024 09:13:51 +0100 Subject: [PATCH 201/356] Serialize agencies in Lucene index --- .../ext/geocoder/LuceneIndexTest.java | 13 ++++---- .../ext/geocoder/LuceneIndex.java | 31 +++++++++++------- .../ext/geocoder/LuceneStopCluster.java | 19 +++++++++++ .../ext/geocoder/StopClusterMapper.java | 32 +++++++------------ 4 files changed, 56 insertions(+), 39 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 178b8b6fd67..01b62a63891 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -175,14 +175,15 @@ class StopClusters { } ) void stopClustersWithTypos(String searchTerm) { - var result1 = index.queryStopClusters(searchTerm).toList(); - assertEquals(List.of(mapper.map(ALEXANDERPLATZ_STATION)), result1); + var results = index.queryStopClusters(searchTerm).toList(); + var ids = results.stream().map(StopCluster::id).toList(); + assertEquals(List.of(ALEXANDERPLATZ_STATION.getId()), ids); } @Test void fuzzyStopClusters() { - var result1 = index.queryStopClusters("arts").toList(); - assertEquals(List.of(mapper.map(ARTS_CENTER).get()), result1); + var result1 = index.queryStopClusters("arts").map(StopCluster::id).toList(); + assertEquals(List.of(ARTS_CENTER.getId()), result1); } @Test @@ -221,8 +222,8 @@ void deduplicatedStopClusters() { } ) void stopClustersWithSpace(String query) { - var result = index.queryStopClusters(query).toList(); - assertEquals(List.of(mapper.map(FIVE_POINTS_STATION)), result); + var result = index.queryStopClusters(query).map(StopCluster::id).toList(); + assertEquals(List.of(FIVE_POINTS_STATION.getId()), result); } @ParameterizedTest diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index e390c900377..26c4d34ce25 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -59,14 +59,16 @@ public class LuceneIndex implements Serializable { private static final String LAT = "latitude"; private static final String LON = "longitude"; private static final String MODE = "mode"; + private static final String AGENCY_IDS= "agency_ids"; private final TransitService transitService; private final Analyzer analyzer; private final SuggestIndexSearcher searcher; + private final StopClusterMapper stopClusterMapper; public LuceneIndex(TransitService transitService) { this.transitService = transitService; - var stopClusterMapper = new StopClusterMapper(transitService); + this.stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -98,6 +100,7 @@ public LuceneIndex(TransitService transitService) { stopLocation.getCode(), stopLocation.getCoordinate().latitude(), stopLocation.getCoordinate().longitude(), + Set.of(), Set.of() ) ); @@ -113,6 +116,7 @@ public LuceneIndex(TransitService transitService) { null, stopLocationsGroup.getCoordinate().latitude(), stopLocationsGroup.getCoordinate().longitude(), + Set.of(), Set.of() ) ); @@ -131,7 +135,8 @@ public LuceneIndex(TransitService transitService) { stopCluster.code(), stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), - stopCluster.modes() + stopCluster.modes(), + stopCluster.agencies() ) ); } @@ -179,23 +184,21 @@ public Stream queryStopClusters(String query) { } private StopCluster toStopCluster(Document document) { - var id = FeedScopedId.parse(document.get(ID)); + var clusterId = FeedScopedId.parse(document.get(ID)); var name = document.get(NAME); var code = document.get(CODE); var lat = document.getField(LAT).numericValue().doubleValue(); var lon = document.getField(LON).numericValue().doubleValue(); var modes = Arrays.asList(document.getValues(MODE)); - var stopLocation = transitService.getStopLocation(id); - var agencies = transitService - .getAgenciesForStopLocation(stopLocation) - .stream() - .map(StopClusterMapper::toAgency) - .toList(); + var agencies = Arrays.stream(document.getValues(AGENCY_IDS)).map(id -> { + var fsid = FeedScopedId.parse(id); + return transitService.getAgencyForId(fsid); + }).filter(Objects::nonNull).map(StopClusterMapper::toAgency).toList(); var feedPublisher = StopClusterMapper.toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) + transitService.getFeedInfo(clusterId.getFeedId()) ); return new StopCluster( - id, + clusterId, code, name, new Coordinate(lat, lon), @@ -230,7 +233,8 @@ private static void addToIndex( @Nullable String code, double latitude, double longitude, - Collection modes + Collection modes, + Collection agencyIds ) { String typeName = type.getSimpleName(); @@ -251,6 +255,9 @@ private static void addToIndex( for (var mode : modes) { document.add(new TextField(MODE, mode, Store.YES)); } + for (var ids : agencyIds) { + document.add(new TextField(AGENCY_IDS, ids, Store.YES)); + } try { writer.addDocument(document); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java new file mode 100644 index 00000000000..3f916186430 --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -0,0 +1,19 @@ +package org.opentripplanner.ext.geocoder; + +import java.util.Collection; +import javax.annotation.Nullable; +import org.opentripplanner.transit.model.framework.FeedScopedId; + +/** + * A package-private helper type for transporting + */ +record LuceneStopCluster( + FeedScopedId id, + @Nullable + String code, + String name, + StopCluster.Coordinate coordinate, + Collection modes, + Collection agencies + ){ +} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 186d6d6b57e..c1a6d216ff0 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -13,7 +13,7 @@ import org.opentripplanner.transit.service.TransitService; /** - * Mappers for generating {@link StopCluster} from the transit model. + * Mappers for generating {@link LuceneStopCluster} from the transit model. */ class StopClusterMapper { @@ -23,6 +23,7 @@ class StopClusterMapper { this.transitService = transitService; } + /** * De-duplicates collections of {@link StopLocation} and {@link StopLocationsGroup} into a stream * of {@link StopCluster}. @@ -31,7 +32,7 @@ class StopClusterMapper { * - of "identical" stops which are very close to each other and have an identical name, only one * is chosen (at random) */ - Iterable generateStopClusters( + Iterable generateStopClusters( Collection stopLocations, Collection stopLocationsGroups ) { @@ -57,42 +58,31 @@ Iterable generateStopClusters( return Iterables.concat(deduplicatedStops, stations); } - StopCluster map(StopLocationsGroup g) { + LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - return new StopCluster( + var agencies = g.getChildStops().stream().flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()).distinct().map(s ->s.getId().toString()).toList(); + return new LuceneStopCluster( g.getId(), null, g.getName().toString(), toCoordinate(g.getCoordinate()), modes, - g - .getChildStops() - .stream() - .flatMap(sl -> transitService.getAgenciesForStopLocation(sl).stream()) - .distinct() - .map(StopClusterMapper::toAgency) - .toList(), - toFeedPublisher(transitService.getFeedInfo(g.getId().getFeedId())) + agencies ); } - Optional map(StopLocation sl) { + Optional map(StopLocation sl) { + var agencies = transitService.getAgenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); return Optional .ofNullable(sl.getName()) .map(name -> { var modes = transitService.getModesOfStopLocation(sl).stream().map(Enum::name).toList(); - return new StopCluster( + return new LuceneStopCluster( sl.getId(), sl.getCode(), name.toString(), toCoordinate(sl.getCoordinate()), - modes, - transitService - .getAgenciesForStopLocation(sl) - .stream() - .map(StopClusterMapper::toAgency) - .toList(), - toFeedPublisher(transitService.getFeedInfo(sl.getId().getFeedId())) + modes, agencies ); }); } From 8726b2fe10a7e48ed5de4e702b8cc3207897f22f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 20 Jan 2024 10:01:25 +0100 Subject: [PATCH 202/356] Add test for agencies --- .../ext/geocoder/LuceneIndexTest.java | 52 +++++++++++++++---- .../ext/geocoder/LuceneIndex.java | 18 ++++--- .../ext/geocoder/LuceneStopCluster.java | 6 +-- .../ext/geocoder/StopClusterMapper.java | 18 +++++-- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 01b62a63891..348586377d4 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -18,6 +18,8 @@ import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; @@ -28,57 +30,63 @@ class LuceneIndexTest { private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + static final Agency BVG = Agency + .of(id("bvg")) + .withName("BVG") + .withTimezone("Europe/Berlin") + .build(); + // Berlin - static Station BERLIN_HAUPTBAHNHOF_STATION = TEST_MODEL + static final Station BERLIN_HAUPTBAHNHOF_STATION = TEST_MODEL .station("Hauptbahnhof") .withCoordinate(52.52495, 13.36952) .build(); - static Station ALEXANDERPLATZ_STATION = TEST_MODEL + static final Station ALEXANDERPLATZ_STATION = TEST_MODEL .station("Alexanderplatz") .withCoordinate(52.52277, 13.41046) .build(); - static RegularStop ALEXANDERPLATZ_BUS = TEST_MODEL + static final RegularStop ALEXANDERPLATZ_BUS = TEST_MODEL .stop("Alexanderplatz Bus") .withCoordinate(52.52277, 13.41046) .withVehicleType(BUS) .withParentStation(ALEXANDERPLATZ_STATION) .build(); - static RegularStop ALEXANDERPLATZ_RAIL = TEST_MODEL + static final RegularStop ALEXANDERPLATZ_RAIL = TEST_MODEL .stop("Alexanderplatz S-Bahn") .withCoordinate(52.52157, 13.41123) .withVehicleType(TransitMode.RAIL) .withParentStation(ALEXANDERPLATZ_STATION) .build(); - static RegularStop LICHTERFELDE_OST_1 = TEST_MODEL + static final RegularStop LICHTERFELDE_OST_1 = TEST_MODEL .stop("Lichterfelde Ost") .withId(id("lichterfelde-gleis-1")) .withCoordinate(52.42986, 13.32808) .build(); - static RegularStop LICHTERFELDE_OST_2 = TEST_MODEL + static final RegularStop LICHTERFELDE_OST_2 = TEST_MODEL .stop("Lichterfelde Ost") .withId(id("lichterfelde-gleis-2")) .withCoordinate(52.42985, 13.32807) .build(); - static RegularStop WESTHAFEN = TEST_MODEL + static final RegularStop WESTHAFEN = TEST_MODEL .stop("Westhafen") .withVehicleType(null) .withCoordinate(52.42985, 13.32807) .build(); // Atlanta - static Station FIVE_POINTS_STATION = TEST_MODEL + static final Station FIVE_POINTS_STATION = TEST_MODEL .station("Five Points") .withCoordinate(33.753899, -84.39156) .build(); - static RegularStop ARTS_CENTER = TEST_MODEL + static final RegularStop ARTS_CENTER = TEST_MODEL .stop("Arts Center") .withCode("4456") .withCoordinate(52.52277, 13.41046) .build(); - static RegularStop ARTHUR = TEST_MODEL + static final RegularStop ARTHUR = TEST_MODEL .stop("Arthur Langford Jr Pl SW at 220") .withCoordinate(52.52277, 13.41046) .build(); @@ -120,6 +128,23 @@ public List getModesOfStopLocation(StopLocation stop) { return List.copyOf(modes.get(stop)); } } + + @Override + public List getAgenciesForStopLocation(StopLocation stop) { + if (stop.equals(ALEXANDERPLATZ_BUS)) { + return List.of(BVG); + } else { + return List.of(); + } + } + + @Override + public Agency getAgencyForId(FeedScopedId id) { + if (id.equals(BVG.getId())) { + return BVG; + } + return null; + } }; index = new LuceneIndex(transitService); mapper = new StopClusterMapper(transitService); @@ -242,5 +267,12 @@ void modes() { assertEquals(WESTHAFEN.getName().toString(), stop.name()); assertEquals(List.of(FERRY.name(), BUS.name()), stop.modes()); } + + @Test + void agencies() { + var result = index.queryStopClusters("alexanderplatz").toList().getFirst(); + assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.name()); + assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.agencies()); + } } } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 26c4d34ce25..75e0fc3333a 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -59,16 +59,15 @@ public class LuceneIndex implements Serializable { private static final String LAT = "latitude"; private static final String LON = "longitude"; private static final String MODE = "mode"; - private static final String AGENCY_IDS= "agency_ids"; + private static final String AGENCY_IDS = "agency_ids"; private final TransitService transitService; private final Analyzer analyzer; private final SuggestIndexSearcher searcher; - private final StopClusterMapper stopClusterMapper; public LuceneIndex(TransitService transitService) { this.transitService = transitService; - this.stopClusterMapper = new StopClusterMapper(transitService); + StopClusterMapper stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -190,10 +189,15 @@ private StopCluster toStopCluster(Document document) { var lat = document.getField(LAT).numericValue().doubleValue(); var lon = document.getField(LON).numericValue().doubleValue(); var modes = Arrays.asList(document.getValues(MODE)); - var agencies = Arrays.stream(document.getValues(AGENCY_IDS)).map(id -> { - var fsid = FeedScopedId.parse(id); - return transitService.getAgencyForId(fsid); - }).filter(Objects::nonNull).map(StopClusterMapper::toAgency).toList(); + var agencies = Arrays + .stream(document.getValues(AGENCY_IDS)) + .map(id -> { + var fsid = FeedScopedId.parse(id); + return transitService.getAgencyForId(fsid); + }) + .filter(Objects::nonNull) + .map(StopClusterMapper::toAgency) + .toList(); var feedPublisher = StopClusterMapper.toFeedPublisher( transitService.getFeedInfo(clusterId.getFeedId()) ); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 3f916186430..25776e1d39f 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -9,11 +9,9 @@ */ record LuceneStopCluster( FeedScopedId id, - @Nullable - String code, + @Nullable String code, String name, StopCluster.Coordinate coordinate, Collection modes, Collection agencies - ){ -} +) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index c1a6d216ff0..d231765b66d 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -23,7 +23,6 @@ class StopClusterMapper { this.transitService = transitService; } - /** * De-duplicates collections of {@link StopLocation} and {@link StopLocationsGroup} into a stream * of {@link StopCluster}. @@ -60,7 +59,13 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = g.getChildStops().stream().flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()).distinct().map(s ->s.getId().toString()).toList(); + var agencies = g + .getChildStops() + .stream() + .flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()) + .distinct() + .map(s -> s.getId().toString()) + .toList(); return new LuceneStopCluster( g.getId(), null, @@ -72,7 +77,11 @@ LuceneStopCluster map(StopLocationsGroup g) { } Optional map(StopLocation sl) { - var agencies = transitService.getAgenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); + var agencies = transitService + .getAgenciesForStopLocation(sl) + .stream() + .map(a -> a.getId().toString()) + .toList(); return Optional .ofNullable(sl.getName()) .map(name -> { @@ -82,7 +91,8 @@ Optional map(StopLocation sl) { sl.getCode(), name.toString(), toCoordinate(sl.getCoordinate()), - modes, agencies + modes, + agencies ); }); } From 1db3ac13d8c5a2b3685087494883f2709407a64b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 20 Jan 2024 17:35:11 +0100 Subject: [PATCH 203/356] Add test for feed publisher --- .../ext/geocoder/LuceneIndexTest.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 348586377d4..0b5933c2a52 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; +import java.time.LocalDate; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -15,6 +16,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.model.FeedInfo; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; @@ -145,6 +147,11 @@ public Agency getAgencyForId(FeedScopedId id) { } return null; } + + @Override + public FeedInfo getFeedInfo(String feedId) { + return new FeedInfo("F", "A Publisher", "http://example.com", "de", LocalDate.MIN, LocalDate.MIN, "1"); + } }; index = new LuceneIndex(transitService); mapper = new StopClusterMapper(transitService); @@ -154,7 +161,7 @@ public Agency getAgencyForId(FeedScopedId id) { void stopLocations() { var result1 = index.queryStopLocations("lich", true).toList(); assertEquals(1, result1.size()); - assertEquals(LICHTERFELDE_OST_1.getName().toString(), result1.get(0).getName().toString()); + assertEquals(LICHTERFELDE_OST_1.getName().toString(), result1.getFirst().getName().toString()); var result2 = index.queryStopLocations("alexan", true).collect(Collectors.toSet()); assertEquals(Set.of(ALEXANDERPLATZ_BUS, ALEXANDERPLATZ_RAIL), result2); @@ -215,7 +222,7 @@ void fuzzyStopClusters() { void deduplicatedStopClusters() { var result = index.queryStopClusters("lich").toList(); assertEquals(1, result.size()); - assertEquals(LICHTERFELDE_OST_1.getName().toString(), result.get(0).name()); + assertEquals(LICHTERFELDE_OST_1.getName().toString(), result.getFirst().name()); } @ParameterizedTest @@ -256,23 +263,24 @@ void stopClustersWithSpace(String query) { void fuzzyStopCode(String query) { var result = index.queryStopClusters(query).toList(); assertEquals(1, result.size()); - assertEquals(ARTS_CENTER.getName().toString(), result.get(0).name()); + assertEquals(ARTS_CENTER.getName().toString(), result.getFirst().name()); } @Test void modes() { var result = index.queryStopClusters("westh").toList(); assertEquals(1, result.size()); - var stop = result.get(0); + var stop = result.getFirst(); assertEquals(WESTHAFEN.getName().toString(), stop.name()); assertEquals(List.of(FERRY.name(), BUS.name()), stop.modes()); } @Test - void agencies() { + void agenciesAndFeedPublisher() { var result = index.queryStopClusters("alexanderplatz").toList().getFirst(); assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.name()); assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.agencies()); + assertEquals("A Publisher", result.feedPublisher().name()); } } } From 1182afd9f95d1c03b38bc89cfc6cb6238f7de15c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 21 Jan 2024 00:02:20 +0100 Subject: [PATCH 204/356] Add documentation --- .../opentripplanner/ext/geocoder/LuceneIndexTest.java | 10 +++++++++- .../ext/geocoder/LuceneStopCluster.java | 2 +- .../transit/service/TransitService.java | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 0b5933c2a52..8dc3ff77a01 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -150,7 +150,15 @@ public Agency getAgencyForId(FeedScopedId id) { @Override public FeedInfo getFeedInfo(String feedId) { - return new FeedInfo("F", "A Publisher", "http://example.com", "de", LocalDate.MIN, LocalDate.MIN, "1"); + return new FeedInfo( + "F", + "A Publisher", + "http://example.com", + "de", + LocalDate.MIN, + LocalDate.MIN, + "1" + ); } }; index = new LuceneIndex(transitService); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 25776e1d39f..49f1a7ee5c3 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -5,7 +5,7 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; /** - * A package-private helper type for transporting + * A package-private helper type for transporting data before serializing. */ record LuceneStopCluster( FeedScopedId id, diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index 5006ed93f30..c16b928d2bd 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -216,5 +216,9 @@ List stopTimesForPatternAtStop( */ List getModesOfStopLocation(StopLocation stop); + /** + * Iterates over all routes that visit this stop location and return a de-duplicated list + * of their agencies. + */ List getAgenciesForStopLocation(StopLocation stop); } From 0e529c74808670b8579ae0f5499ef7d83a5260bf Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 21 Jan 2024 11:35:18 +0100 Subject: [PATCH 205/356] Add tests --- .../org/opentripplanner/ext/geocoder/LuceneIndex.java | 2 +- .../ext/geocoder/LuceneStopCluster.java | 2 +- .../ext/geocoder/StopClusterMapper.java | 6 ++---- .../transit/service/DefaultTransitService.java | 10 ++++++++++ .../transit/service/TransitService.java | 6 ++++++ .../transit/service/DefaultTransitServiceTest.java | 9 +++++++++ 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 75e0fc3333a..b92b36f5a59 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -135,7 +135,7 @@ public LuceneIndex(TransitService transitService) { stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), stopCluster.modes(), - stopCluster.agencies() + stopCluster.agencyIds() ) ); } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 49f1a7ee5c3..f58d7aa9af9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -13,5 +13,5 @@ record LuceneStopCluster( String name, StopCluster.Coordinate coordinate, Collection modes, - Collection agencies + Collection agencyIds ) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index d231765b66d..10243665ac8 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -59,11 +59,9 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = g - .getChildStops() + var agencies = transitService + .getAgenciesForStopLocationsGroup(g) .stream() - .flatMap(s -> transitService.getAgenciesForStopLocation(s).stream()) - .distinct() .map(s -> s.getId().toString()) .toList(); return new LuceneStopCluster( diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 91d129e0a0c..f38499bfd68 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -577,6 +577,16 @@ public List getAgenciesForStopLocation(StopLocation stop) { return getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); } + @Override + public List getAgenciesForStopLocationsGroup(StopLocationsGroup group) { + return group + .getChildStops() + .stream() + .flatMap(sl -> getAgenciesForStopLocation(sl).stream()) + .distinct() + .toList(); + } + /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index c16b928d2bd..156a3c8dd1a 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -216,6 +216,12 @@ List stopTimesForPatternAtStop( */ List getModesOfStopLocation(StopLocation stop); + /** + * Iterates over all child stops, the routes that visit this stop and return a de-duplicated list + * of their agencies. + */ + List getAgenciesForStopLocationsGroup(StopLocationsGroup group); + /** * Iterates over all routes that visit this stop location and return a de-duplicated list * of their agencies. diff --git a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java index 2a26dc681be..ab3d5c8ae0a 100644 --- a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java +++ b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java @@ -43,6 +43,8 @@ static void setup() { .build(); var transitModel = new TransitModel(stopModel, new Deduplicator()); + transitModel.addTripPattern(RAIL_PATTERN.getId(), RAIL_PATTERN); + transitModel.index(); service = new DefaultTransitService(transitModel) { @@ -74,4 +76,11 @@ void stationModes() { var modes = service.getModesOfStopLocationsGroup(STATION); assertEquals(List.of(RAIL, FERRY, TRAM), modes); } + + @Test + void stopAgencies() { + var stop = RAIL_PATTERN.getStopPattern().getStop(0); + var agencies = service.getAgenciesForStopLocation(stop); + assertEquals("[Agency{F:A1 Agency Test}]", agencies.toString()); + } } From a0e40e354167d886e963c3b2662e942dc8ced5ae Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sun, 21 Jan 2024 22:04:56 +0100 Subject: [PATCH 206/356] Inline code --- .../java/org/opentripplanner/ext/geocoder/LuceneIndex.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index b92b36f5a59..56769db0028 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -191,10 +191,7 @@ private StopCluster toStopCluster(Document document) { var modes = Arrays.asList(document.getValues(MODE)); var agencies = Arrays .stream(document.getValues(AGENCY_IDS)) - .map(id -> { - var fsid = FeedScopedId.parse(id); - return transitService.getAgencyForId(fsid); - }) + .map(id -> transitService.getAgencyForId(FeedScopedId.parse(id))) .filter(Objects::nonNull) .map(StopClusterMapper::toAgency) .toList(); From cb59e3dd2d8982a2efde8d810322a3057910dcf0 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 09:55:25 +0100 Subject: [PATCH 207/356] Make the layers param a List --- .../ext/vectortiles/VectorTilesResource.java | 6 ++++-- .../java/org/opentripplanner/apis/support/TileJson.java | 9 +++++---- .../vectortiles/GraphInspectorVectorTileResource.java | 3 ++- .../org/opentripplanner/apis/support/TileJsonTest.java | 3 ++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index d87c60836de..772db7394f3 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -89,14 +89,16 @@ public TileJson getTileJson( .filter(Predicate.not(Objects::isNull)) .toList(); + List rLayers = Arrays.asList(requestedLayers.split(",")); + var url = serverContext .vectorTileConfig() .basePath() .map(overrideBasePath -> - TileJson.urlFromOverriddenBasePath(uri, headers, overrideBasePath, requestedLayers) + TileJson.urlFromOverriddenBasePath(uri, headers, overrideBasePath, rLayers) ) .orElseGet(() -> - TileJson.urlWithDefaultPath(uri, headers, requestedLayers, ignoreRouterId, "vectorTiles") + TileJson.urlWithDefaultPath(uri, headers, rLayers, ignoreRouterId, "vectorTiles") ); return new TileJson(url, envelope, feedInfos); diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index 09261e295e0..75aabb2b6c6 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -4,6 +4,7 @@ import jakarta.ws.rs.core.UriInfo; import java.io.Serializable; import java.util.Collection; +import java.util.List; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.opentripplanner.framework.io.HttpUtils; @@ -65,7 +66,7 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee public static String urlWithDefaultPath( UriInfo uri, HttpHeaders headers, - String layers, + List layers, String ignoreRouterId, String path ) { @@ -73,7 +74,7 @@ public static String urlWithDefaultPath( HttpUtils.getBaseAddress(uri, headers), ignoreRouterId, path, - layers + String.join(",", layers) ); } @@ -85,14 +86,14 @@ public static String urlFromOverriddenBasePath( UriInfo uri, HttpHeaders headers, String overridePath, - String layers + List layers ) { var strippedPath = StringUtils.stripStart(overridePath, "/"); strippedPath = StringUtils.stripEnd(strippedPath, "/"); return "%s/%s/%s/{z}/{x}/{y}.pbf".formatted( HttpUtils.getBaseAddress(uri, headers), strippedPath, - layers + String.join(",", layers) ); } } diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 666adebbbf7..08008b4fe82 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -102,11 +102,12 @@ public TileJson getTileJson( ) { var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); List feedInfos = feedInfos(); + List rlayer = Arrays.asList(requestedLayers.split(",")); var url = TileJson.urlWithDefaultPath( uri, headers, - requestedLayers, + rlayer, ignoreRouterId, "inspector/vectortile" ); diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index 6b78042bf29..ac3b7bca522 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.List; import org.glassfish.jersey.server.internal.routing.UriRoutingContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -10,7 +11,7 @@ class TileJsonTest { - private static final String LAYERS = "stops,rentalVehicles"; + private static final List LAYERS = List.of("stops", "rentalVehicles"); @ParameterizedTest @ValueSource( From de355dd3683281ea59220b7737b2c98b071e2b60 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 10:11:20 +0100 Subject: [PATCH 208/356] Incorporate review feedback --- doc-templates/sandbox/MapboxVectorTilesApi.md | 14 +++++++------ docs/sandbox/MapboxVectorTilesApi.md | 20 ++++++++++--------- .../vectortiles/VectorTilesConfigDocTest.java | 2 +- ...leRentalServiceDirectoryConfigDocTest.java | 2 +- .../config/routerconfig/VectorTileConfig.java | 6 +++--- .../doc/BuildConfigurationDocTest.java | 2 +- .../generate/doc/ConfigurationDocTest.java | 2 +- .../doc/FlexConfigurationDocTest.java | 2 +- .../generate/doc/GraphQLTutorialDocTest.java | 2 +- .../generate/doc/RouteRequestDocTest.java | 2 +- .../doc/RouterConfigurationDocTest.java | 2 +- .../generate/doc/RoutingModeDocTest.java | 2 +- .../generate/doc/UpdaterConfigDocTest.java | 2 +- .../generate/doc/VehicleParkingDocTest.java | 2 +- 14 files changed, 33 insertions(+), 29 deletions(-) diff --git a/doc-templates/sandbox/MapboxVectorTilesApi.md b/doc-templates/sandbox/MapboxVectorTilesApi.md index 4e3e047fedb..879ea3755d6 100644 --- a/doc-templates/sandbox/MapboxVectorTilesApi.md +++ b/doc-templates/sandbox/MapboxVectorTilesApi.md @@ -3,18 +3,19 @@ ## Contact Info - HSL, Finland -- IBI Arcardis, US +- Arcadis, US ## Documentation This API produces [Mapbox vector tiles](https://docs.mapbox.com/vector-tiles/reference/), which are -used by eg. [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) to show information about +used by [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) and +[`otp-react-redux`](https://github.com/opentripplanner/otp-react-redux) to show information about public transit entities on the map. The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, where `layers` is a comma separated list of layer names from the configuration. -Maplibre/Mapbox GL JS also require a tilejson.json endpoint which is available at +Maplibre/Mapbox GL JS also requires a tilejson.json endpoint which is available at `/otp/routers/{routerId}/vectorTiles/{layers}/tilejson.json`. Translatable fields in the tiles are translated based on the `accept-language` header in requests. @@ -37,7 +38,8 @@ The feature must be configured in `router-config.json` as follows ```JSON { - "vectorTiles": + "vectorTiles": { + "basePath": "/only/configure/if/required", "layers": [ { "name": "stops", @@ -145,8 +147,8 @@ For each layer, the configuration includes: ### Extending -If more generic layers are created for this API, it should be moved out from the sandbox, into the -core code, with potentially leaving specific property mappers in place. +If more generic layers are created for this API, the code should be moved out from the sandbox, into +the core, perhaps potentially leaving specific property mappers in place. #### Creating a new layer diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 92cd867ecce..a58bd3c30f0 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -3,18 +3,19 @@ ## Contact Info - HSL, Finland -- IBI Arcardis, US +- Arcadis, US ## Documentation This API produces [Mapbox vector tiles](https://docs.mapbox.com/vector-tiles/reference/), which are -used by eg. [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) to show information about +used by [Digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) and +[`otp-react-redux`](https://github.com/opentripplanner/otp-react-redux) to show information about public transit entities on the map. The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`, where `layers` is a comma separated list of layer names from the configuration. -Maplibre/Mapbox GL JS also require a tilejson.json endpoint which is available at +Maplibre/Mapbox GL JS also requires a tilejson.json endpoint which is available at `/otp/routers/{routerId}/vectorTiles/{layers}/tilejson.json`. Translatable fields in the tiles are translated based on the `accept-language` header in requests. @@ -37,7 +38,8 @@ The feature must be configured in `router-config.json` as follows ```JSON { - "vectorTiles": + "vectorTiles": { + "basePath": "/only/configure/if/required", "layers": [ { "name": "stops", @@ -168,9 +170,9 @@ The path of the vector tile source URLs in `tilejson.json`. This is useful if you have a proxy setup and rewrite the path that is passed to OTP. -If you don't configure this optional value then the path returned in `tilejson.json` is -`/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you, for example, set -a value of `/otp_test/tiles` then the returned path changes to +If you don't configure this optional value then the path returned in `tilejson.json` is in +the format `/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. +If you, for example, set a value of `/otp_test/tiles` then the returned path changes to `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. The protocol and host are always read from the incoming HTTP request. If you run OTP behind @@ -219,8 +221,8 @@ Currently `Digitransit` is supported for all layer types. ### Extending -If more generic layers are created for this API, it should be moved out from the sandbox, into the -core code, with potentially leaving specific property mappers in place. +If more generic layers are created for this API, the code should be moved out from the sandbox, into +the core, perhaps potentially leaving specific property mappers in place. #### Creating a new layer diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java index e758026d02b..233e3fa3737 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/VectorTilesConfigDocTest.java @@ -32,7 +32,7 @@ public class VectorTilesConfigDocTest { public void updateDoc() { NodeAdapter node = readVectorTiles(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String template = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java b/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java index 51f72c05e3e..4936bb4dd44 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vehiclerentalservicedirectory/generatedoc/VehicleRentalServiceDirectoryConfigDocTest.java @@ -37,7 +37,7 @@ public class VehicleRentalServiceDirectoryConfigDocTest { public void updateConfigurationDoc() { NodeAdapter node = readConfigDefaults(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 0abc046282d..ad2f109ac8e 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -57,9 +57,9 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String """ This is useful if you have a proxy setup and rewrite the path that is passed to OTP. - If you don't configure this optional value then the path returned in `tilejson.json` is - `/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. If you, for example, set - a value of `/otp_test/tiles` then the returned path changes to + If you don't configure this optional value then the path returned in `tilejson.json` is in + the format `/otp/routers/default/vectorTiles/layer1,layer2/{z}/{x}/{x}.pbf`. + If you, for example, set a value of `/otp_test/tiles` then the returned path changes to `/otp_test/tiles/layer1,layer2/{z}/{x}/{x}.pbf`. The protocol and host are always read from the incoming HTTP request. If you run OTP behind diff --git a/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java index 287b0145292..4009a455abe 100644 --- a/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/BuildConfigurationDocTest.java @@ -49,7 +49,7 @@ public class BuildConfigurationDocTest { public void updateBuildConfigurationDoc() { NodeAdapter node = readBuildConfig(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java index 2f972e8300a..19a562d8b3f 100644 --- a/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/ConfigurationDocTest.java @@ -36,7 +36,7 @@ public class ConfigurationDocTest { */ @Test public void updateConfigurationDoc() { - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java index 2b440d7545a..fd2d7092dc5 100644 --- a/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/FlexConfigurationDocTest.java @@ -33,7 +33,7 @@ public class FlexConfigurationDocTest { public void updateFlexDoc() { NodeAdapter node = readFlexConfig(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String template = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java b/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java index bf2b092e092..5e858ff4d61 100644 --- a/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/GraphQLTutorialDocTest.java @@ -33,7 +33,7 @@ public class GraphQLTutorialDocTest { */ @Test public void updateTutorialDoc() throws IOException { - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java index 9a39b3cfa3f..76642db3e5a 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouteRequestDocTest.java @@ -44,7 +44,7 @@ public class RouteRequestDocTest { public void updateRouteRequestConfigurationDoc() { NodeAdapter node = readRoutingDefaults(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java index a48374e755c..90cdd9de975 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RouterConfigurationDocTest.java @@ -51,7 +51,7 @@ public class RouterConfigurationDocTest { public void updateBuildConfigurationDoc() { NodeAdapter node = readRouterConfig(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java b/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java index e08de453630..0c6edc7e16b 100644 --- a/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/RoutingModeDocTest.java @@ -24,7 +24,7 @@ public class RoutingModeDocTest { @Test public void updateDocs() { - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String doc = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java b/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java index 3d0cb547b7a..fa5abca7814 100644 --- a/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/UpdaterConfigDocTest.java @@ -50,7 +50,7 @@ public class UpdaterConfigDocTest { public void updateRouterConfigurationDoc() { NodeAdapter node = readBuildConfig(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String template = readFile(TEMPLATE); String original = readFile(OUT_FILE); diff --git a/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java b/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java index de9b921c27a..abc9ceee806 100644 --- a/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java +++ b/src/test/java/org/opentripplanner/generate/doc/VehicleParkingDocTest.java @@ -33,7 +33,7 @@ public class VehicleParkingDocTest { public void updateVehicleParkingDoc() { NodeAdapter node = readVehicleUpdaters(); - // Read and close inout file (same as output file) + // Read and close input file (same as output file) String template = readFile(TEMPLATE); String original = readFile(OUT_FILE); From b2e14f25fc70c5e775bb972483a5de1ea98b3fc0 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 10:24:20 +0100 Subject: [PATCH 209/356] Add changelog entry --- doc-templates/sandbox/MapboxVectorTilesApi.md | 1 + docs/sandbox/MapboxVectorTilesApi.md | 1 + 2 files changed, 2 insertions(+) diff --git a/doc-templates/sandbox/MapboxVectorTilesApi.md b/doc-templates/sandbox/MapboxVectorTilesApi.md index 879ea3755d6..dfec1ed085a 100644 --- a/doc-templates/sandbox/MapboxVectorTilesApi.md +++ b/doc-templates/sandbox/MapboxVectorTilesApi.md @@ -191,3 +191,4 @@ key, and a function to create the mapper, with a `Graph` object as a parameter, * Added DigitransitRealtime for vehicle rental stations * Changed old vehicle parking mapper to be Stadtnavi * Added a new Digitransit vehicle parking mapper with no real-time information and less fields +- 2024-01-22: Make `basePath` configurable [#5627](https://github.com/opentripplanner/OpenTripPlanner/pull/5627) \ No newline at end of file diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index a58bd3c30f0..8b7af296228 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -265,3 +265,4 @@ key, and a function to create the mapper, with a `Graph` object as a parameter, * Added DigitransitRealtime for vehicle rental stations * Changed old vehicle parking mapper to be Stadtnavi * Added a new Digitransit vehicle parking mapper with no real-time information and less fields +- 2024-01-22: Make `basePath` configurable [#5627](https://github.com/opentripplanner/OpenTripPlanner/pull/5627) \ No newline at end of file From 3beffe3ca8ba21e40f52f3ec49eb043be8f82586 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 22 Jan 2024 12:00:02 +0200 Subject: [PATCH 210/356] Use scooter speed in direct street router --- .../raptoradapter/router/street/DirectStreetRouter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java index 2c6b09c2fb2..6229cbb022c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java @@ -96,6 +96,8 @@ private static double calculateDistanceMaxLimit(RouteRequest request) { distanceLimit = durationLimit * preferences.car().speed(); } else if (mode.includesBiking()) { distanceLimit = durationLimit * preferences.bike().speed(); + } else if (mode.includesScooter()) { + distanceLimit = durationLimit * preferences.scooter().speed(); } else if (mode.includesWalking()) { distanceLimit = durationLimit * preferences.walk().speed(); } else { From 3db40a775d78b35ab25dc97fce16f987a59ac58c Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 22 Jan 2024 12:08:47 +0200 Subject: [PATCH 211/356] Add scooter to some more router-cofig examples --- docs/examples/entur/router-config.json | 9 +++++++++ docs/examples/ibi/atlanta/router-config.json | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index ffdec9ded79..1fc56bd8401 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -36,6 +36,15 @@ "dropOffCost": 30 } }, + "scooter": { + "speed": 5, + "reluctance": 5.0, + "rental": { + "pickupCost": 120, + "dropOffTime": "30s", + "dropOffCost": 30 + } + }, "walk": { "speed": 1.3, "reluctance": 4.0, diff --git a/docs/examples/ibi/atlanta/router-config.json b/docs/examples/ibi/atlanta/router-config.json index 909c164ec43..7d6e7272fcd 100644 --- a/docs/examples/ibi/atlanta/router-config.json +++ b/docs/examples/ibi/atlanta/router-config.json @@ -17,6 +17,17 @@ "pickupCost": 850 } }, + "scooter": { + "triangle": { + "time": 0.3, + "flatness": 0.3, + "safety": 0.4 + }, + "rental": { + "pickupTime": "3m", + "pickupCost": 850 + } + }, "itineraryFilters": { // only show non-transit (ie. walking) when it's at least as good as the transit option "nonTransitGeneralizedCostLimit": "0 + 1.0 x", From 01f1576599a0a653002b19a0419763476c3dd266 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 22 Jan 2024 12:26:42 +0200 Subject: [PATCH 212/356] Add test for scooter in routing preferences --- .../routing/core/RoutingPreferencesTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java index c67d539e902..c3cff43b1a9 100644 --- a/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/core/RoutingPreferencesTest.java @@ -48,6 +48,16 @@ public void copyOfWithBikeChanges() { assertSame(pref.walk(), copy.walk()); } + @Test + public void copyOfWithScooterChanges() { + var pref = new RoutingPreferences(); + var copy = pref.copyOf().withScooter(b -> b.withReluctance(2.5)).build(); + + assertNotSame(pref, copy); + assertNotSame(pref.scooter(), copy.scooter()); + assertSame(pref.walk(), copy.walk()); + } + @Test public void copyOfWithWalkChanges() { var pref = new RoutingPreferences(); From a5fe85e8f1c4fd0b2fee76c09472e63a27df94cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 11:13:03 +0000 Subject: [PATCH 213/356] fix(deps): update dependency com.google.guava:guava to v33 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34f4365b580..72b13f5854b 100644 --- a/pom.xml +++ b/pom.xml @@ -739,7 +739,7 @@ com.google.guava guava - 32.1.3-jre + 33.0.0-jre From 5159265161cf836016aa9825a9eaf930a68c7552 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 22 Jan 2024 13:26:04 +0200 Subject: [PATCH 214/356] Add tests for vehicle rental edge --- .../model/edge/VehicleRentalEdgeTest.java | 138 ++++++++++++++++-- 1 file changed, 124 insertions(+), 14 deletions(-) diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java index 84f5efcc1c5..c490e315933 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java @@ -30,7 +30,7 @@ class VehicleRentalEdgeTest { VehicleRentalPlaceVertex vertex; @Test - void testRentingWithAvailableVehicles() { + void testRentingWithAvailableBikes() { initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3); var s1 = rent(); @@ -49,7 +49,7 @@ void testRentingWithNoAvailableVehicles() { @Test void testRentingWithNoAvailableVehiclesAndNoRealtimeUsage() { - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 0, 3, false, true, false); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 0, 3, false, true, false, false); var s1 = rent(); @@ -76,7 +76,7 @@ void testReturningWithNoAvailableSpaces() { @Test void testReturningWithNoAvailableSpacesAndOverloading() { - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 0, true, true, true); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 0, true, true, true, false); var s1 = rentAndDropOff(); @@ -85,7 +85,7 @@ void testReturningWithNoAvailableSpacesAndOverloading() { @Test void testReturningWithNoAvailableSpacesAndNoRealtimeUsage() { - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 0, false, true, false); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 0, false, true, false, false); var s1 = rentAndDropOff(); @@ -94,7 +94,7 @@ void testReturningWithNoAvailableSpacesAndNoRealtimeUsage() { @Test void testRentingFromClosedStation() { - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 0, true, false, true); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 0, true, false, true, false); var s1 = rent(); @@ -103,13 +103,13 @@ void testRentingFromClosedStation() { @Test void testReturningToClosedStation() { - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, true, true, true); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, true, true, true, false); var s1 = rent(); assertFalse(State.isEmpty(s1)); - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, true, false, true); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, true, false, true, false); var s2 = dropOff(s1[0]); @@ -118,15 +118,78 @@ void testReturningToClosedStation() { @Test void testReturningAndReturningToClosedStationWithNoRealtimeUsage() { - initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, false, true, false); + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, false, true, false, false); var s1 = rentAndDropOff(); assertFalse(State.isEmpty(s1)); } + @Test + void testRentingWithFreeFloatingBicycle() { + initFreeFloatingEdgeAndRequest(StreetMode.BIKE_RENTAL, RentalFormFactor.BICYCLE, false); + + var s1 = rent(); + + assertFalse(State.isEmpty(s1)); + } + + @Test + void testRentingWithFreeFloatingScooter() { + initFreeFloatingEdgeAndRequest(StreetMode.SCOOTER_RENTAL, RentalFormFactor.SCOOTER, false); + + var s1 = rent(); + + assertFalse(State.isEmpty(s1)); + } + + @Test + void testRentingWithFreeFloatingCar() { + initFreeFloatingEdgeAndRequest(StreetMode.CAR_RENTAL, RentalFormFactor.CAR, false); + + var s1 = rent(); + + assertFalse(State.isEmpty(s1)); + } + + @Test + void testBannedBicycleNetworkStation() { + initEdgeAndRequest(StreetMode.BIKE_RENTAL, 3, 3, false, true, true, true); + + var s1 = rent(); + + assertTrue(State.isEmpty(s1)); + } + + @Test + void testBannedBicycleNetworkFreeFloating() { + initFreeFloatingEdgeAndRequest(StreetMode.BIKE_RENTAL, RentalFormFactor.BICYCLE, true); + + var s1 = rent(); + + assertTrue(State.isEmpty(s1)); + } + + @Test + void testBannedScooterNetworkFreeFloating() { + initFreeFloatingEdgeAndRequest(StreetMode.SCOOTER_RENTAL, RentalFormFactor.SCOOTER, true); + + var s1 = rent(); + + assertTrue(State.isEmpty(s1)); + } + + @Test + void testBannedCarNetworkFreeFloating() { + initFreeFloatingEdgeAndRequest(StreetMode.CAR_RENTAL, RentalFormFactor.CAR, true); + + var s1 = rent(); + + assertTrue(State.isEmpty(s1)); + } + private void initEdgeAndRequest(StreetMode mode, int vehicles, int spaces) { - initEdgeAndRequest(mode, vehicles, spaces, false, true, true); + initEdgeAndRequest(mode, vehicles, spaces, false, true, true, false); } @Nested @@ -204,7 +267,8 @@ private void initEdgeAndRequest( int spaces, boolean overloadingAllowed, boolean stationOn, - boolean useRealtime + boolean useRealtime, + boolean banNetwork ) { var station = TestVehicleRentalStationBuilder .of() @@ -218,17 +282,63 @@ private void initEdgeAndRequest( vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(vertex, RentalFormFactor.BICYCLE); + Set bannedNetworks = banNetwork ? Set.of(station.getNetwork()) : Set.of(); + this.request = StreetSearchRequest .of() .withMode(mode) .withPreferences(preferences -> preferences - .withCar(car -> - car.withRental(rental -> rental.withUseAvailabilityInformation(useRealtime)) - ) .withBike(bike -> - bike.withRental(rental -> rental.withUseAvailabilityInformation(useRealtime)) + bike.withRental(rental -> + rental + .withUseAvailabilityInformation(useRealtime) + .withBannedNetworks(bannedNetworks) + ) + ) + .build() + ) + .build(); + } + + private void initFreeFloatingEdgeAndRequest( + StreetMode mode, + RentalFormFactor formFactor, + boolean banNetwork + ) { + var network = "1"; + + VehicleRentalVehicle rentalVehicle = new VehicleRentalVehicle(); + + rentalVehicle.latitude = 1; + rentalVehicle.longitude = 1; + rentalVehicle.id = new FeedScopedId(network, "123"); + rentalVehicle.vehicleType = + new RentalVehicleType( + new FeedScopedId(network, "type"), + "type", + formFactor, + RentalVehicleType.PropulsionType.ELECTRIC, + 100000d + ); + + this.vertex = new VehicleRentalPlaceVertex(rentalVehicle); + + vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(vertex, formFactor); + + Set bannedNetworks = banNetwork ? Set.of(network) : Set.of(); + + this.request = + StreetSearchRequest + .of() + .withMode(mode) + .withPreferences(preferences -> + preferences + .withCar(car -> car.withRental(rental -> rental.withBannedNetworks(bannedNetworks))) + .withBike(bike -> bike.withRental(rental -> rental.withBannedNetworks(bannedNetworks))) + .withScooter(scooter -> + scooter.withRental(rental -> rental.withBannedNetworks(bannedNetworks)) ) .build() ) From 6901346f1f461da4e6b14002b4817ff857685945 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 22 Jan 2024 15:11:38 +0200 Subject: [PATCH 215/356] Add scooter street edge traversal tests --- .../street/model/edge/StreetEdgeTest.java | 220 ++++++++++++++++++ 1 file changed, 220 insertions(+) diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index 60e8cf58952..0435ca16c82 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -21,6 +21,12 @@ import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.util.ElevationUtils; import org.opentripplanner.routing.util.SlopeCosts; +import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; +import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; +import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; +import org.opentripplanner.service.vehiclerental.street.VehicleRentalEdge; +import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; +import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.TurnRestriction; import org.opentripplanner.street.model._data.StreetModelForTest; @@ -33,6 +39,7 @@ import org.opentripplanner.street.search.request.StreetSearchRequestBuilder; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.StateData; +import org.opentripplanner.transit.model.framework.FeedScopedId; public class StreetEdgeTest { @@ -121,6 +128,88 @@ public void testTraverseAsCar() { assertEquals(expectedWeight, s1.getWeight(), 0.0); } + @Test + public void testTraverseFloatingScooter() { + // This test does not depend on the setup method - and can probably be simplified + Coordinate c1 = new Coordinate(-122.575033, 45.456773); + Coordinate c2 = new Coordinate(-122.576668, 45.451426); + + var formFactor = RentalFormFactor.SCOOTER; + var rentalVertex = createRentalVertex(formFactor); + var vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(rentalVertex, formFactor); + + StreetVertex v1 = StreetModelForTest.intersectionVertex("v1", c1.x, c1.y); + StreetVertex v2 = StreetModelForTest.intersectionVertex("v2", c2.x, c2.y); + + var link = StreetVehicleRentalLink.createStreetVehicleRentalLink(rentalVertex, v1); + + GeometryFactory factory = new GeometryFactory(); + LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 }); + + double length = 650.0; + + StreetEdge testStreet = new StreetEdgeBuilder<>() + .withFromVertex(v1) + .withToVertex(v2) + .withGeometry(geometry) + .withName("Test Lane") + .withMeterLength(length) + .withPermission(StreetTraversalPermission.ALL) + .withBack(false) + .buildAndConnect(); + + var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); + + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withSpeed(5))); + + State slowResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withSpeed(10))); + + State fastResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + + // Cost and time should be less when scooter speed is higher. + assertTrue(slowResult.getWeight() > fastResult.getWeight() + DELTA); + assertTrue(slowResult.getElapsedTimeSeconds() > fastResult.getElapsedTimeSeconds()); + + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withReluctance(1))); + State lowReluctanceResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withReluctance(5))); + + State highReluctanceResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + // Cost should be more when reluctance is higher but the time should be the same. + assertTrue(highReluctanceResult.getWeight() > lowReluctanceResult.getWeight() + DELTA); + + assertEquals( + highReluctanceResult.getElapsedTimeSeconds(), + lowReluctanceResult.getElapsedTimeSeconds() + ); + } + @Test public void testModeSetCanTraverse() { StreetEdge e = streetEdge(v1, v2, 1.0, StreetTraversalPermission.ALL); @@ -400,4 +489,135 @@ public void testBikeOptimizeTriangle() { double expectedWeight = timeWeight * 0.33 + slopeWeight * 0.33 + safetyWeight * 0.34; assertEquals(expectedWeight, result.getWeight(), DELTA); } + + @Test + public void testScooterOptimizeTriangle() { + // This test does not depend on the setup method - and can probably be simplified + Coordinate c1 = new Coordinate(-122.575033, 45.456773); + Coordinate c2 = new Coordinate(-122.576668, 45.451426); + + var formFactor = RentalFormFactor.SCOOTER; + + var rentalVertex = createRentalVertex(formFactor); + var vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(rentalVertex, formFactor); + + StreetVertex v1 = StreetModelForTest.intersectionVertex("v1", c1.x, c1.y); + StreetVertex v2 = StreetModelForTest.intersectionVertex("v2", c2.x, c2.y); + + var link = StreetVehicleRentalLink.createStreetVehicleRentalLink(rentalVertex, v1); + + GeometryFactory factory = new GeometryFactory(); + LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 }); + + double length = 650.0; + + StreetEdge testStreet = new StreetEdgeBuilder<>() + .withFromVertex(v1) + .withToVertex(v2) + .withGeometry(geometry) + .withName("Test Lane") + .withMeterLength(length) + .withPermission(StreetTraversalPermission.ALL) + .withBack(false) + // a safe street + .withBicycleSafetyFactor(0.74f) + .buildAndConnect(); + + Coordinate[] profile = new Coordinate[] { + new Coordinate(0, 0), // slope = 0.1 + new Coordinate(length / 2, length / 20.0), + new Coordinate(length, 0), // slope = -0.1 + }; + PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile); + StreetElevationExtensionBuilder + .of(testStreet) + .withElevationProfile(elev) + .withComputed(false) + .build() + .ifPresent(testStreet::setElevationExtension); + + SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, true); + double trueLength = costs.lengthMultiplier * length; + double slopeWorkLength = testStreet.getEffectiveBikeDistanceForWorkCost(); + double slopeSpeedLength = testStreet.getEffectiveBikeDistance(); + + var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); + + request.withPreferences(pref -> + pref + .withScooter(scooter -> + scooter + .withSpeed(SPEED) + .withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE) + .withOptimizeTriangle(it -> it.withTime(1)) + .withReluctance(1) + ) + .withWalk(walk -> walk.withReluctance(1)) + .withCar(car -> car.withReluctance(1)) + ); + + var rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); + var startState = link.traverse(rentedState[0])[0]; + + State result = testStreet.traverse(startState)[0]; + double expectedTimeWeight = slopeSpeedLength / SPEED; + assertEquals(TraverseMode.SCOOTER, result.currentMode()); + assertEquals(expectedTimeWeight, result.getWeight() - startState.getWeight(), DELTA); + + request.withPreferences(p -> + p.withScooter(scooter -> scooter.withOptimizeTriangle(it -> it.withSlope(1))) + ); + rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); + startState = link.traverse(rentedState[0])[0]; + + result = testStreet.traverse(startState)[0]; + double slopeWeight = result.getWeight(); + double expectedSlopeWeight = slopeWorkLength / SPEED; + assertEquals(expectedSlopeWeight, slopeWeight - startState.getWeight(), DELTA); + assertTrue(length * 1.5 / SPEED < slopeWeight); + assertTrue(length * 1.5 * 10 / SPEED > slopeWeight); + + request.withPreferences(p -> + p.withScooter(scooter -> scooter.withOptimizeTriangle(it -> it.withSafety(1))) + ); + rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); + startState = link.traverse(rentedState[0])[0]; + + result = testStreet.traverse(startState)[0]; + double slopeSafety = costs.slopeSafetyCost; + double safetyWeight = result.getWeight(); + double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / SPEED; + assertEquals(expectedSafetyWeight, safetyWeight - startState.getWeight(), DELTA); + } + + private VehicleRentalPlaceVertex createRentalVertex(RentalFormFactor formFactor) { + VehicleRentalVehicle rentalVehicle = new VehicleRentalVehicle(); + + var network = "1"; + rentalVehicle.latitude = -122.575133; + rentalVehicle.longitude = 45.456773; + rentalVehicle.id = new FeedScopedId(network, "123"); + rentalVehicle.vehicleType = + new RentalVehicleType( + new FeedScopedId(network, "type"), + "type", + formFactor, + RentalVehicleType.PropulsionType.ELECTRIC, + 100000d + ); + + return new VehicleRentalPlaceVertex(rentalVehicle); + } + + private State traverseStreetFromRental( + StreetEdge streetEdge, + VehicleRentalEdge rentalEdge, + StreetVehicleRentalLink link, + VehicleRentalPlaceVertex rentalVertex, + StreetSearchRequest request + ) { + var rentedState = rentalEdge.traverse(new State(rentalVertex, request)); + var startState = link.traverse(rentedState[0])[0]; + return streetEdge.traverse(startState)[0]; + } } From 79bd73cd45b91963a77dc9a513bd1186deeb3f08 Mon Sep 17 00:00:00 2001 From: eibakke Date: Mon, 22 Jan 2024 14:18:36 +0100 Subject: [PATCH 216/356] Adds AreaStop layer to new debug frontend --- .../src/components/MapView/MapView.tsx | 2 +- .../apis/vectortiles/DebugStyleSpec.java | 10 +++++++++ .../GraphInspectorVectorTileResource.java | 4 +++- .../apis/vectortiles/model/StyleBuilder.java | 21 +++++++++++++++++++ .../apis/vectortiles/DebugStyleSpecTest.java | 5 +++-- .../apis/vectortiles/style.json | 13 ++++++++++++ 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 51cb39068f8..96b4e820bae 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -75,7 +75,7 @@ export function MapView({ }} // it's unfortunate that you have to list these layers here. // maybe there is a way around it: https://github.com/visgl/react-map-gl/discussions/2343 - interactiveLayerIds={['regular-stop', 'vertex', 'edge', 'link']} + interactiveLayerIds={['regular-stop', 'area-stop', 'vertex', 'edge', 'link']} onClick={showFeaturePropPopup} // put lat/long in URL and pan to it on page reload hash={true} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index f7ca564b149..f45d7d36413 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -52,6 +52,7 @@ public class DebugStyleSpec { static StyleSpec build( VectorSourceLayer regularStops, + VectorSourceLayer areaStops, VectorSourceLayer edges, VectorSourceLayer vertices ) { @@ -112,6 +113,15 @@ static StyleSpec build( .minZoom(15) .maxZoom(MAX_ZOOM) .intiallyHidden(), + StyleBuilder + .ofId("area-stop") + .typeFill() + .vectorSourceLayer(areaStops) + .fillColor(GREEN) + .fillOpacity(0.5f) + .fillOutlineColor(BLACK) + .minZoom(6) + .maxZoom(MAX_ZOOM), StyleBuilder .ofId("regular-stop") .typeCircle() diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 5d0778eae6d..b94482af711 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -1,5 +1,6 @@ package org.opentripplanner.apis.vectortiles; +import static org.opentripplanner.apis.vectortiles.model.LayerType.AreaStop; import static org.opentripplanner.apis.vectortiles.model.LayerType.Edge; import static org.opentripplanner.apis.vectortiles.model.LayerType.GeofencingZones; import static org.opentripplanner.apis.vectortiles.model.LayerType.RegularStop; @@ -47,7 +48,7 @@ public class GraphInspectorVectorTileResource { private static final LayerParams REGULAR_STOPS = new LayerParams("regularStops", RegularStop); - private static final LayerParams AREA_STOPS = new LayerParams("areaStops", LayerType.AreaStop); + private static final LayerParams AREA_STOPS = new LayerParams("areaStops", AreaStop); private static final LayerParams GEOFENCING_ZONES = new LayerParams( "geofencingZones", GeofencingZones @@ -140,6 +141,7 @@ public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) return DebugStyleSpec.build( REGULAR_STOPS.toVectorSourceLayer(stopsSource), + AREA_STOPS.toVectorSourceLayer(stopsSource), EDGES.toVectorSourceLayer(streetSource), VERTICES.toVectorSourceLayer(streetSource) ); diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java index 3b2f36d3156..07efe376968 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/StyleBuilder.java @@ -40,6 +40,7 @@ public enum LayerType { Circle, Line, Raster, + Fill, } private StyleBuilder(String id) { @@ -88,6 +89,11 @@ public StyleBuilder typeLine() { return this; } + public StyleBuilder typeFill() { + type(LayerType.Fill); + return this; + } + private StyleBuilder type(LayerType type) { props.put(TYPE, type.name().toLowerCase()); return this; @@ -132,6 +138,21 @@ public StyleBuilder lineWidth(ZoomDependentNumber zoomStops) { return this; } + public StyleBuilder fillColor(String color) { + paint.put("fill-color", validateColor(color)); + return this; + } + + public StyleBuilder fillOpacity(float opacity) { + paint.put("fill-opacity", opacity); + return this; + } + + public StyleBuilder fillOutlineColor(String color) { + paint.put("fill-outline-color", validateColor(color)); + return this; + } + /** * Hide this layer when the debug client starts. It can be made visible in the UI later. */ diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index befd34a3b38..f2c3ebf49de 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -15,10 +15,11 @@ class DebugStyleSpecTest { @Test void spec() { var vectorSource = new VectorSource("vectorSource", "https://example.com"); - var stops = new VectorSourceLayer(vectorSource, "stops"); + var regularStops = new VectorSourceLayer(vectorSource, "stops"); + var areaStops = new VectorSourceLayer(vectorSource, "stops"); var edges = new VectorSourceLayer(vectorSource, "edges"); var vertices = new VectorSourceLayer(vectorSource, "vertices"); - var spec = DebugStyleSpec.build(stops, edges, vertices); + var spec = DebugStyleSpec.build(regularStops, areaStops, edges, vertices); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RESOURCES.fileToString("style.json"); diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index 9555f32c1e5..e62c3968924 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -141,6 +141,19 @@ "visibility" : "none" } }, + { + "id" : "area-stop", + "type" : "fill", + "source" : "vectorSource", + "source-layer" : "stops", + "minzoom" : 6, + "maxzoom" : 23, + "paint" : { + "fill-color" : "#22DD9E", + "fill-opacity" : 0.5, + "fill-outline-color" : "#140d0e" + } + }, { "id" : "regular-stop", "type" : "circle", From fe388c785c56d9c277e7f70cec89482dce2fb9c3 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 22 Jan 2024 15:35:54 +0200 Subject: [PATCH 217/356] Add test for walking before rental --- .../street/model/edge/StreetEdgeTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index 0435ca16c82..743cfa673ba 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -210,6 +210,33 @@ public void testTraverseFloatingScooter() { ); } + @Test + public void testWalkingBeforeScooter() { + StreetEdge e1 = streetEdgeBuilder(v1, v2, 100.0, StreetTraversalPermission.ALL) + .withCarSpeed(10.0f) + .buildAndConnect(); + + var request = StreetSearchRequest + .copyOf(proto) + .withPreferences(pref -> pref.withWalk(walk -> walk.withReluctance(1))) + .withMode(StreetMode.SCOOTER_RENTAL); + + State s0 = new State(v1, request.build()); + State result = e1.traverse(s0)[0]; + + request.withPreferences(pref -> + pref.withScooter(scooter -> scooter.withReluctance(5).withSpeed(8.5)) + ); + + s0 = new State(v1, request.build()); + var scooterReluctanceResult = e1.traverse(s0)[0]; + + // Scooter preferences shouldn't affect walking when SCOOTER_RENTAL is used as mode + assertEquals(TraverseMode.WALK, result.currentMode()); + assertEquals(result.getWeight(), scooterReluctanceResult.getWeight(), DELTA); + assertEquals(result.getElapsedTimeSeconds(), scooterReluctanceResult.getElapsedTimeSeconds()); + } + @Test public void testModeSetCanTraverse() { StreetEdge e = streetEdge(v1, v2, 1.0, StreetTraversalPermission.ALL); From 696c587e679169437a7c4f17a179f763ed7e0fed Mon Sep 17 00:00:00 2001 From: eibakke Date: Mon, 22 Jan 2024 15:17:17 +0100 Subject: [PATCH 218/356] Makes the ChildLocations of a GroupStop a List instead of a Set. --- .../opentripplanner/transit/model/site/GroupStop.java | 6 +++--- .../transit/model/site/GroupStopBuilder.java | 11 +++++------ .../transit/model/site/StopLocation.java | 3 +-- .../netex/mapping/FlexStopsMapperTest.java | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index d42a1eb121d..c5aa3fa028f 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -1,7 +1,7 @@ package org.opentripplanner.transit.model.site; +import java.util.List; import java.util.Objects; -import java.util.Set; import java.util.function.IntSupplier; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -20,7 +20,7 @@ public class GroupStop implements StopLocation { private final int index; - private final Set stopLocations; + private final List stopLocations; private final I18NString name; private final GeometryCollection geometry; @@ -120,7 +120,7 @@ public boolean isPartOfSameStationAs(StopLocation alternativeStop) { */ @Override @Nonnull - public Set getChildLocations() { + public List getChildLocations() { return stopLocations; } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 0dc22d20512..8873e6ede99 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -1,8 +1,7 @@ package org.opentripplanner.transit.model.site; -import java.util.HashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.function.IntSupplier; import javax.annotation.Nonnull; import org.locationtech.jts.geom.Envelope; @@ -20,7 +19,7 @@ public class GroupStopBuilder extends AbstractEntityBuilder stopLocations = new HashSet<>(); + private List stopLocations = new ArrayList<>(); private GeometryCollection geometry = new GeometryCollection( null, @@ -41,7 +40,7 @@ public class GroupStopBuilder extends AbstractEntityBuilder(original.getChildLocations()); + this.stopLocations = new ArrayList<>(original.getChildLocations()); this.geometry = (GeometryCollection) original.getGeometry(); this.centroid = original.getCoordinate(); } @@ -94,8 +93,8 @@ public GroupStopBuilder addLocation(StopLocation location) { return this; } - public Set stopLocations() { - return Set.copyOf(stopLocations); + public List stopLocations() { + return List.copyOf(stopLocations); } public GeometryCollection geometry() { diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java index 0d42519d663..bff327302af 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java @@ -3,7 +3,6 @@ import java.time.ZoneId; import java.util.Collection; import java.util.List; -import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Geometry; @@ -152,7 +151,7 @@ default StopTransferPriority getPriority() { * Returns the child locations of this location, for example StopLocations within a GroupStop. */ @Nullable - default Set getChildLocations() { + default List getChildLocations() { return null; } diff --git a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java b/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java index e4bba2b729d..3167d64e766 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java +++ b/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java @@ -258,7 +258,7 @@ private void assertGroupStopMapping(FlexibleStopPlace flexibleStopPlace) { assertNotNull(groupStop); // Only one of the stops should be inside the polygon - Set locations = groupStop.getChildLocations(); + List locations = groupStop.getChildLocations(); assertEquals(1, locations.size()); assertEquals(stop1.getId(), locations.stream().findFirst().orElseThrow().getId()); } From e6d30052860ebb0c750419dd7d0e679769939ec8 Mon Sep 17 00:00:00 2001 From: eibakke Date: Mon, 22 Jan 2024 15:56:38 +0100 Subject: [PATCH 219/356] Makes the getEncompassingAreaGeometry method return Optional instead of being nullable. --- .../apis/transmodel/model/stop/QuayType.java | 4 ++-- .../org/opentripplanner/transit/model/site/AreaStop.java | 5 +++-- .../org/opentripplanner/transit/model/site/GroupStop.java | 7 ++++--- .../opentripplanner/transit/model/site/StopLocation.java | 6 +++--- .../opentripplanner/netex/mapping/FlexStopsMapperTest.java | 1 - 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index 6dd9fc5e31c..74a2d0c153e 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -361,9 +361,9 @@ public static GraphQLObjectType create( .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) .dataFetcher(env -> { StopLocation stopLocation = env.getSource(); - return stopLocation.getEncompassingAreaGeometry() == null + return stopLocation.getEncompassingAreaGeometry().isEmpty() ? null - : stopLocation.getEncompassingAreaGeometry().getCoordinates(); + : stopLocation.getEncompassingAreaGeometry().get().getCoordinates(); }) .build() ) diff --git a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java b/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java index a398a7dae1c..41a522f595a 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java @@ -1,6 +1,7 @@ package org.opentripplanner.transit.model.site; import java.util.Objects; +import java.util.Optional; import java.util.function.IntSupplier; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -113,8 +114,8 @@ public Geometry getGeometry() { * Returns the geometry of area that defines the stop, in this case the same as getGeometry. */ @Override - public Geometry getEncompassingAreaGeometry() { - return geometry; + public Optional getEncompassingAreaGeometry() { + return Optional.of(geometry); } @Override diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index c5aa3fa028f..fa23c8999ef 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.function.IntSupplier; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -98,11 +99,11 @@ public Geometry getGeometry() { * will return the geometry of the area. */ @Override - public Geometry getEncompassingAreaGeometry() { + public Optional getEncompassingAreaGeometry() { if (encompassingAreaGeometry == null) { - return geometry; + return Optional.of(geometry); } - return encompassingAreaGeometry; + return Optional.of(encompassingAreaGeometry); } @Override diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java index bff327302af..1e4a1cc4033 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java @@ -3,6 +3,7 @@ import java.time.ZoneId; import java.util.Collection; import java.util.List; +import java.util.Optional; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.locationtech.jts.geom.Geometry; @@ -128,9 +129,8 @@ default String getFirstZoneAsString() { * The geometry of the area that encompasses the bounds of the stop area. If the stop is defined * as a point, this is null. */ - @Nullable - default Geometry getEncompassingAreaGeometry() { - return null; + default Optional getEncompassingAreaGeometry() { + return Optional.empty(); } @Nullable diff --git a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java b/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java index 3167d64e766..7529ae52a34 100644 --- a/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java +++ b/src/test/java/org/opentripplanner/netex/mapping/FlexStopsMapperTest.java @@ -9,7 +9,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Set; import net.opengis.gml._3.AbstractRingPropertyType; import net.opengis.gml._3.DirectPositionListType; import net.opengis.gml._3.LinearRingType; From 5c419e5d7e1a275cb84e0eb1dd700c9271088616 Mon Sep 17 00:00:00 2001 From: Eivind Morris Bakke Date: Tue, 23 Jan 2024 09:12:02 +0100 Subject: [PATCH 220/356] Update src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java Co-authored-by: Leonard Ehrenfried --- .../opentripplanner/apis/transmodel/model/stop/QuayType.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index 74a2d0c153e..cc5a9baf6e4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -361,9 +361,7 @@ public static GraphQLObjectType create( .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) .dataFetcher(env -> { StopLocation stopLocation = env.getSource(); - return stopLocation.getEncompassingAreaGeometry().isEmpty() - ? null - : stopLocation.getEncompassingAreaGeometry().get().getCoordinates(); + return stopLocation.getEncompassingAreaGeometry().map(g -> g.getCoordinates()).orElse(null); }) .build() ) From f446f3e941f18dc2f35e734d563c50e2c5f8502f Mon Sep 17 00:00:00 2001 From: Eivind Morris Bakke Date: Tue, 23 Jan 2024 09:12:22 +0100 Subject: [PATCH 221/356] Update src/main/java/org/opentripplanner/transit/model/site/GroupStop.java Co-authored-by: Leonard Ehrenfried --- .../org/opentripplanner/transit/model/site/GroupStop.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index fa23c8999ef..2ee6e98a2c6 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -100,10 +100,7 @@ public Geometry getGeometry() { */ @Override public Optional getEncompassingAreaGeometry() { - if (encompassingAreaGeometry == null) { - return Optional.of(geometry); - } - return Optional.of(encompassingAreaGeometry); + return Optional.ofNullable(encompassingGeometry).or(Optional.of(geometry)); } @Override From f27c900069089584519f7cb1f629b520cbd06386 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 18:32:28 +0100 Subject: [PATCH 222/356] Introduce new path for Transmodel API --- .../opentripplanner/apis/APIEndpoints.java | 2 + .../apis/transmodel/TransmodelAPI.java | 41 ++++++++----------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/APIEndpoints.java b/src/main/java/org/opentripplanner/apis/APIEndpoints.java index 68f6bda3d3a..959815f1716 100644 --- a/src/main/java/org/opentripplanner/apis/APIEndpoints.java +++ b/src/main/java/org/opentripplanner/apis/APIEndpoints.java @@ -54,6 +54,8 @@ private APIEndpoints() { // scheduled to be removed and only here for backwards compatibility addIfEnabled(GtfsGraphQlApi, GtfsGraphQLAPI.GtfsGraphQLAPIOldPath.class); addIfEnabled(TransmodelGraphQlApi, TransmodelAPI.class); + // scheduled to be removed and only here for backwards compatibility + addIfEnabled(TransmodelGraphQlApi, TransmodelAPI.TransmodelAPIOldPath.class); // Sandbox extension APIs addIfEnabled(ActuatorAPI, ActuatorAPI.class); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java index 6af4ab1953c..5944fb2d2c4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java @@ -6,7 +6,6 @@ import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DefaultValue; -import jakarta.ws.rs.GET; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; @@ -22,6 +21,7 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; +import org.opentripplanner.apis.gtfs.GtfsGraphQLAPI; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.api.request.RouteRequest; @@ -30,11 +30,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// TODO move to org.opentripplanner.api.resource, this is a Jersey resource class - -@Path("/routers/{ignoreRouterId}/transmodel/index") -// It would be nice to get rid of the final /index. -@Produces(MediaType.APPLICATION_JSON) // One @Produces annotation for all endpoints. +@Path("/transmodel/v3") +@Produces(MediaType.APPLICATION_JSON) public class TransmodelAPI { @SuppressWarnings("unused") @@ -48,17 +45,26 @@ public class TransmodelAPI { private final ObjectMapper deserializer = new ObjectMapper(); public TransmodelAPI( - @Context OtpServerRequestContext serverContext, - /** - * @deprecated The support for multiple routers are removed from OTP2. - * See https://github.com/opentripplanner/OpenTripPlanner/issues/2760 - */ - @Deprecated @PathParam("ignoreRouterId") String ignoreRouterId + @Context OtpServerRequestContext serverContext ) { this.serverContext = serverContext; this.index = new TransmodelGraph(schema); } + /** + * This class is only here for backwards-compatibility. It will be removed in the future. + */ + @Path("/routers/{ignoreRouterId}/transmodel/index/graphql") + public static class TransmodelAPIOldPath extends GtfsGraphQLAPI { + + public TransmodelAPIOldPath( + @Context OtpServerRequestContext serverContext, + @PathParam("ignoreRouterId") String ignore + ) { + super(serverContext); + } + } + /** * This method should be called BEFORE the Web-Container is started and load new instances of this * class. This is a hack, and it would be better if the configuration was done more explicit and @@ -77,17 +83,7 @@ public static void setUp( schema = TransmodelGraphQLSchema.create(defaultRouteRequest, gqlUtil); } - /** - * Return 200 when service is loaded. - */ - @GET - @Path("/live") - public Response isAlive() { - return Response.status(Response.Status.NO_CONTENT).build(); - } - @POST - @Path("/graphql") @Consumes(MediaType.APPLICATION_JSON) public Response getGraphQL( HashMap queryParameters, @@ -130,7 +126,6 @@ public Response getGraphQL( } @POST - @Path("/graphql") @Consumes("application/graphql") public Response getGraphQL( String query, From d434086fda090e0fafda3971c245d47d2ff86da6 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 23 Jan 2024 12:45:52 +0100 Subject: [PATCH 223/356] Simplify Transmodel API path --- docs/apis/TransmodelApi.md | 5 ++--- src/client/graphiql/index.html | 2 +- .../opentripplanner/apis/transmodel/TransmodelAPI.java | 8 ++------ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/docs/apis/TransmodelApi.md b/docs/apis/TransmodelApi.md index ce772734276..5a669b8cae5 100644 --- a/docs/apis/TransmodelApi.md +++ b/docs/apis/TransmodelApi.md @@ -13,12 +13,11 @@ Transmodel (NeTEx) with some limitations/simplification. It provides both a rout Entur provides a [GraphQL explorer](https://api.entur.io/graphql-explorer) where you may browse the GraphQL schema and try your own queries. -When running OTP locally the endpoint is available at: `http://localhost:8080/otp/routers/default/transmodel/index/graphql` +When running OTP locally the endpoint is available at: `http://localhost:8080/otp/transmodel/v3` ### Configuration -To turn this API off, add the feature `TransmodelGraphQlApi : false` in _otp-config.json_. - +To turn this API off, add the feature `TransmodelGraphQlApi : false` in `otp-config.json`. ## Changelog - old diff --git a/src/client/graphiql/index.html b/src/client/graphiql/index.html index d96f736b287..0e8d4afd1ea 100644 --- a/src/client/graphiql/index.html +++ b/src/client/graphiql/index.html @@ -153,7 +153,7 @@ let apiFlavor = parameters.flavor || "gtfs"; let urls = { gtfs: '/otp/gtfs/v1', - transmodel: '/otp/routers/default/transmodel/index/graphql' + transmodel: '/otp/transmodel/v3' } let defaultQueries = { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java index 5944fb2d2c4..3df6e1d6a51 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelAPI.java @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; -import org.opentripplanner.apis.gtfs.GtfsGraphQLAPI; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; import org.opentripplanner.apis.transmodel.support.GqlUtil; import org.opentripplanner.routing.api.request.RouteRequest; @@ -34,7 +33,6 @@ @Produces(MediaType.APPLICATION_JSON) public class TransmodelAPI { - @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(TransmodelAPI.class); private static GraphQLSchema schema; @@ -44,9 +42,7 @@ public class TransmodelAPI { private final TransmodelGraph index; private final ObjectMapper deserializer = new ObjectMapper(); - public TransmodelAPI( - @Context OtpServerRequestContext serverContext - ) { + public TransmodelAPI(@Context OtpServerRequestContext serverContext) { this.serverContext = serverContext; this.index = new TransmodelGraph(schema); } @@ -55,7 +51,7 @@ public TransmodelAPI( * This class is only here for backwards-compatibility. It will be removed in the future. */ @Path("/routers/{ignoreRouterId}/transmodel/index/graphql") - public static class TransmodelAPIOldPath extends GtfsGraphQLAPI { + public static class TransmodelAPIOldPath extends TransmodelAPI { public TransmodelAPIOldPath( @Context OtpServerRequestContext serverContext, From da95a92b0602d1a5c3b69bfbdcf8cca9fc1678d3 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 23 Jan 2024 14:21:42 +0200 Subject: [PATCH 224/356] Update src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java Co-authored-by: Leonard Ehrenfried --- .../routing/api/request/preference/ScooterPreferences.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java index 7c139c08730..1d5cf83a54b 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/ScooterPreferences.java @@ -17,7 +17,7 @@ * related to street and transit routing. The values are normalized(rounded) so the class can used * as a cache key. * - * Scooter rental is only supported currently. + * Only Scooter rental is supported currently. *

      * THIS CLASS IS IMMUTABLE AND THREAD-SAFE. */ From cdc84e2943a921b41b8216782b32165c7ea752c2 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 23 Jan 2024 15:12:14 +0200 Subject: [PATCH 225/356] Apply suggestions from code review Co-authored-by: Leonard Ehrenfried --- .../org/opentripplanner/street/model/edge/StreetEdgeTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index 743cfa673ba..a346baf3cb9 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -155,7 +155,6 @@ public void testTraverseFloatingScooter() { .withName("Test Lane") .withMeterLength(length) .withPermission(StreetTraversalPermission.ALL) - .withBack(false) .buildAndConnect(); var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); @@ -545,7 +544,6 @@ public void testScooterOptimizeTriangle() { .withName("Test Lane") .withMeterLength(length) .withPermission(StreetTraversalPermission.ALL) - .withBack(false) // a safe street .withBicycleSafetyFactor(0.74f) .buildAndConnect(); From ae61117ad6ae5f0b1e56cf60b6e0546a0b13b43f Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 23 Jan 2024 15:45:10 +0200 Subject: [PATCH 226/356] Refactor tests --- .../model/_data/StreetModelForTest.java | 16 ++ .../edge/StreetEdgeScooterTraversalTest.java | 249 ++++++++++++++++++ .../street/model/edge/StreetEdgeTest.java | 245 ----------------- .../model/edge/VehicleRentalEdgeTest.java | 21 +- 4 files changed, 268 insertions(+), 263 deletions(-) create mode 100644 src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java diff --git a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java index 1f3dbf8c4c9..cd0ad900311 100644 --- a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java +++ b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java @@ -9,6 +9,9 @@ import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.service.vehiclerental.model.TestFreeFloatingRentalVehicleBuilder; +import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; +import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetEdgeBuilder; @@ -93,4 +96,17 @@ public static StreetEdge streetEdge( ) { return streetEdge(from, to, 1, permissions); } + + public static VehicleRentalPlaceVertex rentalVertex(RentalFormFactor formFactor) { + var rentalVehicleBuilder = TestFreeFloatingRentalVehicleBuilder.of().withLatitude(-122.575133).withLongitude(45.456773); + if (formFactor == RentalFormFactor.SCOOTER) { + rentalVehicleBuilder.withVehicleScooter(); + } else if (formFactor == RentalFormFactor.BICYCLE) { + rentalVehicleBuilder.withVehicleBicycle(); + } else if (formFactor == RentalFormFactor.CAR) { + rentalVehicleBuilder.withVehicleCar(); + } + return new VehicleRentalPlaceVertex(rentalVehicleBuilder.build()); + } + } diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java new file mode 100644 index 00000000000..215b3cb6467 --- /dev/null +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java @@ -0,0 +1,249 @@ +package org.opentripplanner.street.model.edge; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.impl.PackedCoordinateSequence; +import org.opentripplanner.routing.api.request.StreetMode; +import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; +import org.opentripplanner.routing.util.ElevationUtils; +import org.opentripplanner.routing.util.SlopeCosts; +import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; +import org.opentripplanner.service.vehiclerental.street.VehicleRentalEdge; +import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; +import org.opentripplanner.street.model.RentalFormFactor; +import org.opentripplanner.street.model.StreetTraversalPermission; +import org.opentripplanner.street.model._data.StreetModelForTest; +import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.search.TraverseMode; +import org.opentripplanner.street.search.request.StreetSearchRequest; +import org.opentripplanner.street.search.state.State; + +public class StreetEdgeScooterTraversalTest { + + private static final double DELTA = 0.00001; + private static final double SPEED = 6.0; + + @Test + public void testTraverseFloatingScooter() { + // This test does not depend on the setup method - and can probably be simplified + Coordinate c1 = new Coordinate(-122.575033, 45.456773); + Coordinate c2 = new Coordinate(-122.576668, 45.451426); + + var formFactor = RentalFormFactor.SCOOTER; + var rentalVertex = StreetModelForTest.rentalVertex(formFactor); + var vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(rentalVertex, formFactor); + + StreetVertex v1 = StreetModelForTest.intersectionVertex("v1", c1.x, c1.y); + StreetVertex v2 = StreetModelForTest.intersectionVertex("v2", c2.x, c2.y); + + var link = StreetVehicleRentalLink.createStreetVehicleRentalLink(rentalVertex, v1); + + GeometryFactory factory = new GeometryFactory(); + LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 }); + + double length = 650.0; + + StreetEdge testStreet = new StreetEdgeBuilder<>() + .withFromVertex(v1) + .withToVertex(v2) + .withGeometry(geometry) + .withName("Test Lane") + .withMeterLength(length) + .withPermission(StreetTraversalPermission.ALL) + .buildAndConnect(); + + var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); + + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withSpeed(5))); + + State slowResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withSpeed(10))); + + State fastResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + + // Cost and time should be less when scooter speed is higher. + assertTrue(slowResult.getWeight() > fastResult.getWeight() + DELTA); + assertTrue(slowResult.getElapsedTimeSeconds() > fastResult.getElapsedTimeSeconds()); + + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withReluctance(1))); + State lowReluctanceResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + + request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withReluctance(5))); + + State highReluctanceResult = traverseStreetFromRental( + testStreet, + vehicleRentalEdge, + link, + rentalVertex, + request.build() + ); + // Cost should be more when reluctance is higher but the time should be the same. + assertTrue(highReluctanceResult.getWeight() > lowReluctanceResult.getWeight() + DELTA); + + assertEquals( + highReluctanceResult.getElapsedTimeSeconds(), + lowReluctanceResult.getElapsedTimeSeconds() + ); + } + + @Test + public void testWalkingBeforeScooter() { + StreetEdge e1 = StreetModelForTest.streetEdgeBuilder(StreetModelForTest.V1, StreetModelForTest.V2, 100.0, StreetTraversalPermission.ALL) + .withCarSpeed(10.0f) + .buildAndConnect(); + + var request = StreetSearchRequest + .of() + .withPreferences(pref -> pref.withWalk(walk -> walk.withReluctance(1))) + .withMode(StreetMode.SCOOTER_RENTAL); + + State s0 = new State(StreetModelForTest.V1, request.build()); + State result = e1.traverse(s0)[0]; + + request.withPreferences(pref -> + pref.withScooter(scooter -> scooter.withReluctance(5).withSpeed(8.5)) + ); + + s0 = new State(StreetModelForTest.V1, request.build()); + var scooterReluctanceResult = e1.traverse(s0)[0]; + + // Scooter preferences shouldn't affect walking when SCOOTER_RENTAL is used as mode + assertEquals(TraverseMode.WALK, result.currentMode()); + assertEquals(result.getWeight(), scooterReluctanceResult.getWeight(), DELTA); + assertEquals(result.getElapsedTimeSeconds(), scooterReluctanceResult.getElapsedTimeSeconds()); + } + + @Test + public void testScooterOptimizeTriangle() { + // This test does not depend on the setup method - and can probably be simplified + Coordinate c1 = new Coordinate(-122.575033, 45.456773); + Coordinate c2 = new Coordinate(-122.576668, 45.451426); + + var formFactor = RentalFormFactor.SCOOTER; + + var rentalVertex = StreetModelForTest.rentalVertex(formFactor); + var vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(rentalVertex, formFactor); + + StreetVertex v1 = StreetModelForTest.intersectionVertex("v1", c1.x, c1.y); + StreetVertex v2 = StreetModelForTest.intersectionVertex("v2", c2.x, c2.y); + + var link = StreetVehicleRentalLink.createStreetVehicleRentalLink(rentalVertex, v1); + + GeometryFactory factory = new GeometryFactory(); + LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 }); + + double length = 650.0; + + StreetEdge testStreet = new StreetEdgeBuilder<>() + .withFromVertex(v1) + .withToVertex(v2) + .withGeometry(geometry) + .withName("Test Lane") + .withMeterLength(length) + .withPermission(StreetTraversalPermission.ALL) + // a safe street + .withBicycleSafetyFactor(0.74f) + .buildAndConnect(); + + Coordinate[] profile = new Coordinate[] { + new Coordinate(0, 0), // slope = 0.1 + new Coordinate(length / 2, length / 20.0), + new Coordinate(length, 0), // slope = -0.1 + }; + PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile); + StreetElevationExtensionBuilder + .of(testStreet) + .withElevationProfile(elev) + .withComputed(false) + .build() + .ifPresent(testStreet::setElevationExtension); + + SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, true); + double trueLength = costs.lengthMultiplier * length; + double slopeWorkLength = testStreet.getEffectiveBikeDistanceForWorkCost(); + double slopeSpeedLength = testStreet.getEffectiveBikeDistance(); + + var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); + + request.withPreferences(pref -> + pref + .withScooter(scooter -> + scooter + .withSpeed(SPEED) + .withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE) + .withOptimizeTriangle(it -> it.withTime(1)) + .withReluctance(1) + ) + .withWalk(walk -> walk.withReluctance(1)) + .withCar(car -> car.withReluctance(1)) + ); + + var rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); + var startState = link.traverse(rentedState[0])[0]; + + State result = testStreet.traverse(startState)[0]; + double expectedTimeWeight = slopeSpeedLength / SPEED; + assertEquals(TraverseMode.SCOOTER, result.currentMode()); + assertEquals(expectedTimeWeight, result.getWeight() - startState.getWeight(), DELTA); + + request.withPreferences(p -> + p.withScooter(scooter -> scooter.withOptimizeTriangle(it -> it.withSlope(1))) + ); + rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); + startState = link.traverse(rentedState[0])[0]; + + result = testStreet.traverse(startState)[0]; + double slopeWeight = result.getWeight(); + double expectedSlopeWeight = slopeWorkLength / SPEED; + assertEquals(expectedSlopeWeight, slopeWeight - startState.getWeight(), DELTA); + assertTrue(length * 1.5 / SPEED < slopeWeight); + assertTrue(length * 1.5 * 10 / SPEED > slopeWeight); + + request.withPreferences(p -> + p.withScooter(scooter -> scooter.withOptimizeTriangle(it -> it.withSafety(1))) + ); + rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); + startState = link.traverse(rentedState[0])[0]; + + result = testStreet.traverse(startState)[0]; + double slopeSafety = costs.slopeSafetyCost; + double safetyWeight = result.getWeight(); + double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / SPEED; + assertEquals(expectedSafetyWeight, safetyWeight - startState.getWeight(), DELTA); + } + + private State traverseStreetFromRental( + StreetEdge streetEdge, + VehicleRentalEdge rentalEdge, + StreetVehicleRentalLink link, + VehicleRentalPlaceVertex rentalVertex, + StreetSearchRequest request + ) { + var rentedState = rentalEdge.traverse(new State(rentalVertex, request)); + var startState = link.traverse(rentedState[0])[0]; + return streetEdge.traverse(startState)[0]; + } +} diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index a346baf3cb9..60e8cf58952 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -21,12 +21,6 @@ import org.opentripplanner.routing.core.VehicleRoutingOptimizeType; import org.opentripplanner.routing.util.ElevationUtils; import org.opentripplanner.routing.util.SlopeCosts; -import org.opentripplanner.service.vehiclerental.model.RentalVehicleType; -import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; -import org.opentripplanner.service.vehiclerental.street.StreetVehicleRentalLink; -import org.opentripplanner.service.vehiclerental.street.VehicleRentalEdge; -import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; -import org.opentripplanner.street.model.RentalFormFactor; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.TurnRestriction; import org.opentripplanner.street.model._data.StreetModelForTest; @@ -39,7 +33,6 @@ import org.opentripplanner.street.search.request.StreetSearchRequestBuilder; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.StateData; -import org.opentripplanner.transit.model.framework.FeedScopedId; public class StreetEdgeTest { @@ -128,114 +121,6 @@ public void testTraverseAsCar() { assertEquals(expectedWeight, s1.getWeight(), 0.0); } - @Test - public void testTraverseFloatingScooter() { - // This test does not depend on the setup method - and can probably be simplified - Coordinate c1 = new Coordinate(-122.575033, 45.456773); - Coordinate c2 = new Coordinate(-122.576668, 45.451426); - - var formFactor = RentalFormFactor.SCOOTER; - var rentalVertex = createRentalVertex(formFactor); - var vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(rentalVertex, formFactor); - - StreetVertex v1 = StreetModelForTest.intersectionVertex("v1", c1.x, c1.y); - StreetVertex v2 = StreetModelForTest.intersectionVertex("v2", c2.x, c2.y); - - var link = StreetVehicleRentalLink.createStreetVehicleRentalLink(rentalVertex, v1); - - GeometryFactory factory = new GeometryFactory(); - LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 }); - - double length = 650.0; - - StreetEdge testStreet = new StreetEdgeBuilder<>() - .withFromVertex(v1) - .withToVertex(v2) - .withGeometry(geometry) - .withName("Test Lane") - .withMeterLength(length) - .withPermission(StreetTraversalPermission.ALL) - .buildAndConnect(); - - var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); - - request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withSpeed(5))); - - State slowResult = traverseStreetFromRental( - testStreet, - vehicleRentalEdge, - link, - rentalVertex, - request.build() - ); - request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withSpeed(10))); - - State fastResult = traverseStreetFromRental( - testStreet, - vehicleRentalEdge, - link, - rentalVertex, - request.build() - ); - - // Cost and time should be less when scooter speed is higher. - assertTrue(slowResult.getWeight() > fastResult.getWeight() + DELTA); - assertTrue(slowResult.getElapsedTimeSeconds() > fastResult.getElapsedTimeSeconds()); - - request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withReluctance(1))); - State lowReluctanceResult = traverseStreetFromRental( - testStreet, - vehicleRentalEdge, - link, - rentalVertex, - request.build() - ); - - request.withPreferences(pref -> pref.withScooter(scooter -> scooter.withReluctance(5))); - - State highReluctanceResult = traverseStreetFromRental( - testStreet, - vehicleRentalEdge, - link, - rentalVertex, - request.build() - ); - // Cost should be more when reluctance is higher but the time should be the same. - assertTrue(highReluctanceResult.getWeight() > lowReluctanceResult.getWeight() + DELTA); - - assertEquals( - highReluctanceResult.getElapsedTimeSeconds(), - lowReluctanceResult.getElapsedTimeSeconds() - ); - } - - @Test - public void testWalkingBeforeScooter() { - StreetEdge e1 = streetEdgeBuilder(v1, v2, 100.0, StreetTraversalPermission.ALL) - .withCarSpeed(10.0f) - .buildAndConnect(); - - var request = StreetSearchRequest - .copyOf(proto) - .withPreferences(pref -> pref.withWalk(walk -> walk.withReluctance(1))) - .withMode(StreetMode.SCOOTER_RENTAL); - - State s0 = new State(v1, request.build()); - State result = e1.traverse(s0)[0]; - - request.withPreferences(pref -> - pref.withScooter(scooter -> scooter.withReluctance(5).withSpeed(8.5)) - ); - - s0 = new State(v1, request.build()); - var scooterReluctanceResult = e1.traverse(s0)[0]; - - // Scooter preferences shouldn't affect walking when SCOOTER_RENTAL is used as mode - assertEquals(TraverseMode.WALK, result.currentMode()); - assertEquals(result.getWeight(), scooterReluctanceResult.getWeight(), DELTA); - assertEquals(result.getElapsedTimeSeconds(), scooterReluctanceResult.getElapsedTimeSeconds()); - } - @Test public void testModeSetCanTraverse() { StreetEdge e = streetEdge(v1, v2, 1.0, StreetTraversalPermission.ALL); @@ -515,134 +400,4 @@ public void testBikeOptimizeTriangle() { double expectedWeight = timeWeight * 0.33 + slopeWeight * 0.33 + safetyWeight * 0.34; assertEquals(expectedWeight, result.getWeight(), DELTA); } - - @Test - public void testScooterOptimizeTriangle() { - // This test does not depend on the setup method - and can probably be simplified - Coordinate c1 = new Coordinate(-122.575033, 45.456773); - Coordinate c2 = new Coordinate(-122.576668, 45.451426); - - var formFactor = RentalFormFactor.SCOOTER; - - var rentalVertex = createRentalVertex(formFactor); - var vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(rentalVertex, formFactor); - - StreetVertex v1 = StreetModelForTest.intersectionVertex("v1", c1.x, c1.y); - StreetVertex v2 = StreetModelForTest.intersectionVertex("v2", c2.x, c2.y); - - var link = StreetVehicleRentalLink.createStreetVehicleRentalLink(rentalVertex, v1); - - GeometryFactory factory = new GeometryFactory(); - LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 }); - - double length = 650.0; - - StreetEdge testStreet = new StreetEdgeBuilder<>() - .withFromVertex(v1) - .withToVertex(v2) - .withGeometry(geometry) - .withName("Test Lane") - .withMeterLength(length) - .withPermission(StreetTraversalPermission.ALL) - // a safe street - .withBicycleSafetyFactor(0.74f) - .buildAndConnect(); - - Coordinate[] profile = new Coordinate[] { - new Coordinate(0, 0), // slope = 0.1 - new Coordinate(length / 2, length / 20.0), - new Coordinate(length, 0), // slope = -0.1 - }; - PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile); - StreetElevationExtensionBuilder - .of(testStreet) - .withElevationProfile(elev) - .withComputed(false) - .build() - .ifPresent(testStreet::setElevationExtension); - - SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, true); - double trueLength = costs.lengthMultiplier * length; - double slopeWorkLength = testStreet.getEffectiveBikeDistanceForWorkCost(); - double slopeSpeedLength = testStreet.getEffectiveBikeDistance(); - - var request = StreetSearchRequest.of().withMode(StreetMode.SCOOTER_RENTAL); - - request.withPreferences(pref -> - pref - .withScooter(scooter -> - scooter - .withSpeed(SPEED) - .withOptimizeType(VehicleRoutingOptimizeType.TRIANGLE) - .withOptimizeTriangle(it -> it.withTime(1)) - .withReluctance(1) - ) - .withWalk(walk -> walk.withReluctance(1)) - .withCar(car -> car.withReluctance(1)) - ); - - var rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); - var startState = link.traverse(rentedState[0])[0]; - - State result = testStreet.traverse(startState)[0]; - double expectedTimeWeight = slopeSpeedLength / SPEED; - assertEquals(TraverseMode.SCOOTER, result.currentMode()); - assertEquals(expectedTimeWeight, result.getWeight() - startState.getWeight(), DELTA); - - request.withPreferences(p -> - p.withScooter(scooter -> scooter.withOptimizeTriangle(it -> it.withSlope(1))) - ); - rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); - startState = link.traverse(rentedState[0])[0]; - - result = testStreet.traverse(startState)[0]; - double slopeWeight = result.getWeight(); - double expectedSlopeWeight = slopeWorkLength / SPEED; - assertEquals(expectedSlopeWeight, slopeWeight - startState.getWeight(), DELTA); - assertTrue(length * 1.5 / SPEED < slopeWeight); - assertTrue(length * 1.5 * 10 / SPEED > slopeWeight); - - request.withPreferences(p -> - p.withScooter(scooter -> scooter.withOptimizeTriangle(it -> it.withSafety(1))) - ); - rentedState = vehicleRentalEdge.traverse(new State(rentalVertex, request.build())); - startState = link.traverse(rentedState[0])[0]; - - result = testStreet.traverse(startState)[0]; - double slopeSafety = costs.slopeSafetyCost; - double safetyWeight = result.getWeight(); - double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / SPEED; - assertEquals(expectedSafetyWeight, safetyWeight - startState.getWeight(), DELTA); - } - - private VehicleRentalPlaceVertex createRentalVertex(RentalFormFactor formFactor) { - VehicleRentalVehicle rentalVehicle = new VehicleRentalVehicle(); - - var network = "1"; - rentalVehicle.latitude = -122.575133; - rentalVehicle.longitude = 45.456773; - rentalVehicle.id = new FeedScopedId(network, "123"); - rentalVehicle.vehicleType = - new RentalVehicleType( - new FeedScopedId(network, "type"), - "type", - formFactor, - RentalVehicleType.PropulsionType.ELECTRIC, - 100000d - ); - - return new VehicleRentalPlaceVertex(rentalVehicle); - } - - private State traverseStreetFromRental( - StreetEdge streetEdge, - VehicleRentalEdge rentalEdge, - StreetVehicleRentalLink link, - VehicleRentalPlaceVertex rentalVertex, - StreetSearchRequest request - ) { - var rentedState = rentalEdge.traverse(new State(rentalVertex, request)); - var startState = link.traverse(rentedState[0])[0]; - return streetEdge.traverse(startState)[0]; - } } diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java index c490e315933..0e68ea0da78 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java @@ -18,6 +18,7 @@ import org.opentripplanner.service.vehiclerental.street.VehicleRentalEdge; import org.opentripplanner.service.vehiclerental.street.VehicleRentalPlaceVertex; import org.opentripplanner.street.model.RentalFormFactor; +import org.opentripplanner.street.model._data.StreetModelForTest; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.VehicleRentalState; @@ -307,27 +308,11 @@ private void initFreeFloatingEdgeAndRequest( RentalFormFactor formFactor, boolean banNetwork ) { - var network = "1"; - - VehicleRentalVehicle rentalVehicle = new VehicleRentalVehicle(); - - rentalVehicle.latitude = 1; - rentalVehicle.longitude = 1; - rentalVehicle.id = new FeedScopedId(network, "123"); - rentalVehicle.vehicleType = - new RentalVehicleType( - new FeedScopedId(network, "type"), - "type", - formFactor, - RentalVehicleType.PropulsionType.ELECTRIC, - 100000d - ); - - this.vertex = new VehicleRentalPlaceVertex(rentalVehicle); + this.vertex = StreetModelForTest.rentalVertex(formFactor); vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(vertex, formFactor); - Set bannedNetworks = banNetwork ? Set.of(network) : Set.of(); + Set bannedNetworks = banNetwork ? Set.of(this.vertex.getStation().getNetwork()) : Set.of(); this.request = StreetSearchRequest From a3090d2dc3962a81570acbae5365055a771efdd5 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 23 Jan 2024 16:02:06 +0200 Subject: [PATCH 227/356] Fix formatting --- .../street/model/_data/StreetModelForTest.java | 6 ++++-- .../street/model/edge/StreetEdgeScooterTraversalTest.java | 8 +++++++- .../street/model/edge/VehicleRentalEdgeTest.java | 4 +++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java index cd0ad900311..d50c8a74dfc 100644 --- a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java +++ b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java @@ -98,7 +98,10 @@ public static StreetEdge streetEdge( } public static VehicleRentalPlaceVertex rentalVertex(RentalFormFactor formFactor) { - var rentalVehicleBuilder = TestFreeFloatingRentalVehicleBuilder.of().withLatitude(-122.575133).withLongitude(45.456773); + var rentalVehicleBuilder = TestFreeFloatingRentalVehicleBuilder + .of() + .withLatitude(-122.575133) + .withLongitude(45.456773); if (formFactor == RentalFormFactor.SCOOTER) { rentalVehicleBuilder.withVehicleScooter(); } else if (formFactor == RentalFormFactor.BICYCLE) { @@ -108,5 +111,4 @@ public static VehicleRentalPlaceVertex rentalVertex(RentalFormFactor formFactor) } return new VehicleRentalPlaceVertex(rentalVehicleBuilder.build()); } - } diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java index 215b3cb6467..734b1efa2b9 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeScooterTraversalTest.java @@ -111,7 +111,13 @@ public void testTraverseFloatingScooter() { @Test public void testWalkingBeforeScooter() { - StreetEdge e1 = StreetModelForTest.streetEdgeBuilder(StreetModelForTest.V1, StreetModelForTest.V2, 100.0, StreetTraversalPermission.ALL) + StreetEdge e1 = StreetModelForTest + .streetEdgeBuilder( + StreetModelForTest.V1, + StreetModelForTest.V2, + 100.0, + StreetTraversalPermission.ALL + ) .withCarSpeed(10.0f) .buildAndConnect(); diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java index 0e68ea0da78..a3fbfcb018e 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/VehicleRentalEdgeTest.java @@ -312,7 +312,9 @@ private void initFreeFloatingEdgeAndRequest( vehicleRentalEdge = VehicleRentalEdge.createVehicleRentalEdge(vertex, formFactor); - Set bannedNetworks = banNetwork ? Set.of(this.vertex.getStation().getNetwork()) : Set.of(); + Set bannedNetworks = banNetwork + ? Set.of(this.vertex.getStation().getNetwork()) + : Set.of(); this.request = StreetSearchRequest From 81c8fcd74ce1606be8f7142f5c581e3d0e86c138 Mon Sep 17 00:00:00 2001 From: eibakke Date: Tue, 23 Jan 2024 15:54:54 +0100 Subject: [PATCH 228/356] Makes the getEncompassingAreaGeometry in StopLocation return an Optional in order to allow returns of both GeometryCollection and Geometry. --- .../apis/transmodel/model/stop/QuayType.java | 6 +++++- .../org/opentripplanner/transit/model/site/GroupStop.java | 4 ++-- .../opentripplanner/transit/model/site/StopLocation.java | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index cc5a9baf6e4..a8390e23197 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -15,6 +15,7 @@ import java.util.Collection; import java.util.Objects; import java.util.Optional; +import org.locationtech.jts.geom.Geometry; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.model.plan.JourneyWhiteListed; import org.opentripplanner.apis.transmodel.model.scalars.GeoJSONCoordinatesScalar; @@ -361,7 +362,10 @@ public static GraphQLObjectType create( .type(GeoJSONCoordinatesScalar.getGraphQGeoJSONCoordinatesScalar()) .dataFetcher(env -> { StopLocation stopLocation = env.getSource(); - return stopLocation.getEncompassingAreaGeometry().map(g -> g.getCoordinates()).orElse(null); + return stopLocation + .getEncompassingAreaGeometry() + .map(Geometry::getCoordinates) + .orElse(null); }) .build() ) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index 2ee6e98a2c6..20a5afb4070 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -99,8 +99,8 @@ public Geometry getGeometry() { * will return the geometry of the area. */ @Override - public Optional getEncompassingAreaGeometry() { - return Optional.ofNullable(encompassingGeometry).or(Optional.of(geometry)); + public Optional getEncompassingAreaGeometry() { + return Optional.ofNullable(encompassingAreaGeometry).or(() -> Optional.of(geometry)); } @Override diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java index 1e4a1cc4033..1f2ca33d460 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java @@ -129,7 +129,7 @@ default String getFirstZoneAsString() { * The geometry of the area that encompasses the bounds of the stop area. If the stop is defined * as a point, this is null. */ - default Optional getEncompassingAreaGeometry() { + default Optional getEncompassingAreaGeometry() { return Optional.empty(); } From 31a621b3d71b4db00a83768e4b7526f1709a263d Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 23 Jan 2024 15:19:23 +0100 Subject: [PATCH 229/356] Fix: Make pass-trough override transit-group-priority --- .../transit/mappers/RaptorRequestMapper.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java index 5f3b4b13746..c46e5a907cc 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java @@ -119,12 +119,14 @@ private RaptorRequest doMap() { builder.withMultiCriteria(mcBuilder -> { var pt = preferences.transit(); var r = pt.raptor(); - if (!pt.relaxTransitGroupPriority().isNormal()) { - mcBuilder.withTransitPriorityCalculator(TransitGroupPriority32n.priorityCalculator()); - mcBuilder.withRelaxC1(mapRelaxCost(pt.relaxTransitGroupPriority())); - } else { + + // Note! If a pass-through-point exists, then the transit-group-priority feature is disabled + if (!request.getPassThroughPoints().isEmpty()) { mcBuilder.withPassThroughPoints(mapPassThroughPoints()); r.relaxGeneralizedCostAtDestination().ifPresent(mcBuilder::withRelaxCostAtDestination); + } else if (!pt.relaxTransitGroupPriority().isNormal()) { + mcBuilder.withTransitPriorityCalculator(TransitGroupPriority32n.priorityCalculator()); + mcBuilder.withRelaxC1(mapRelaxCost(pt.relaxTransitGroupPriority())); } }); From 3a37e98b8c0bec5af50480096c84997ff9a5d18c Mon Sep 17 00:00:00 2001 From: eibakke Date: Tue, 23 Jan 2024 16:08:50 +0100 Subject: [PATCH 230/356] Introduces the StopType Enum and StopTypeMapper for the Transmodel GraphQL API. --- .../apis/transmodel/model/stop/QuayType.java | 2 +- .../transmodel/model/stop/StopTypeMapper.java | 15 +++++++++++++++ .../transit/model/site/AreaStop.java | 4 ++-- .../transit/model/site/GroupStop.java | 4 ++-- .../transit/model/site/RegularStop.java | 4 ++-- .../transit/model/site/StopLocation.java | 2 +- .../transit/model/site/StopType.java | 7 +++++++ .../apis/transmodel/schema.graphql | 8 +++++++- 8 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java create mode 100644 src/main/java/org/opentripplanner/transit/model/site/StopType.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index a8390e23197..46b09956eb2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -350,7 +350,7 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("stopType") - .type(Scalars.GraphQLString) + .type(StopTypeMapper.STOP_TYPE) .dataFetcher(env -> ((StopLocation) env.getSource()).getStopType()) .build() ) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java new file mode 100644 index 00000000000..4725f5ac4f9 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java @@ -0,0 +1,15 @@ +package org.opentripplanner.apis.transmodel.model.stop; + +import graphql.schema.GraphQLEnumType; +import org.opentripplanner.transit.model.site.StopType; + +public class StopTypeMapper { + + public static final GraphQLEnumType STOP_TYPE = GraphQLEnumType + .newEnum() + .name("StopType") + .value("regular", StopType.REGULAR) + .value("flexible_area", StopType.FLEXIBLE_AREA) + .value("flexible_group", StopType.FLEXIBLE_GROUP) + .build(); +} diff --git a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java b/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java index 41a522f595a..35576e0c42f 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/AreaStop.java @@ -87,8 +87,8 @@ public I18NString getUrl() { @Nonnull @Override - public String getStopType() { - return "flexible_area"; + public StopType getStopType() { + return StopType.FLEXIBLE_AREA; } @Override diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index 20a5afb4070..edee00e27e1 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -66,8 +66,8 @@ public I18NString getUrl() { @Override @Nonnull - public String getStopType() { - return "flexible_group"; + public StopType getStopType() { + return StopType.FLEXIBLE_GROUP; } @Override diff --git a/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java b/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java index 88fafab17e8..4c1638e7bae 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/RegularStop.java @@ -83,8 +83,8 @@ public I18NString getUrl() { @Nonnull @Override - public String getStopType() { - return "regular"; + public StopType getStopType() { + return StopType.REGULAR; } @Override diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java index 1f2ca33d460..a3cbd1a8014 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocation.java @@ -45,7 +45,7 @@ public interface StopLocation extends LogInfo { I18NString getUrl(); @Nonnull - String getStopType(); + StopType getStopType(); /** * Short text or a number that identifies the location for riders. These codes are often used in diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopType.java b/src/main/java/org/opentripplanner/transit/model/site/StopType.java new file mode 100644 index 00000000000..29a859fdd1c --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/site/StopType.java @@ -0,0 +1,7 @@ +package org.opentripplanner.transit.model.site; + +public enum StopType { + REGULAR, + FLEXIBLE_AREA, + FLEXIBLE_GROUP, +} diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 25cf95ca2f9..f0053e2a806 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -600,7 +600,7 @@ type Quay implements PlaceInterface { situations: [PtSituationElement!]! "The stop place to which this quay belongs to." stopPlace: StopPlace - stopType: String + stopType: StopType tariffZones: [TariffZone]! timeZone: String "Whether this quay is suitable for wheelchair boarding." @@ -1697,6 +1697,12 @@ enum StopCondition { startPoint } +enum StopType { + flexible_area + flexible_group + regular +} + enum StreetMode { "Bike only. This can be used as access/egress, but transfers will still be walk only." bicycle From 65e47e61ce7d998d7fddcf4c099df88871176a88 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 23 Jan 2024 17:04:38 +0100 Subject: [PATCH 231/356] test: Add unit test for pass-through-points in RaptorRequestMapper --- .../raptoradapter/router/TransitRouter.java | 2 +- .../transit/mappers/RaptorRequestMapper.java | 27 ++++---- .../mappers/RaptorRequestMapperTest.java | 61 +++++++++++++++++++ 3 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java index 1b5c836c832..c9e7f92263f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java @@ -121,7 +121,7 @@ private TransitRouterResult route() { ); // Prepare transit search - var raptorRequest = RaptorRequestMapper.mapRequest( + var raptorRequest = RaptorRequestMapper.mapRequest( request, transitSearchTimeZero, serverContext.raptorConfig().isMultiThreaded(), diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java index c46e5a907cc..91547b1f62f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapper.java @@ -12,6 +12,7 @@ import org.opentripplanner.raptor.api.model.GeneralizedCostRelaxFunction; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; +import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.raptor.api.model.RelaxFunction; import org.opentripplanner.raptor.api.request.DebugRequestBuilder; import org.opentripplanner.raptor.api.request.Optimization; @@ -28,7 +29,7 @@ import org.opentripplanner.routing.api.request.framework.CostLinearFunction; import org.opentripplanner.transit.model.site.StopLocation; -public class RaptorRequestMapper { +public class RaptorRequestMapper { private final RouteRequest request; private final Collection accessPaths; @@ -56,7 +57,7 @@ private RaptorRequestMapper( this.meterRegistry = meterRegistry; } - public static RaptorRequest mapRequest( + public static RaptorRequest mapRequest( RouteRequest request, ZonedDateTime transitSearchTimeZero, boolean isMultiThreaded, @@ -65,7 +66,7 @@ public static RaptorRequest mapRequest( Duration searchWindowAccessSlack, MeterRegistry meterRegistry ) { - return new RaptorRequestMapper( + return new RaptorRequestMapper( request, isMultiThreaded, accessPaths, @@ -77,8 +78,8 @@ public static RaptorRequest mapRequest( .doMap(); } - private RaptorRequest doMap() { - var builder = new RaptorRequestBuilder(); + private RaptorRequest doMap() { + var builder = new RaptorRequestBuilder(); var searchParams = builder.searchParams(); var preferences = request.preferences(); @@ -176,13 +177,15 @@ private RaptorRequest doMap() { } // Add this last, it depends on generating an alias from the set values - builder.performanceTimers( - new PerformanceTimersForRaptor( - builder.generateAlias(), - preferences.system().tags(), - meterRegistry - ) - ); + if (meterRegistry != null) { + builder.performanceTimers( + new PerformanceTimersForRaptor( + builder.generateAlias(), + preferences.system().tags(), + meterRegistry + ) + ); + } return builder.build(); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java index 11c59030180..89348be5c89 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/RaptorRequestMapperTest.java @@ -1,15 +1,33 @@ package org.opentripplanner.routing.algorithm.raptoradapter.transit.mappers; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.time.Duration; +import java.time.ZonedDateTime; import java.util.List; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.raptor._data.transit.TestAccessEgress; +import org.opentripplanner.raptor._data.transit.TestTripSchedule; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; +import org.opentripplanner.raptor.api.request.RaptorRequest; +import org.opentripplanner.routing.api.request.PassThroughPoint; +import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model.site.StopLocation; class RaptorRequestMapperTest { + private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final StopLocation STOP_A = TEST_MODEL.stop("Stop:A").build(); + private static final List ACCESS = List.of(TestAccessEgress.walk(12, 45)); + private static final List EGRESS = List.of(TestAccessEgress.walk(144, 54)); + private static final Duration D0s = Duration.ofSeconds(0); + private static final CostLinearFunction R1 = CostLinearFunction.of("50 + 1.0x"); private static final CostLinearFunction R2 = CostLinearFunction.of("0 + 1.5x"); private static final CostLinearFunction R3 = CostLinearFunction.of("30 + 2.0x"); @@ -33,4 +51,47 @@ void mapRelaxCost(CostLinearFunction input, int cost, int expected) { var calcCost = RaptorRequestMapper.mapRelaxCost(input); assertEquals(expected, calcCost.relax(cost)); } + + @Test + void testPassThroughPoints() { + var req = new RouteRequest(); + + req.setPassThroughPoints(List.of(new PassThroughPoint(List.of(STOP_A), "Via A"))); + + var result = map(req); + + assertTrue(result.multiCriteria().hasPassThroughPoints()); + assertEquals( + "[(Via A, stops: " + STOP_A.getIndex() + ")]", + result.multiCriteria().passThroughPoints().toString() + ); + } + + @Test + void testPassThroughPointsTurnTransitGroupPriorityOff() { + var req = new RouteRequest(); + + // Set pass-through and relax transit-group-priority + req.setPassThroughPoints(List.of(new PassThroughPoint(List.of(STOP_A), "Via A"))); + req.withPreferences(p -> + p.withTransit(t -> t.withRelaxTransitGroupPriority(CostLinearFunction.of("30m + 1.2t"))) + ); + + var result = map(req); + + // transit-group-priority CANNOT be used with pass-through and is turned off... + assertTrue(result.multiCriteria().transitPriorityCalculator().isEmpty()); + } + + private static RaptorRequest map(RouteRequest request) { + return RaptorRequestMapper.mapRequest( + request, + ZonedDateTime.now(), + false, + ACCESS, + EGRESS, + D0s, + null + ); + } } From 4e14a55c4454e8dced9e2c158ab3929c3f1e9ca3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 01:46:02 +0000 Subject: [PATCH 232/356] fix(deps): update geotools.version to v30.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34f4365b580..681d3b015a0 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 137 - 30.1 + 30.2 2.50 2.16.1 3.1.5 From d31a84e986ef4ef25aa8fee84092b41de36a3ea7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 24 Jan 2024 10:21:20 +0100 Subject: [PATCH 233/356] Update docs/apis/TransmodelApi.md Co-authored-by: Thomas Gran --- docs/apis/TransmodelApi.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/apis/TransmodelApi.md b/docs/apis/TransmodelApi.md index 5a669b8cae5..c6d3a16a99c 100644 --- a/docs/apis/TransmodelApi.md +++ b/docs/apis/TransmodelApi.md @@ -15,6 +15,8 @@ queries. When running OTP locally the endpoint is available at: `http://localhost:8080/otp/transmodel/v3` +Note! Version `v1` and `v2` does not exist in the main OTP git repository, but in the (Entur fork)[https://github.com/entur/OpenTripPlanner] from which this code originate from. + ### Configuration To turn this API off, add the feature `TransmodelGraphQlApi : false` in `otp-config.json`. From 6d0780928917705dbccf4659e050a30bfcc8be35 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 24 Jan 2024 10:22:59 +0100 Subject: [PATCH 234/356] Improve documentation --- docs/apis/TransmodelApi.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/apis/TransmodelApi.md b/docs/apis/TransmodelApi.md index c6d3a16a99c..6f99847798a 100644 --- a/docs/apis/TransmodelApi.md +++ b/docs/apis/TransmodelApi.md @@ -15,7 +15,8 @@ queries. When running OTP locally the endpoint is available at: `http://localhost:8080/otp/transmodel/v3` -Note! Version `v1` and `v2` does not exist in the main OTP git repository, but in the (Entur fork)[https://github.com/entur/OpenTripPlanner] from which this code originate from. +**Note!** Versions `v1` and `v2` do not exist in the main OTP git repository, but in +the [Entur fork](https://github.com/entur/OpenTripPlanner) from which this code originates from. ### Configuration From 6a087d15e2baf48bac7038dba8d6c81eacc2e5e1 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 24 Jan 2024 10:53:24 +0100 Subject: [PATCH 235/356] Clarify documentation --- docs/RouterConfiguration.md | 2 +- docs/sandbox/MapboxVectorTilesApi.md | 4 ++++ .../standalone/config/routerconfig/VectorTileConfig.java | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index be4be9d34ff..62fb5d9617a 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -67,7 +67,7 @@ A full list of them can be found in the [RouteRequest](RouteRequest.md). |    [hideFeedId](#transmodelApi_hideFeedId) | `boolean` | Hide the FeedId in all API output, and add it to input. | *Optional* | `false` | na | |    [tracingHeaderTags](#transmodelApi_tracingHeaderTags) | `string[]` | Used to group requests when monitoring OTP. | *Optional* | | na | | [updaters](UpdaterConfig.md) | `object[]` | Configuration for the updaters that import various types of data into OTP. | *Optional* | | 1.5 | -| [vectorTiles](sandbox/MapboxVectorTilesApi.md) | `object` | TODO: Add short summary. | *Optional* | | na | +| [vectorTiles](sandbox/MapboxVectorTilesApi.md) | `object` | Vector tile configuration | *Optional* | | na | | [vehicleRentalServiceDirectory](sandbox/VehicleRentalServiceDirectory.md) | `object` | Configuration for the vehicle rental service directory. | *Optional* | | 2.0 | diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 8b7af296228..da9fd1120e1 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -179,6 +179,10 @@ The protocol and host are always read from the incoming HTTP request. If you run a proxy then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP return the protocol and host for the original request and not the proxied one. +**Note:** This does _not_ change the path that OTP itself serves the tiles or `tilejson.json` +responses but simply changes the URLs listed in `tilejson.json`. The rewriting of the path +is expected to be handled by a proxy. +

      layers

      diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index ad2f109ac8e..6f7d6967ce8 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -42,7 +42,7 @@ public Optional basePath() { } public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String paramName) { - var root = node.of(paramName).asObject(); + var root = node.of(paramName).summary("Vector tile configuration").asObject(); return new VectorTileConfig( root .of("layers") @@ -65,6 +65,10 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String The protocol and host are always read from the incoming HTTP request. If you run OTP behind a proxy then make sure to set the headers `X-Forwarded-Proto` and `X-Forwarded-Host` to make OTP return the protocol and host for the original request and not the proxied one. + + **Note:** This does _not_ change the path that OTP itself serves the tiles or `tilejson.json` + responses but simply changes the URLs listed in `tilejson.json`. The rewriting of the path + is expected to be handled by a proxy. """ ) .asString(DEFAULT.basePath) From 264ab35db7ccb53db042ea0256f1f2f09a6f73bd Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 24 Jan 2024 16:11:57 +0100 Subject: [PATCH 236/356] Adds documentation to the new enums and mapper. --- .../transmodel/model/stop/StopTypeMapper.java | 17 ++++++++++++++--- .../transit/model/site/StopType.java | 12 ++++++++++++ .../apis/transmodel/schema.graphql | 3 +++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java index 4725f5ac4f9..bde676bec59 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java @@ -3,13 +3,24 @@ import graphql.schema.GraphQLEnumType; import org.opentripplanner.transit.model.site.StopType; +/** + * Maps the StopType enum to a GraphQL enum. + */ public class StopTypeMapper { public static final GraphQLEnumType STOP_TYPE = GraphQLEnumType .newEnum() .name("StopType") - .value("regular", StopType.REGULAR) - .value("flexible_area", StopType.FLEXIBLE_AREA) - .value("flexible_group", StopType.FLEXIBLE_GROUP) + .value("regular", StopType.REGULAR, "A regular stop defined geographically as a point.") + .value( + "flexible_area", + StopType.FLEXIBLE_AREA, + "Boarding and alighting is allowed anywhere within the geographic area of this stop." + ) + .value( + "flexible_group", + StopType.FLEXIBLE_GROUP, + "A stop that consists of multiple other stops, area or regular." + ) .build(); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopType.java b/src/main/java/org/opentripplanner/transit/model/site/StopType.java index 29a859fdd1c..69f11bb6b39 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopType.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopType.java @@ -1,7 +1,19 @@ package org.opentripplanner.transit.model.site; +/** + * The type of a stop location. + */ public enum StopType { + /** + * A regular stop defined geographically as a point. + */ REGULAR, + /** + * Boarding and alighting is allowed anywhere within the geographic area of this stop. + */ FLEXIBLE_AREA, + /** + * A stop that consists of multiple other stops, area or regular. + */ FLEXIBLE_GROUP, } diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index f0053e2a806..a1e971d66ef 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -1698,8 +1698,11 @@ enum StopCondition { } enum StopType { + "Boarding and alighting is allowed anywhere within the geographic area of this stop." flexible_area + "A stop that consists of multiple other stops, area or regular." flexible_group + "A regular stop defined geographically as a point." regular } From 47e2b94fb58e00535b9f567b9e5aa1ef535bbd2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:38:46 +0000 Subject: [PATCH 237/356] fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34f4365b580..06f002ff5c0 100644 --- a/pom.xml +++ b/pom.xml @@ -876,7 +876,7 @@ org.apache.httpcomponents.client5 httpclient5 - 5.3 + 5.3.1 commons-cli From d72ebf043c02d1a68591ae2bf59ebbad150aa49d Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Wed, 24 Jan 2024 19:07:39 +0000 Subject: [PATCH 238/356] Add changelog entry for #5613 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 6f27f60d947..4cfb1176773 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -78,6 +78,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581) - Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582) - Revert REST API spelling change of real-time [#5629](https://github.com/opentripplanner/OpenTripPlanner/pull/5629) +- Remove `FareComponent` [#5613](https://github.com/opentripplanner/OpenTripPlanner/pull/5613) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From d0c552bffc56642a2dc9c279780875378325bf04 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Wed, 24 Jan 2024 19:07:57 +0000 Subject: [PATCH 239/356] Bump serialization version id for #5613 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34f4365b580..3f7fc0dd2bb 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 137 + 138 30.1 2.50 From a437720287650f5408aba4d6abeb226feeb38418 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 16 Jan 2024 23:51:14 +0100 Subject: [PATCH 240/356] Remove 'fare' --- ...reInFreeTransferWindowFareServiceTest.java | 5 --- .../ext/fares/impl/DefaultFareService.java | 45 ++----------------- ...stFareInFreeTransferWindowFareService.java | 2 - .../ext/restapi/mapping/FareMapper.java | 18 +------- .../apis/gtfs/datafetchers/ItineraryImpl.java | 12 +---- 5 files changed, 6 insertions(+), 76 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java index 5664dcc765d..5d7615c49e3 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java @@ -18,7 +18,6 @@ import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.fares.FareService; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; @@ -43,18 +42,14 @@ public void canCalculateFare( Money expectedFare ) { var fares = fareService.calculateFares(i); - assertEquals(expectedFare, fares.getFare(FareType.regular)); assertFalse(fares.getItineraryProducts().isEmpty()); - for (var type : fares.getFareTypes()) { var prices = fares .getItineraryProducts() .stream() - .filter(fp -> fp.name().equals(type.name())) .map(FareProduct::price) .toList(); assertEquals(List.of(expectedFare), prices); - } } private static List createTestCases() { diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index 0bc4408b635..9f3bb2094b0 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -122,9 +122,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { boolean hasFare = false; for (FareType fareType : fareRulesPerType.keySet()) { final Multimap fareProducts = LinkedHashMultimap.create(); - List fares = new ArrayList<>(); - boolean legWithoutRulesFound = false; - boolean legsWithoutMatchingRulesFound = false; + List itineraryProducts = new ArrayList<>(); for (String feedId : fareLegsByFeed.keySet()) { ItineraryFares currentFare = ItineraryFares.empty(); var fareRules = fareRulesForFeed(fareType, feedId); @@ -140,57 +138,23 @@ public ItineraryFares calculateFares(Itinerary itinerary) { fareRules ); - if (!feedHasFare) { - legsWithoutMatchingRulesFound = true; - } hasFare = feedHasFare || hasFare; // Other feeds might still have fare for some legs fareProducts.putAll(currentFare.getLegProducts()); - fare.addFare(fareType, currentFare.getFare(fareType)); - - fares.add(currentFare.getFare(fareType)); - - // If all the legs are from one feed, consider itinerary products - if (fareLegs.equals(fareLegsByFeed.get(feedId))) { - currentFare - .getFareTypes() - .forEach(type -> { - var money = currentFare.getFare(type); - var fareProduct = FareProduct - .of(new FeedScopedId(feedId, type.name()), type.name(), money) - .build(); - fare.addItineraryProducts(List.of(fareProduct)); - }); - } + itineraryProducts.addAll(currentFare.getItineraryProducts()); + } else { - legWithoutRulesFound = true; } } fare.addFareProductUses(fareProducts); + fare.addItineraryProducts(itineraryProducts); // No fares will be discovered after this point if (!hasFare) { continue; } - // Accumulate the final price of the fare or indicate that no final fare could be found - if (legWithoutRulesFound || legsWithoutMatchingRulesFound) { - fare.addFare( - fareType, - Money.ofFractionalAmount(fares.get(0).currency(), UNKNOWN_FARE_PRICE) - ); - } else { - fare.addFare( - fareType, - fares - .stream() - .reduce( - Money.ofFractionalAmount(fare.getFare(fareType).currency(), 0), - (r1, r2) -> r1.plus(r2) - ) - ); - } } return hasFare ? fare : null; } @@ -292,7 +256,6 @@ protected boolean populateFare( } var amount = r.resultTable[0][legs.size() - 1]; - fare.addFare(fareType, Money.ofFractionalAmount(currency, amount)); fare.addFareProductUses(fareProductUses); return count > 0; } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java index 1f1c112e63c..cbb50fd57b9 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java @@ -85,7 +85,6 @@ protected boolean populateFare( currentTransferWindowCost = Money.max(currentTransferWindowCost, rideCost.orElse(zero)); } cost = cost.plus(currentTransferWindowCost); - fare.addFare(fareType, cost); var fp = new FareProduct( new FeedScopedId("fares", fareType.name()), fareType.name(), @@ -95,7 +94,6 @@ protected boolean populateFare( null ); fare.addItineraryProducts(List.of(fp)); - fare.addFare(fareType, cost); return cost.greaterThan(zero); } diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java index e8582607ce5..0e9f452b5c1 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/FareMapper.java @@ -1,14 +1,11 @@ package org.opentripplanner.ext.restapi.mapping; import com.google.common.collect.Multimap; -import java.util.AbstractMap.SimpleEntry; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Map.Entry; import java.util.Optional; -import java.util.stream.Collectors; import javax.annotation.Nullable; import org.opentripplanner.ext.restapi.model.ApiCurrency; import org.opentripplanner.ext.restapi.model.ApiFareProduct; @@ -19,7 +16,6 @@ import org.opentripplanner.model.fare.FareMedium; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.model.fare.FareProductUse; -import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.fare.RiderCategory; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; @@ -35,10 +31,9 @@ public FareMapper(Locale locale) { public ApiItineraryFares mapFare(Itinerary itinerary) { var fares = itinerary.getFares(); - Map apiFare = toApiMoneys(fares); return new ApiItineraryFares( - apiFare, + Map.of(), Map.of(), toApiFareProducts(fares.getItineraryProducts()), toApiLegProducts(itinerary, fares.getLegProducts()) @@ -102,17 +97,6 @@ private List toApiFareProducts(Collection product) } } - private Map toApiMoneys(ItineraryFares fare) { - return fare - .getFareTypes() - .stream() - .map(key -> { - var money = toApiMoney(fare.getFare(key)); - return new SimpleEntry<>(key, money); - }) - .collect(Collectors.toMap(e -> e.getKey().name(), Entry::getValue)); - } - private ApiMoney toApiMoney(Money m) { var c = m.currency(); return new ApiMoney( diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java index 5399783bee0..a7ae7954cd6 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java @@ -48,17 +48,7 @@ public DataFetcher>> fares() { if (fare == null) { return null; } - return fare - .getFareTypes() - .stream() - .map(fareKey -> { - Map result = new HashMap<>(); - result.put("name", fareKey); - result.put("fare", fare.getFare(fareKey)); - result.put("details", List.of()); - return result; - }) - .collect(Collectors.toList()); + return List.of(); }; } From d273717d91584370164cee65ea36d9f8b6ac0168 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 00:07:48 +0100 Subject: [PATCH 241/356] Remove more fares --- .../flex/trip/ScheduledDeviatedTripTest.java | 2 +- .../ext/fares/impl/AtlantaFareService.java | 29 +++++++------------ .../model/fare/ItineraryFares.java | 17 ----------- .../apis/gtfs/GraphQLIntegrationTest.java | 1 - 4 files changed, 12 insertions(+), 37 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index 3523a6e5c5e..a922886c3b1 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -149,7 +149,7 @@ void calculateDirectFare() { var itineraries = router.createFlexOnlyItineraries().stream().peek(filter::decorate).toList(); var itinerary = itineraries.iterator().next(); - assertFalse(itinerary.getFares().getFareTypes().isEmpty()); + assertFalse(itinerary.getFares().getItineraryProducts().isEmpty()); assertEquals(Money.usDollars(2.5f), itinerary.getFares().getFare(FareType.regular)); diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java index d2d9d3e2a1b..019edd5d30a 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java @@ -1,8 +1,11 @@ package org.opentripplanner.ext.fares.impl; +import static org.opentripplanner.transit.model.basic.Money.ZERO_USD; import static org.opentripplanner.transit.model.basic.Money.usDollars; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import java.time.Duration; import java.time.ZoneId; import java.util.ArrayList; @@ -69,7 +72,7 @@ public boolean routeNamesContains(@Nullable String s) { private static class ATLTransfer { List legs = new ArrayList<>(); - List fares = new ArrayList<>(); + Multimap fares = ArrayListMultimap.create(); final FareType fareType; final Currency currency; Money lastFareWithTransfer; @@ -89,12 +92,10 @@ public ATLTransfer(Currency currency, FareType fareType) { */ public boolean addLeg(Leg leg, Money defaultFare) { // A transfer will always contain at least one ride. - ItineraryFares fare = new ItineraryFares(); RideType toRideType = classify(leg); if (legs.size() == 0) { legs.add(leg); - fare.addFare(fareType, defaultFare); - fares.add(fare); + fares.put(fareType, defaultFare); lastFareWithTransfer = defaultFare; maxRides = getMaxTransfers(toRideType); transferWindow = getTransferWindow(toRideType); @@ -128,12 +129,8 @@ public boolean addLeg(Leg leg, Money defaultFare) { } } - // The transfer is valid for this ride, so create a fare object. - // TODO: Change this fare object out for the one on the Ride object when Fare-by-leg is added - fares.add(fare); - if (transferClassification.type.equals(TransferType.NO_TRANSFER)) { - fare.addFare(fareType, defaultFare); + fares.put(fareType, defaultFare); // Full fare is charged, but transfer is still valid. // Ride is not added to rides list since it doesn't count towards transfer limit. // NOTE: Rides and fares list will not always be in sync because of this. @@ -143,7 +140,7 @@ public boolean addLeg(Leg leg, Money defaultFare) { // All conditions below this point "use" the transfer, so we add the ride. legs.add(leg); if (transferClassification.type.equals(TransferType.FREE_TRANSFER)) { - fare.addFare(fareType, Money.ofFractionalAmount(currency, 0)); + fares.put(fareType, Money.ofFractionalAmount(currency, 0)); lastFareWithTransfer = defaultFare; return true; } else if (transferClassification.type.equals(TransferType.TRANSFER_PAY_DIFFERENCE)) { @@ -151,11 +148,11 @@ public boolean addLeg(Leg leg, Money defaultFare) { if (defaultFare.greaterThan(lastFareWithTransfer)) { newCost = defaultFare.minus(lastFareWithTransfer); } - fare.addFare(fareType, newCost); + fares.put(fareType, newCost); lastFareWithTransfer = defaultFare; return true; } else if (transferClassification.type.equals(TransferType.TRANSFER_WITH_UPCHARGE)) { - fare.addFare(fareType, transferClassification.upcharge); + fares.put(fareType, transferClassification.upcharge); lastFareWithTransfer = defaultFare; return true; } @@ -163,11 +160,8 @@ public boolean addLeg(Leg leg, Money defaultFare) { } public Money getTotal() { - Money total = Money.ZERO_USD; - for (ItineraryFares f : fares) { - total = total.plus(f.getFare(fareType)); - } - return total; + return fares.get(fareType).stream().reduce(ZERO_USD, Money::plus); + } } @@ -420,7 +414,6 @@ public boolean populateFare( null ); fare.addItineraryProducts(List.of(fareProduct)); - fare.addFare(fareType, cost); return true; } diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index d60dbfb249e..a8ed13418ad 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -38,14 +38,6 @@ public class ItineraryFares { */ private final Multimap legProducts = LinkedHashMultimap.create(); - /** - * Holds the "fares" for the entire itinerary. The definition of a fare is not clear so - * this is deprecated. - * @deprecated Exists only for backwards compatibility and will be removed in the future. - */ - @Deprecated - private final Map fares = new HashMap<>(); - public static ItineraryFares empty() { return new ItineraryFares(); } @@ -74,7 +66,6 @@ public Multimap getLegProducts() { */ @Deprecated public void addFare(FareType fareType, Money money) { - fares.put(fareType, money); } /** @@ -99,14 +90,6 @@ public Money getFare(FareType type) { return fares.get(type); } - /** - * Return the set of {@link FareType}s that are contained in this instance. - */ - @Deprecated - public Set getFareTypes() { - return fares.keySet(); - } - @Override public int hashCode() { return Objects.hash(itineraryProducts, legProducts); diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index 6e99e096c2c..d89afea6f9d 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -183,7 +183,6 @@ static void setup() { var railLeg = (ScheduledTransitLeg) i1.getTransitLeg(2); var fares = new ItineraryFares(); - fares.addFare(FareType.regular, Money.euros(3.1f)); var dayPass = fareProduct("day-pass"); fares.addItineraryProducts(List.of(dayPass)); From d28b42b3b39f0767a7ac066f798b525138466ce6 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 17 Jan 2024 09:37:39 +0100 Subject: [PATCH 242/356] Remove more fares --- .../fares/impl/AtlantaFareServiceTest.java | 2 +- .../fares/impl/DefaultFareServiceTest.java | 12 ------- ...reInFreeTransferWindowFareServiceTest.java | 8 ++--- .../ext/fares/impl/OrcaFareServiceTest.java | 2 +- .../flex/trip/ScheduledDeviatedTripTest.java | 2 +- .../ext/fares/impl/AtlantaFareService.java | 3 +- .../ext/fares/impl/DefaultFareService.java | 5 +-- .../ext/fares/impl/OrcaFareService.java | 3 +- .../model/fare/ItineraryFares.java | 32 ------------------- 9 files changed, 9 insertions(+), 60 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java index b75c58923e1..d0055990782 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java @@ -228,7 +228,7 @@ void fullItinerary() { private static void calculateFare(List rides, Money expectedFare) { ItineraryFares fare = new ItineraryFares(); atlFareService.populateFare(fare, USD, FareType.electronicRegular, rides, null); - assertEquals(expectedFare, fare.getFare(FareType.electronicRegular)); + assertEquals(expectedFare, fare.getItineraryProducts().stream().filter(fp -> fp.name().equals(FareType.electronicRegular.name())).findFirst().get().price(); var fareProducts = fare .getItineraryProducts() diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index c5e26cc3c9b..6e92373854d 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -113,10 +113,6 @@ void shouldNotCombineInterlinedLegs() { var fare = service.calculateFares(itin); assertNotNull(fare); - var price = fare.getFare(FareType.regular); - - assertEquals(TWENTY_DOLLARS, price); - var legProducts = fare.getLegProducts(); var firstLeg = itin.getLegs().getFirst(); @@ -145,9 +141,6 @@ void unknownLeg() { var fare = service.calculateFares(itin); assertNotNull(fare); - var price = fare.getFare(FareType.regular); - assertEquals(Money.usDollars(-0.01f), price); - var fareProducts = List.copyOf(fare.getLegProducts().values()); assertEquals(1, fareProducts.size()); @@ -220,9 +213,6 @@ void multipleFeedsWithTransfersWithinFeed() { "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", legProducts.get(finalBusLeg).toString() ); - - var resultPrice = result.getFare(FareType.regular); - assertEquals(TWENTY_DOLLARS, resultPrice); } @Test @@ -241,8 +231,6 @@ void multipleFeedsWithUnknownFareLegs() { .stream() .map(r -> r.product().id()) .toList(); - var resultPrice = result.getFare(FareType.regular); assertEquals(List.of(OTHER_FEED_ATTRIBUTE.getId()), resultProductIds); - assertEquals(Money.usDollars(-0.01f), resultPrice); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java index 5d7615c49e3..e9aa17ba35f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareServiceTest.java @@ -44,12 +44,8 @@ public void canCalculateFare( var fares = fareService.calculateFares(i); assertFalse(fares.getItineraryProducts().isEmpty()); - var prices = fares - .getItineraryProducts() - .stream() - .map(FareProduct::price) - .toList(); - assertEquals(List.of(expectedFare), prices); + var prices = fares.getItineraryProducts().stream().map(FareProduct::price).toList(); + assertEquals(List.of(expectedFare), prices); } private static List createTestCases() { diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java index e30fb2d8b18..158e9feeac3 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java @@ -81,7 +81,7 @@ public static void setUpClass() { private static void calculateFare(List legs, FareType fareType, Money expectedPrice) { var itinerary = new Itinerary(legs); var itineraryFares = orcaFareService.calculateFares(itinerary); - assertEquals(expectedPrice, itineraryFares.getFare(fareType)); + assertEquals(expectedPrice, itineraryFares.getItineraryProducts().stream().filter(fareProduct -> fareProduct.name().equals(fareType.name()))); } private static void assertLegFareEquals( diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index a922886c3b1..e9c4bebe069 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -151,7 +151,7 @@ void calculateDirectFare() { var itinerary = itineraries.iterator().next(); assertFalse(itinerary.getFares().getItineraryProducts().isEmpty()); - assertEquals(Money.usDollars(2.5f), itinerary.getFares().getFare(FareType.regular)); + assertEquals(Money.usDollars(2.5f), itinerary.getFares().getItineraryProducts().getFirst().price()); OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, false)); } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java index 019edd5d30a..799e7ef37d7 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java @@ -160,8 +160,7 @@ public boolean addLeg(Leg leg, Money defaultFare) { } public Money getTotal() { - return fares.get(fareType).stream().reduce(ZERO_USD, Money::plus); - + return fares.get(fareType).stream().reduce(ZERO_USD, Money::plus); } } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index 9f3bb2094b0..c6ab951dc86 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -142,9 +142,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { fareProducts.putAll(currentFare.getLegProducts()); itineraryProducts.addAll(currentFare.getItineraryProducts()); - - } else { - } + } else {} } fare.addFareProductUses(fareProducts); @@ -154,7 +152,6 @@ public ItineraryFares calculateFares(Itinerary itinerary) { if (!hasFare) { continue; } - } return hasFare ? fare : null; } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java index 4879d858e86..d9bfb952e6d 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java @@ -480,7 +480,8 @@ public boolean populateFare( } cost = cost.plus(orcaFareDiscount); if (cost.fractionalAmount().floatValue() < Float.MAX_VALUE) { - fare.addFare(fareType, cost); + var fp = FareProduct.of(new FeedScopedId(FEED_ID, fareType.name()), fareType.name(), cost).build(); + fare.addItineraryProducts(List.of(fp)); return true; } else { return false; diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index a8ed13418ad..530c48914c6 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -4,18 +4,13 @@ import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import java.util.Collection; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Set; -import javax.annotation.Nullable; import org.opentripplanner.framework.lang.Sandbox; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.routing.core.FareType; -import org.opentripplanner.transit.model.basic.Money; /** * @@ -56,18 +51,6 @@ public Multimap getLegProducts() { return ImmutableMultimap.copyOf(legProducts); } - /** - * Add a "fare". This is an ill-defined concept (is it for the entire itinerary or only some - * legs?) from the early days of OTP which will be removed in the future. - *

      - * @deprecated It only exists for backwards-compatibility. - * Use {@link ItineraryFares#addFareProduct(Leg, FareProduct)}, - * {@link ItineraryFares#addItineraryProducts(Collection)} instead. - */ - @Deprecated - public void addFare(FareType fareType, Money money) { - } - /** * Add fare products that cover the entire itinerary, i.e. are valid for all legs. */ @@ -75,21 +58,6 @@ public void addItineraryProducts(Collection products) { itineraryProducts.addAll(products); } - /** - * - * Get the "fare" for a specific fare type. - *

      - * It is ill-defined what this actually means (entire itinerary?, some legs?). - *

      - * Use {@link ItineraryFares#getItineraryProducts()} or {@link ItineraryFares#getLegProducts()} - * instead. - */ - @Nullable - @Deprecated - public Money getFare(FareType type) { - return fares.get(type); - } - @Override public int hashCode() { return Objects.hash(itineraryProducts, legProducts); From ab253d9ba7d1db806170bfa6d914e60548c7c7f8 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 12:53:38 +0100 Subject: [PATCH 243/356] Fix more tests --- .../java/org/opentripplanner/ext/fares/FaresFilterTest.java | 2 -- .../ext/fares/impl/AtlantaFareServiceTest.java | 2 +- .../fares/impl/CombinedInterlinedLegsFareServiceTest.java | 3 --- .../ext/fares/impl/DefaultFareServiceTest.java | 5 +---- .../opentripplanner/ext/fares/impl/OrcaFareServiceTest.java | 4 ++-- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java index 90468b091f9..ac11886c208 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/FaresFilterTest.java @@ -12,7 +12,6 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.fares.FareService; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.basic.Money; @@ -34,7 +33,6 @@ void shouldAddFare() { assertEquals(ItineraryFares.empty(), i1.getFares()); var fares = new ItineraryFares(); - fares.addFare(FareType.regular, Money.euros(2.80f)); var leg = i1.getLegs().get(1); var fp = new FareProduct(id("fp"), "fare product", Money.euros(10.00f), null, null, null); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java index d0055990782..e7d5b60c023 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java @@ -228,7 +228,7 @@ void fullItinerary() { private static void calculateFare(List rides, Money expectedFare) { ItineraryFares fare = new ItineraryFares(); atlFareService.populateFare(fare, USD, FareType.electronicRegular, rides, null); - assertEquals(expectedFare, fare.getItineraryProducts().stream().filter(fp -> fp.name().equals(FareType.electronicRegular.name())).findFirst().get().price(); + assertEquals(expectedFare, fare.getItineraryProducts().stream().filter(fp -> fp.name().equals(FareType.electronicRegular.name())).findFirst().get().price()); var fareProducts = fare .getItineraryProducts() diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java index 350bae04dce..53295486128 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java @@ -65,9 +65,6 @@ void modes(CombinationMode mode, Itinerary itinerary, Money totalPrice, String h var fare = service.calculateFares(itinerary); assertNotNull(fare); - var price = fare.getFare(FareType.regular); - assertEquals(totalPrice, price); - var firstLeg = itinerary.getTransitLeg(0); var uses = fare.getLegProducts().get(firstLeg); assertEquals(1, uses.size()); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 6e92373854d..d9dc59b898f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -49,14 +49,11 @@ void simpleZoneBasedFare() { var fare = service.calculateFares(itin); assertNotNull(fare); - var price = fare.getFare(FareType.regular); - - assertEquals(TEN_DOLLARS, price); - var fp = fare.getItineraryProducts().get(0); assertEquals(TEN_DOLLARS, fp.price()); assertEquals("F:regular", fp.id().toString()); + // todo var lp = fare.getLegProducts(); assertEquals(1, lp.size()); var product = lp.values().iterator().next().product(); diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java index 158e9feeac3..88fbff9c69c 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java @@ -491,7 +491,7 @@ void nullLongName(FareType type) { var fare = new ItineraryFares(); orcaFareService.populateFare(fare, USD, type, legs, null); - assertNotNull(fare.getFare(type)); + assertFalse(fare.getLegProducts().isEmpty()); } @ParameterizedTest @@ -513,7 +513,7 @@ void nullShortName(FareType type) { var fare = new ItineraryFares(); orcaFareService.populateFare(fare, USD, type, legs, null); - assertNotNull(fare.getFare(type)); + assertFalse(fare.getLegProducts().isEmpty()); } @Test From 5cf0b59fb27df3e32c51131734e1e578566d410c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 13:42:31 +0100 Subject: [PATCH 244/356] Fix tests after fare removal --- .../fares/impl/AtlantaFareServiceTest.java | 11 +- ...CombinedInterlinedLegsFareServiceTest.java | 9 + .../fares/impl/DefaultFareServiceTest.java | 42 ++- .../ext/fares/impl/FaresIntegrationTest.java | 12 +- .../ext/fares/impl/OrcaFareServiceTest.java | 11 +- .../flex/trip/ScheduledDeviatedTripTest.java | 5 +- .../ext/restapi/mapping/FareMapperTest.java | 32 -- .../ext/fares/impl/DefaultFareService.java | 9 +- .../ext/fares/impl/OrcaFareService.java | 4 +- .../__snapshots__/BikeRentalSnapshotTest.snap | 324 +----------------- .../__snapshots__/ElevationSnapshotTest.snap | 162 +-------- .../__snapshots__/TransitSnapshotTest.snap | 270 +-------------- 12 files changed, 97 insertions(+), 794 deletions(-) delete mode 100644 src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java index e7d5b60c023..2d26bf711e4 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java @@ -228,7 +228,16 @@ void fullItinerary() { private static void calculateFare(List rides, Money expectedFare) { ItineraryFares fare = new ItineraryFares(); atlFareService.populateFare(fare, USD, FareType.electronicRegular, rides, null); - assertEquals(expectedFare, fare.getItineraryProducts().stream().filter(fp -> fp.name().equals(FareType.electronicRegular.name())).findFirst().get().price()); + assertEquals( + expectedFare, + fare + .getItineraryProducts() + .stream() + .filter(fp -> fp.name().equals(FareType.electronicRegular.name())) + .findFirst() + .get() + .price() + ); var fareProducts = fare .getItineraryProducts() diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java index 53295486128..3f237cf509f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/CombinedInterlinedLegsFareServiceTest.java @@ -72,6 +72,15 @@ void modes(CombinationMode mode, Itinerary itinerary, Money totalPrice, String h var secondLeg = itinerary.getTransitLeg(1); uses = fare.getLegProducts().get(secondLeg); assertEquals(1, uses.size()); + + var sum = fare + .getLegProducts() + .values() + .stream() + .distinct() + .map(p -> p.product().price()) + .reduce(Money.ZERO_USD, Money::plus); + assertEquals(totalPrice, sum); } @Test diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index d9dc59b898f..cc56556c4dd 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -49,15 +49,11 @@ void simpleZoneBasedFare() { var fare = service.calculateFares(itin); assertNotNull(fare); - var fp = fare.getItineraryProducts().get(0); - assertEquals(TEN_DOLLARS, fp.price()); - assertEquals("F:regular", fp.id().toString()); - - // todo - var lp = fare.getLegProducts(); - assertEquals(1, lp.size()); - var product = lp.values().iterator().next().product(); - assertEquals(TEN_DOLLARS, product.price()); + var legProducts = fare.getLegProducts().get(itin.getTransitLeg(0)); + assertEquals( + "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + legProducts.toString() + ); } @Test @@ -113,16 +109,17 @@ void shouldNotCombineInterlinedLegs() { var legProducts = fare.getLegProducts(); var firstLeg = itin.getLegs().getFirst(); - var products = List.copyOf(legProducts.get(firstLeg)); - assertEquals(TEN_DOLLARS, products.getFirst().product().price()); + assertEquals( + "[FareProductUse[id=ccadd1d3-f284-31a4-9d58-0a300198950f, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + legProducts.get(firstLeg).toString() + ); var secondLeg = itin.getLegs().get(1); - products = List.copyOf(legProducts.get(secondLeg)); - assertEquals(TEN_DOLLARS, products.getFirst().product().price()); - - assertEquals(1, fare.getItineraryProducts().size()); - assertEquals(TWENTY_DOLLARS, fare.getItineraryProducts().getFirst().price()); + assertEquals( + "[FareProductUse[id=c58974dd-9a2f-3f42-90ec-c62a7b0dfd51, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + legProducts.get(secondLeg).toString() + ); } @Test @@ -175,8 +172,17 @@ void multipleFeeds() { fareProductIds ); - var resultPrice = result.getFare(FareType.regular); - assertEquals(TWENTY_DOLLARS, resultPrice); + var legProducts = result.getLegProducts(); + var firstBusLeg = itin.getTransitLeg(0); + assertEquals( + "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + legProducts.get(firstBusLeg).toString() + ); + var secondBusLeg = itin.getTransitLeg(2); + assertEquals( + "[FareProductUse[id=678d201c-e839-35c3-ae7b-1bc3834da5e5, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + legProducts.get(secondBusLeg).toString() + ); } @Test diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index d6a1432a75b..7efdeaff083 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -19,10 +19,8 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; -import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; -import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.service.TransitModel; public class FaresIntegrationTest { @@ -45,7 +43,10 @@ public void testBasic() { var to = GenericLocation.fromStopId("Destination", feedId, "Mountain View Caltrain"); ItineraryFares fare = getFare(from, to, start, serverContext); - assertEquals(fare.getFare(FareType.regular), Money.usDollars(4.25f)); + assertEquals( + "[FareProductUse[id=eec97231-e931-3584-8cc3-e7657a1ff14d, product=FareProduct{id: '1:OW_2', amount: $4.25}]]", + fare.getLegProducts().values().toString() + ); } @Test @@ -76,7 +77,10 @@ public void testPortland() { ItineraryFares fare = getFare(from, to, startTime, serverContext); - assertEquals(Money.usDollars(2), fare.getFare(FareType.regular)); + assertEquals( + "[FareProductUse[id=26a5a5ee-c7db-37ad-be09-fa3afdce748b, product=FareProduct{id: 'prt:19', amount: $2.00}]]", + fare.getLegProducts().values().toString() + ); // long trip diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java index 88fbff9c69c..0058fd6b9df 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java @@ -81,7 +81,16 @@ public static void setUpClass() { private static void calculateFare(List legs, FareType fareType, Money expectedPrice) { var itinerary = new Itinerary(legs); var itineraryFares = orcaFareService.calculateFares(itinerary); - assertEquals(expectedPrice, itineraryFares.getItineraryProducts().stream().filter(fareProduct -> fareProduct.name().equals(fareType.name()))); + assertEquals( + expectedPrice, + itineraryFares + .getItineraryProducts() + .stream() + .filter(fareProduct -> fareProduct.name().equals(fareType.name())) + .findFirst() + .get() + .price() + ); } private static void assertLegFareEquals( diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index e9c4bebe069..c93eed50ebd 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -151,7 +151,10 @@ void calculateDirectFare() { var itinerary = itineraries.iterator().next(); assertFalse(itinerary.getFares().getItineraryProducts().isEmpty()); - assertEquals(Money.usDollars(2.5f), itinerary.getFares().getItineraryProducts().getFirst().price()); + assertEquals( + Money.usDollars(2.5f), + itinerary.getFares().getItineraryProducts().getFirst().price() + ); OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, false)); } diff --git a/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java deleted file mode 100644 index 4b455cce0f7..00000000000 --- a/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/FareMapperTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.opentripplanner.ext.restapi.mapping; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; - -import java.util.Locale; -import org.junit.jupiter.api.Test; -import org.opentripplanner.model.fare.ItineraryFares; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.PlanTestConstants; -import org.opentripplanner.routing.core.FareType; -import org.opentripplanner.transit.model.basic.Money; - -class FareMapperTest implements PlanTestConstants { - - @Test - public void emptyDetails() { - var fare = new ItineraryFares(); - fare.addFare(FareType.regular, Money.usDollars(5)); - - Itinerary itinerary = newItinerary(A, 30).bus(1, 30, 60, B).bus(2, 90, 120, C).build(); - - itinerary.setFare(fare); - - var mapper = new FareMapper(Locale.US); - var apiFare = mapper.mapFare(itinerary); - - var apiMoney = apiFare.fare().get(FareType.regular.name()); - assertEquals(500, apiMoney.cents()); - assertEquals("USD", apiMoney.currency().currency()); - } -} diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index c6ab951dc86..92b1b562611 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -75,8 +75,6 @@ public class DefaultFareService implements FareService { private static final Logger LOG = LoggerFactory.getLogger(DefaultFareService.class); - private final float UNKNOWN_FARE_PRICE = -0.01f; - /** For each fare type (regular, student, etc...) the collection of rules that apply. */ protected Map> fareRulesPerType; @@ -142,16 +140,11 @@ public ItineraryFares calculateFares(Itinerary itinerary) { fareProducts.putAll(currentFare.getLegProducts()); itineraryProducts.addAll(currentFare.getItineraryProducts()); - } else {} + } } fare.addFareProductUses(fareProducts); fare.addItineraryProducts(itineraryProducts); - - // No fares will be discovered after this point - if (!hasFare) { - continue; - } } return hasFare ? fare : null; } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java index d9bfb952e6d..c55e059de7b 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java @@ -480,7 +480,9 @@ public boolean populateFare( } cost = cost.plus(orcaFareDiscount); if (cost.fractionalAmount().floatValue() < Float.MAX_VALUE) { - var fp = FareProduct.of(new FeedScopedId(FEED_ID, fareType.name()), fareType.name(), cost).build(); + var fp = FareProduct + .of(new FeedScopedId(FEED_ID, fareType.name()), fareType.name(), cost) + .build(); fare.addItineraryProducts(List.of(fp)); return true; } else { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap index 41bc4278ca1..5e2a04c07d7 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/BikeRentalSnapshotTest.snap @@ -7,33 +7,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:32:24.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -493,33 +468,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:38:09.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -937,33 +887,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:40:10.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -1277,33 +1202,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:45:24.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -1763,33 +1663,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:54:24.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -2249,33 +2124,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.accessBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:56:10.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -3264,33 +3114,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:28:51.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -3802,33 +3627,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:35:24.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -4220,33 +4020,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:37:21.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -4612,33 +4387,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:43:51.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -5150,33 +4900,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:51:24.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -5568,33 +5293,8 @@ org.opentripplanner.routing.algorithm.mapping.BikeRentalSnapshotTest.egressBikeR "elevationLost" : 0.0, "endTime" : "2009-10-21T23:56:21.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap index 6579e4bbd37..390185cd96f 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/ElevationSnapshotTest.snap @@ -535,33 +535,8 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "elevationLost" : 4.23, "endTime" : "2009-10-21T23:31:21.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -929,33 +904,8 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "elevationLost" : 23.58, "endTime" : "2009-10-21T23:35:04.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -1349,33 +1299,8 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "elevationLost" : 1.09, "endTime" : "2009-10-21T23:37:44.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -1743,33 +1668,8 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "elevationLost" : 4.76, "endTime" : "2009-10-21T23:46:18.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -2215,33 +2115,8 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "elevationLost" : 4.23, "endTime" : "2009-10-21T23:46:21.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -2609,33 +2484,8 @@ org.opentripplanner.routing.algorithm.mapping.ElevationSnapshotTest.transit=[ "elevationLost" : 23.58, "endTime" : "2009-10-21T23:51:04.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap index d5da342f9a6..adc5ee69635 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/TransitSnapshotTest.snap @@ -235,33 +235,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T18:38:41.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -718,33 +693,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T18:39:22.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -1266,33 +1216,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T18:53:55.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -1749,33 +1674,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T18:55:32.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -2297,33 +2197,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T19:08:19.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -3044,33 +2919,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T18:38:40.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -3530,33 +3380,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T18:54:10.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -4016,33 +3841,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T19:09:40.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -4502,33 +4302,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T19:11:51.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ @@ -5028,33 +4803,8 @@ org.opentripplanner.routing.algorithm.mapping.TransitSnapshotTest.test_trip_plan "elevationLost" : 0.0, "endTime" : "2009-11-17T19:25:05.000+00:00", "fare" : { - "coveringItinerary" : [ - { - "amount" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - }, - "id" : "prt:regular", - "name" : "regular" - } - ], "details" : { }, - "fare" : { - "regular" : { - "cents" : 200, - "currency" : { - "currency" : "USD", - "currencyCode" : "USD", - "defaultFractionDigits" : 2, - "symbol" : "$" - } - } - }, + "fare" : { }, "legProducts" : [ { "legIndices" : [ From 2d4cf94698eb523826c857e012de3f3df5f95cf8 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 21:59:44 +0100 Subject: [PATCH 245/356] Update more tests --- .../ext/fares/impl/FaresIntegrationTest.java | 5 +++-- .../ext/flex/trip/ScheduledDeviatedTripTest.java | 8 +++----- .../ext/fares/impl/DefaultFareService.java | 6 +++--- .../apis/gtfs/expectations/plan-fares.json | 9 +-------- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 7efdeaff083..6265dc60c1e 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -14,6 +14,7 @@ import org.opentripplanner.TestServerContext; import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.model.GenericLocation; +import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.api.request.RouteRequest; @@ -44,8 +45,8 @@ public void testBasic() { ItineraryFares fare = getFare(from, to, start, serverContext); assertEquals( - "[FareProductUse[id=eec97231-e931-3584-8cc3-e7657a1ff14d, product=FareProduct{id: '1:OW_2', amount: $4.25}]]", - fare.getLegProducts().values().toString() + "[FareProduct{id: '1:OW_2', amount: $4.25}]", + fare.getLegProducts().values().stream().map(FareProductUse::product).toList().toString() ); } diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index c93eed50ebd..378d18d7bb4 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -33,7 +33,6 @@ import org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; -import org.opentripplanner.routing.core.FareType; import org.opentripplanner.routing.framework.DebugTimingAggregator; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.NearbyStop; @@ -42,7 +41,6 @@ import org.opentripplanner.street.model.vertex.StreetLocation; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.state.State; -import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.DefaultTransitService; @@ -149,11 +147,11 @@ void calculateDirectFare() { var itineraries = router.createFlexOnlyItineraries().stream().peek(filter::decorate).toList(); var itinerary = itineraries.iterator().next(); - assertFalse(itinerary.getFares().getItineraryProducts().isEmpty()); + assertFalse(itinerary.getFares().getLegProducts().isEmpty()); assertEquals( - Money.usDollars(2.5f), - itinerary.getFares().getItineraryProducts().getFirst().price() + "[FareProductUse[id=1532715d-bffe-310c-9c76-842f3c74bbd3, product=FareProduct{id: '1:flex-adult', amount: $2.50}]]", + itinerary.getFares().getLegProducts().values().toString() ); OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, false)); diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index 92b1b562611..e1d0200aff6 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -119,7 +119,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { ItineraryFares fare = ItineraryFares.empty(); boolean hasFare = false; for (FareType fareType : fareRulesPerType.keySet()) { - final Multimap fareProducts = LinkedHashMultimap.create(); + final Multimap legProducts = LinkedHashMultimap.create(); List itineraryProducts = new ArrayList<>(); for (String feedId : fareLegsByFeed.keySet()) { ItineraryFares currentFare = ItineraryFares.empty(); @@ -138,12 +138,12 @@ public ItineraryFares calculateFares(Itinerary itinerary) { hasFare = feedHasFare || hasFare; // Other feeds might still have fare for some legs - fareProducts.putAll(currentFare.getLegProducts()); + legProducts.putAll(currentFare.getLegProducts()); itineraryProducts.addAll(currentFare.getItineraryProducts()); } } - fare.addFareProductUses(fareProducts); + fare.addFareProductUses(legProducts); fare.addItineraryProducts(itineraryProducts); } return hasFare ? fare : null; diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json index 9ee3d4706b3..1defc81ded1 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-fares.json @@ -183,14 +183,7 @@ "fareProducts" : [ ] } ], - "fares" : [ - { - "type" : "regular", - "cents" : 310, - "currency" : "EUR", - "components" : [] - } - ] + "fares" : [ ] } ] } From a346d9c1478a64681ef60b401be1e00e3e977073 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 22 Jan 2024 22:15:57 +0100 Subject: [PATCH 246/356] Remove fareImpl from GTFS API --- .../apis/gtfs/GtfsGraphQLIndex.java | 2 -- .../apis/gtfs/datafetchers/fareImpl.java | 35 ------------------- .../apis/gtfs/generated/graphql-codegen.yml | 1 - 3 files changed, 38 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 7101d132834..ff3e8681ce8 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -77,7 +77,6 @@ import org.opentripplanner.apis.gtfs.datafetchers.VehicleRentalStationImpl; import org.opentripplanner.apis.gtfs.datafetchers.debugOutputImpl; import org.opentripplanner.apis.gtfs.datafetchers.elevationProfileComponentImpl; -import org.opentripplanner.apis.gtfs.datafetchers.fareImpl; import org.opentripplanner.apis.gtfs.datafetchers.placeAtDistanceImpl; import org.opentripplanner.apis.gtfs.datafetchers.serviceTimeRangeImpl; import org.opentripplanner.apis.gtfs.datafetchers.stepImpl; @@ -128,7 +127,6 @@ protected static GraphQLSchema buildSchema() { .type(typeWiring.build(debugOutputImpl.class)) .type(typeWiring.build(DepartureRowImpl.class)) .type(typeWiring.build(elevationProfileComponentImpl.class)) - .type(typeWiring.build(fareImpl.class)) .type(typeWiring.build(FeedImpl.class)) .type(typeWiring.build(FeedImpl.class)) .type(typeWiring.build(GeometryImpl.class)) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java deleted file mode 100644 index fb2c6ee184c..00000000000 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/fareImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.opentripplanner.apis.gtfs.datafetchers; - -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; -import java.util.List; -import java.util.Map; -import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; -import org.opentripplanner.transit.model.basic.Money; - -public class fareImpl implements GraphQLDataFetchers.GraphQLFare { - - @Override - public DataFetcher cents() { - return environment -> ((Money) getSource(environment).get("fare")).minorUnitAmount(); - } - - @Override - public DataFetcher> components() { - return environment -> List.of(); - } - - @Override - public DataFetcher currency() { - return environment -> ((Money) getSource(environment).get("fare")).currency().getCurrencyCode(); - } - - @Override - public DataFetcher type() { - return environment -> getSource(environment).get("name").toString(); - } - - private Map getSource(DataFetchingEnvironment environment) { - return environment.getSource(); - } -} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml b/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml index c720fc5a119..c141266d2e6 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml @@ -54,7 +54,6 @@ config: DepartureRow: org.opentripplanner.routing.graphfinder.PatternAtStop#PatternAtStop elevationProfileComponent: org.opentripplanner.model.plan.ElevationProfile.Step Emissions: org.opentripplanner.model.plan.Emissions#Emissions - fare: java.util.Map#Map Feed: String Geometry: org.locationtech.jts.geom.Geometry#Geometry InputField: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLInputField#GraphQLInputField From e5e599703cd9472ada47761e762b8c95538fa530 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 24 Jan 2024 21:29:33 +0100 Subject: [PATCH 247/356] Remove unused fare types --- src/main/java/org/opentripplanner/routing/core/FareType.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/core/FareType.java b/src/main/java/org/opentripplanner/routing/core/FareType.java index 8efe12246d2..007f9e2cef6 100644 --- a/src/main/java/org/opentripplanner/routing/core/FareType.java +++ b/src/main/java/org/opentripplanner/routing/core/FareType.java @@ -10,10 +10,7 @@ @Deprecated public enum FareType implements Serializable { regular, - student, senior, - tram, - special, youth, electronicRegular, electronicSenior, From 451c1d3b44cfe6ce6642f177c2222ce3c64d3b51 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 00:05:35 +0100 Subject: [PATCH 248/356] Update tests --- .../fares/impl/AtlantaFareServiceTest.java | 7 ++--- .../fares/impl/DefaultFareServiceTest.java | 5 ++-- .../ext/fares/impl/HSLFareServiceTest.java | 3 ++- .../ext/fares/impl/OrcaFareServiceTest.java | 9 +++---- .../ext/fares/impl/AtlantaFareService.java | 11 ++++---- .../ext/fares/impl/DefaultFareService.java | 26 +++++-------------- ...stFareInFreeTransferWindowFareService.java | 10 ++++--- .../ext/fares/impl/OrcaFareService.java | 8 +++--- .../model/fare/FareProduct.java | 1 + .../model/fare/ItineraryFares.java | 9 +++++++ 10 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java index 2d26bf711e4..39b80deace1 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java @@ -21,7 +21,6 @@ import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.NonLocalizedString; -import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; import org.opentripplanner.model.plan.Place; @@ -226,8 +225,7 @@ void fullItinerary() { * used. This will be the same for all cash fare types except when overriden above. */ private static void calculateFare(List rides, Money expectedFare) { - ItineraryFares fare = new ItineraryFares(); - atlFareService.populateFare(fare, USD, FareType.electronicRegular, rides, null); + var fare = atlFareService.populateFare(USD, FareType.electronicRegular, rides, null); assertEquals( expectedFare, fare @@ -293,10 +291,9 @@ private static Itinerary createItinerary(String agencyId, String shortName, long .build(); int start = (int) (T11_00 + (startTimeMins * 60)); - var itin = newItinerary(Place.forStop(firstStop), start) + return newItinerary(Place.forStop(firstStop), start) .bus(route, 1, start, T11_12, Place.forStop(lastStop)) .build(); - return itin; } private static class TestAtlantaFareService extends AtlantaFareService { diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index cc56556c4dd..32a15f2be0a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_STOP; import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_TO_CITY_CENTER_SET; import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_A_STOP; @@ -19,6 +18,7 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.core.FareType; @@ -28,7 +28,6 @@ class DefaultFareServiceTest implements PlanTestConstants { private static final Money TEN_DOLLARS = Money.usDollars(10); - private static final Money TWENTY_DOLLARS = Money.usDollars(20); @Test void noRules() { @@ -36,7 +35,7 @@ void noRules() { service.addFareRules(FareType.regular, List.of()); var itin = newItinerary(A, T11_00).bus(1, T11_05, T11_12, B).build(); var fare = service.calculateFares(itin); - assertNull(fare); + assertEquals(ItineraryFares.empty(), fare); } @Test diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java index 4e1347cae16..17c381f1bd6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/HSLFareServiceTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary; import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID; import static org.opentripplanner.transit.model.basic.Money.euros; @@ -450,6 +451,6 @@ void unknownFare() { .bus(1, T11_20, T11_30, PlanTestConstants.E) .build(); var result = service.calculateFares(outsideHsl); - assertNull(result); + assertTrue(result.isEmpty()); } } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java index 0058fd6b9df..ae8df72dd6a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java @@ -176,8 +176,7 @@ void calculateFareWithNoFreeTransfer() { @Test void calculateFareByLeg() { List rides = List.of(getLeg(KITSAP_TRANSIT_AGENCY_ID, 0), getLeg(COMM_TRANS_AGENCY_ID, 2)); - ItineraryFares fares = new ItineraryFares(); - orcaFareService.populateFare(fares, USD, FareType.electronicRegular, rides, null); + var fares = orcaFareService.populateFare(USD, FareType.electronicRegular, rides, null); assertLegFareEquals(349, rides.get(0), fares, false); assertLegFareEquals(0, rides.get(1), fares, true); @@ -498,8 +497,7 @@ void nullLongName(FareType type) { ) ); - var fare = new ItineraryFares(); - orcaFareService.populateFare(fare, USD, type, legs, null); + var fare = orcaFareService.populateFare(USD, type, legs, null); assertFalse(fare.getLegProducts().isEmpty()); } @@ -520,8 +518,7 @@ void nullShortName(FareType type) { ) ); - var fare = new ItineraryFares(); - orcaFareService.populateFare(fare, USD, type, legs, null); + var fare = orcaFareService.populateFare(USD, type, legs, null); assertFalse(fare.getLegProducts().isEmpty()); } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java index 799e7ef37d7..6c22db217cc 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java @@ -378,15 +378,14 @@ protected Collection fareRulesForFeed(FareType fareType, String fee } @Override - public boolean populateFare( - ItineraryFares fare, + public ItineraryFares populateFare( Currency currency, FareType fareType, - List rides, + List legs, Collection fareRules ) { List transfers = new ArrayList<>(); - for (var ride : rides) { + for (var ride : legs) { Money defaultFare = getLegPrice(ride, fareType, fareRules); if (transfers.isEmpty()) { transfers.add(new ATLTransfer(currency, fareType)); @@ -412,8 +411,8 @@ public boolean populateFare( null, null ); + var fare = ItineraryFares.empty(); fare.addItineraryProducts(List.of(fareProduct)); - - return true; + return fare; } } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index e1d0200aff6..5e8fa6de195 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -117,36 +117,25 @@ public ItineraryFares calculateFares(Itinerary itinerary) { var fareLegsByFeed = fareLegsByFeed(fareLegs); ItineraryFares fare = ItineraryFares.empty(); - boolean hasFare = false; for (FareType fareType : fareRulesPerType.keySet()) { - final Multimap legProducts = LinkedHashMultimap.create(); - List itineraryProducts = new ArrayList<>(); for (String feedId : fareLegsByFeed.keySet()) { - ItineraryFares currentFare = ItineraryFares.empty(); var fareRules = fareRulesForFeed(fareType, feedId); // Get the currency from the first fareAttribute, assuming that all tickets use the same currency. if (fareRules != null && !fareRules.isEmpty()) { Currency currency = fareRules.iterator().next().getFareAttribute().getPrice().currency(); - boolean feedHasFare = populateFare( - currentFare, + ItineraryFares computedFaresForType = populateFare( currency, fareType, fareLegsByFeed.get(feedId), fareRules ); - hasFare = feedHasFare || hasFare; // Other feeds might still have fare for some legs - - legProducts.putAll(currentFare.getLegProducts()); - itineraryProducts.addAll(currentFare.getItineraryProducts()); + fare.add(computedFaresForType); } } - - fare.addFareProductUses(legProducts); - fare.addItineraryProducts(itineraryProducts); } - return hasFare ? fare : null; + return fare; } /** @@ -186,8 +175,7 @@ protected Collection fareRulesForFeed(FareType fareType, String fee * If our only rule were A-B with a fare of 10, we would have no lowest fare, but we will still * have one fare detail with fare 10 for the route A-B. B-C will not just not be listed at all. */ - protected boolean populateFare( - ItineraryFares fare, + protected ItineraryFares populateFare( Currency currency, FareType fareType, List legs, @@ -196,7 +184,6 @@ protected boolean populateFare( FareSearch r = performSearch(fareType, legs, fareRules); Multimap fareProductUses = LinkedHashMultimap.create(); - int count = 0; int start = 0; int end = legs.size() - 1; while (start <= end) { @@ -241,13 +228,12 @@ protected boolean populateFare( }); } - ++count; start = via + 1; } - var amount = r.resultTable[0][legs.size() - 1]; + var fare = ItineraryFares.empty(); fare.addFareProductUses(fareProductUses); - return count > 0; + return fare; } protected Optional calculateCost( diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java index cbb50fd57b9..bd4afb29315 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java @@ -48,8 +48,7 @@ public Duration freeTransferWindow() { * additional free transfers from there. */ @Override - protected boolean populateFare( - ItineraryFares fare, + protected ItineraryFares populateFare( Currency currency, FareType fareType, List legs, @@ -93,8 +92,11 @@ protected boolean populateFare( null, null ); - fare.addItineraryProducts(List.of(fp)); - return cost.greaterThan(zero); + var fare = ItineraryFares.empty(); + if (cost.greaterThan(zero)) { + fare.addItineraryProducts(List.of(fp)); + } + return fare; } @Override diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java index c55e059de7b..5e76ec934d7 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java @@ -396,13 +396,13 @@ protected Optional getRidePrice( * one. */ @Override - public boolean populateFare( - ItineraryFares fare, + public ItineraryFares populateFare( Currency currency, FareType fareType, List legs, Collection fareRules ) { + var fare = ItineraryFares.empty(); ZonedDateTime freeTransferStartTime = null; Money cost = Money.ZERO_USD; Money orcaFareDiscount = Money.ZERO_USD; @@ -484,10 +484,8 @@ public boolean populateFare( .of(new FeedScopedId(FEED_ID, fareType.name()), fareType.name(), cost) .build(); fare.addItineraryProducts(List.of(fp)); - return true; - } else { - return false; } + return fare; } /** diff --git a/src/main/java/org/opentripplanner/model/fare/FareProduct.java b/src/main/java/org/opentripplanner/model/fare/FareProduct.java index c82e128f550..189b73807e7 100644 --- a/src/main/java/org/opentripplanner/model/fare/FareProduct.java +++ b/src/main/java/org/opentripplanner/model/fare/FareProduct.java @@ -51,6 +51,7 @@ public String toString() { return ToStringBuilder .of(FareProduct.class) .addStr("id", id.toString()) + .addStr("name", name) .addObj("amount", price) .addDuration("duration", validity) .addObj("category", category) diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 530c48914c6..3f4cb04e01c 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -103,4 +103,13 @@ public void addFareProduct(Leg leg, Collection fareProduct) { public void addFareProductUses(Multimap fareProducts) { legProducts.putAll(fareProducts); } + + public void add(ItineraryFares fare) { + itineraryProducts.addAll(fare.itineraryProducts); + legProducts.putAll(fare.legProducts); + } + + public boolean isEmpty() { + return itineraryProducts.isEmpty() && legProducts.isEmpty(); + } } From ab426d84ed121d75e4d269616f2017de1bb9c865 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 09:53:56 +0100 Subject: [PATCH 249/356] Update expectations --- .../ext/fares/impl/DefaultFareServiceTest.java | 18 +++++++++--------- .../ext/fares/impl/FaresIntegrationTest.java | 4 ++-- .../flex/trip/ScheduledDeviatedTripTest.java | 5 ++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 32a15f2be0a..3fca4b949e4 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -50,7 +50,7 @@ void simpleZoneBasedFare() { var legProducts = fare.getLegProducts().get(itin.getTransitLeg(0)); assertEquals( - "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", legProducts.toString() ); } @@ -78,7 +78,7 @@ void applyToSeveralLegs() { assertEquals(firstProducts, secondProducts); assertEquals( - "[FareProductUse[id=ddbf1572-18bc-3724-8b64-e1c7d5c8b6c6, product=FareProduct{id: 'F:free-transfers', amount: $20.00}]]", + "[FareProductUse[id=ddbf1572-18bc-3724-8b64-e1c7d5c8b6c6, product=FareProduct{id: 'F:free-transfers', name: 'regular', amount: $20.00}]]", firstProducts.toString() ); } @@ -110,13 +110,13 @@ void shouldNotCombineInterlinedLegs() { var firstLeg = itin.getLegs().getFirst(); assertEquals( - "[FareProductUse[id=ccadd1d3-f284-31a4-9d58-0a300198950f, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + "[FareProductUse[id=ccadd1d3-f284-31a4-9d58-0a300198950f, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", legProducts.get(firstLeg).toString() ); var secondLeg = itin.getLegs().get(1); assertEquals( - "[FareProductUse[id=c58974dd-9a2f-3f42-90ec-c62a7b0dfd51, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + "[FareProductUse[id=c58974dd-9a2f-3f42-90ec-c62a7b0dfd51, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", legProducts.get(secondLeg).toString() ); } @@ -174,12 +174,12 @@ void multipleFeeds() { var legProducts = result.getLegProducts(); var firstBusLeg = itin.getTransitLeg(0); assertEquals( - "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", legProducts.get(firstBusLeg).toString() ); var secondBusLeg = itin.getTransitLeg(2); assertEquals( - "[FareProductUse[id=678d201c-e839-35c3-ae7b-1bc3834da5e5, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + "[FareProductUse[id=678d201c-e839-35c3-ae7b-1bc3834da5e5, product=FareProduct{id: 'F2:other-feed-attribute', name: 'regular', amount: $10.00}]]", legProducts.get(secondBusLeg).toString() ); } @@ -204,15 +204,15 @@ void multipleFeedsWithTransfersWithinFeed() { var finalBusLeg = itin.getTransitLeg(4); assertEquals( - "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', name: 'regular', amount: $10.00}]]", legProducts.get(firstBusLeg).toString() ); assertEquals( - "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', amount: $10.00}]]", + "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", legProducts.get(secondBusLeg).toString() ); assertEquals( - "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', amount: $10.00}]]", + "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', name: 'regular', amount: $10.00}]]", legProducts.get(finalBusLeg).toString() ); } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 6265dc60c1e..344cd2e58b2 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -45,7 +45,7 @@ public void testBasic() { ItineraryFares fare = getFare(from, to, start, serverContext); assertEquals( - "[FareProduct{id: '1:OW_2', amount: $4.25}]", + "[FareProduct{id: '1:OW_2', name: 'regular', amount: $4.25}]", fare.getLegProducts().values().stream().map(FareProductUse::product).toList().toString() ); } @@ -79,7 +79,7 @@ public void testPortland() { ItineraryFares fare = getFare(from, to, startTime, serverContext); assertEquals( - "[FareProductUse[id=26a5a5ee-c7db-37ad-be09-fa3afdce748b, product=FareProduct{id: 'prt:19', amount: $2.00}]]", + "[FareProductUse[id=26a5a5ee-c7db-37ad-be09-fa3afdce748b, product=FareProduct{id: 'prt:19', name: 'regular', amount: $2.00}]]", fare.getLegProducts().values().toString() ); diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index 378d18d7bb4..85b533cbf69 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -146,11 +146,10 @@ void calculateDirectFare() { var itineraries = router.createFlexOnlyItineraries().stream().peek(filter::decorate).toList(); - var itinerary = itineraries.iterator().next(); - assertFalse(itinerary.getFares().getLegProducts().isEmpty()); + var itinerary = itineraries.getFirst(); assertEquals( - "[FareProductUse[id=1532715d-bffe-310c-9c76-842f3c74bbd3, product=FareProduct{id: '1:flex-adult', amount: $2.50}]]", + "[FareProductUse[id=1532715d-bffe-310c-9c76-842f3c74bbd3, product=FareProduct{id: '1:flex-adult', name: 'regular', amount: $2.50}]]", itinerary.getFares().getLegProducts().values().toString() ); From 6d7936f624bde3b339a17adeb527a80ce7788d51 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 10:08:16 +0100 Subject: [PATCH 250/356] Rename methods --- .../ext/fares/impl/AtlantaFareServiceTest.java | 2 +- .../ext/fares/impl/FaresIntegrationTest.java | 9 ++++----- .../ext/fares/impl/OrcaFareServiceTest.java | 6 +++--- .../ext/fares/impl/AtlantaFareService.java | 2 +- .../ext/fares/impl/DefaultFareService.java | 4 ++-- .../impl/HighestFareInFreeTransferWindowFareService.java | 2 +- .../opentripplanner/ext/fares/impl/OrcaFareService.java | 2 +- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java index 39b80deace1..3662d45affa 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/AtlantaFareServiceTest.java @@ -225,7 +225,7 @@ void fullItinerary() { * used. This will be the same for all cash fare types except when overriden above. */ private static void calculateFare(List rides, Money expectedFare) { - var fare = atlFareService.populateFare(USD, FareType.electronicRegular, rides, null); + var fare = atlFareService.calculateFaresForType(USD, FareType.electronicRegular, rides, null); assertEquals( expectedFare, fare diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 344cd2e58b2..90df7481720 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -14,7 +14,6 @@ import org.opentripplanner.TestServerContext; import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.model.GenericLocation; -import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.api.request.RouteRequest; @@ -22,6 +21,7 @@ import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.standalone.api.OtpServerRequestContext; +import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.service.TransitModel; public class FaresIntegrationTest { @@ -44,10 +44,9 @@ public void testBasic() { var to = GenericLocation.fromStopId("Destination", feedId, "Mountain View Caltrain"); ItineraryFares fare = getFare(from, to, start, serverContext); - assertEquals( - "[FareProduct{id: '1:OW_2', name: 'regular', amount: $4.25}]", - fare.getLegProducts().values().stream().map(FareProductUse::product).toList().toString() - ); + var product = fare.getLegProducts().values().iterator().next().product(); + assertEquals(Money.usDollars(4.25f), product.price()); + assertEquals("1:OW_2", product.id().toString()); } @Test diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java index ae8df72dd6a..4d04281ebb6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/OrcaFareServiceTest.java @@ -176,7 +176,7 @@ void calculateFareWithNoFreeTransfer() { @Test void calculateFareByLeg() { List rides = List.of(getLeg(KITSAP_TRANSIT_AGENCY_ID, 0), getLeg(COMM_TRANS_AGENCY_ID, 2)); - var fares = orcaFareService.populateFare(USD, FareType.electronicRegular, rides, null); + var fares = orcaFareService.calculateFaresForType(USD, FareType.electronicRegular, rides, null); assertLegFareEquals(349, rides.get(0), fares, false); assertLegFareEquals(0, rides.get(1), fares, true); @@ -497,7 +497,7 @@ void nullLongName(FareType type) { ) ); - var fare = orcaFareService.populateFare(USD, type, legs, null); + var fare = orcaFareService.calculateFaresForType(USD, type, legs, null); assertFalse(fare.getLegProducts().isEmpty()); } @@ -518,7 +518,7 @@ void nullShortName(FareType type) { ) ); - var fare = orcaFareService.populateFare(USD, type, legs, null); + var fare = orcaFareService.calculateFaresForType(USD, type, legs, null); assertFalse(fare.getLegProducts().isEmpty()); } diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java index 6c22db217cc..fdeb7a975d2 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/AtlantaFareService.java @@ -378,7 +378,7 @@ protected Collection fareRulesForFeed(FareType fareType, String fee } @Override - public ItineraryFares populateFare( + public ItineraryFares calculateFaresForType( Currency currency, FareType fareType, List legs, diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java index 5e8fa6de195..03e6eeff9fd 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/DefaultFareService.java @@ -124,7 +124,7 @@ public ItineraryFares calculateFares(Itinerary itinerary) { // Get the currency from the first fareAttribute, assuming that all tickets use the same currency. if (fareRules != null && !fareRules.isEmpty()) { Currency currency = fareRules.iterator().next().getFareAttribute().getPrice().currency(); - ItineraryFares computedFaresForType = populateFare( + ItineraryFares computedFaresForType = calculateFaresForType( currency, fareType, fareLegsByFeed.get(feedId), @@ -175,7 +175,7 @@ protected Collection fareRulesForFeed(FareType fareType, String fee * If our only rule were A-B with a fare of 10, we would have no lowest fare, but we will still * have one fare detail with fare 10 for the route A-B. B-C will not just not be listed at all. */ - protected ItineraryFares populateFare( + protected ItineraryFares calculateFaresForType( Currency currency, FareType fareType, List legs, diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java index bd4afb29315..3cc9398f7c7 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/HighestFareInFreeTransferWindowFareService.java @@ -48,7 +48,7 @@ public Duration freeTransferWindow() { * additional free transfers from there. */ @Override - protected ItineraryFares populateFare( + protected ItineraryFares calculateFaresForType( Currency currency, FareType fareType, List legs, diff --git a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java index 5e76ec934d7..a02f37417ec 100644 --- a/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java +++ b/src/ext/java/org/opentripplanner/ext/fares/impl/OrcaFareService.java @@ -396,7 +396,7 @@ protected Optional getRidePrice( * one. */ @Override - public ItineraryFares populateFare( + public ItineraryFares calculateFaresForType( Currency currency, FareType fareType, List legs, From dd827066cf0a0bae0d6d5ffd27d15c84b3e0f3f4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 1 Nov 2023 15:03:38 +0100 Subject: [PATCH 251/356] Subtract generalized cost that was previously added --- .../org/opentripplanner/model/plan/Itinerary.java | 14 +++++++++++++- ...onTransitItinerariesBasedOnGeneralizedCost.java | 4 ++-- .../transit/RemoveTransitIfStreetOnlyIsBetter.java | 4 ++-- .../transit/RemoveTransitIfWalkingIsBetter.java | 2 +- .../transit/TransitGeneralizedCostFilter.java | 1 + .../mapping/RaptorPathToItineraryMapper.java | 2 +- 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 903e04c8b0c..8c8981b833d 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -489,7 +489,7 @@ public void setElevationGained(Double elevationGained) { /** * If a generalized cost is used in the routing algorithm, this should be the total cost computed - * by the algorithm. This is relevant for anyone who want to debug an search and tuning the + * by the algorithm. This is relevant for anyone who want to debug a search and tuning the * system. The unit should be equivalent to the cost of "one second of transit". *

      * -1 indicate that the cost is not set/computed. @@ -498,6 +498,10 @@ public int getGeneralizedCost() { return generalizedCost; } + public int getGeneralizedCostIncludingPenalty() { + return generalizedCost - penaltyCost(accessPenalty) - penaltyCost(egressPenalty); + } + public void setGeneralizedCost(int generalizedCost) { this.generalizedCost = generalizedCost; } @@ -663,4 +667,12 @@ public void setEmissionsPerPerson(Emissions emissionsPerPerson) { public Emissions getEmissionsPerPerson() { return this.emissionsPerPerson; } + + private static int penaltyCost(TimeAndCost penalty) { + if (penalty == null) { + return 0; + } else { + return penalty.cost().toSeconds(); + } + } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java index 427084a55f6..1980838bec0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java @@ -43,7 +43,7 @@ public List flagForRemoval(List itineraries) { // ALL itineraries are considered here. Both transit and non-transit OptionalInt minGeneralizedCost = itineraries .stream() - .mapToInt(Itinerary::getGeneralizedCost) + .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) .min(); if (minGeneralizedCost.isEmpty()) { @@ -58,7 +58,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - .filter(it -> !it.hasTransit() && it.getGeneralizedCost() > maxLimit) + .filter(it -> !it.hasTransit() && it.getGeneralizedCostIncludingPenalty() > maxLimit) .collect(Collectors.toList()); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java index bddf5238f23..0e60836ae1c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java @@ -38,7 +38,7 @@ public List flagForRemoval(List itineraries) { OptionalInt minStreetCost = itineraries .stream() .filter(Itinerary::isOnStreetAllTheWay) - .mapToInt(Itinerary::getGeneralizedCost) + .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) .min(); if (minStreetCost.isEmpty()) { @@ -52,7 +52,7 @@ public List flagForRemoval(List itineraries) { // Filter away itineraries that have higher cost than limit cost computed above return itineraries .stream() - .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) + .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCostIncludingPenalty() >= limit) .collect(Collectors.toList()); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java index cf4d102c11a..f37743af0eb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java @@ -38,7 +38,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) + .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCostIncludingPenalty() >= limit) .collect(Collectors.toList()); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java index 4d7ffffa13a..f4516421889 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java @@ -11,6 +11,7 @@ import org.opentripplanner.routing.api.request.framework.CostLinearFunction; /** + * This filter removes all transit results which have a generalized-cost higher than the max-limit * This filter removes all transit results that have a generalized-cost higher than the max-limit * computed by the {@link #costLimitFunction} plus the wait cost given by * {@link TransitGeneralizedCostFilter#getWaitTimeCost}. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index fe20592576e..a399047271c 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -151,7 +151,7 @@ else if (pathLeg.isTransferLeg()) { } if (egressPathLeg.egress() instanceof DefaultAccessEgress ae) { - itinerary.setAccessPenalty(ae.penalty()); + itinerary.setEgressPenalty(ae.penalty()); } if (path.isC2Set()) { itinerary.setGeneralizedCost2(path.c2()); From 022f51bf133ae9429d8d3bc8043133991af17633 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 6 Nov 2023 14:17:10 +0100 Subject: [PATCH 252/356] Add documentation for newly added method --- .../org/opentripplanner/model/plan/Itinerary.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 8c8981b833d..f54a5067f89 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -498,6 +498,18 @@ public int getGeneralizedCost() { return generalizedCost; } + /** + * If a generalized cost is used in the routing algorithm, this should be the cost computed minus + * the artificial penalty added for car access/egresses. This is useful so that itineraries + * using only on-street legs don't have an unfair advantage over those combining access/egress with + * transit and using a penalty when being processed by the itinerary filter chain. + * + * @see Itinerary#getGeneralizedCost() + * @see org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressPenaltyDecorator + * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NonTransitGeneralizedCostFilter + * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfStreetOnlyIsBetterFilter + * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfWalkingIsBetterFilter + */ public int getGeneralizedCostIncludingPenalty() { return generalizedCost - penaltyCost(accessPenalty) - penaltyCost(egressPenalty); } From d8e018ce59ffafdd3cfc255a89bcefc068f43ba3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 6 Nov 2023 14:28:31 +0100 Subject: [PATCH 253/356] Add test for subtracting penalties --- .../model/plan/ItineraryTest.java | 73 ++++++++++++++++--- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index df67e3c2f44..15b1978dea8 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -10,7 +10,10 @@ import static org.opentripplanner.model.plan.TestItineraryBuilder.newTime; import java.time.Duration; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.model.SystemNotice; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model._data.TransitModelForTest; @@ -18,8 +21,10 @@ public class ItineraryTest implements PlanTestConstants { + private static final int DEFAULT_COST = 720; + @Test - public void testDerivedFieldsWithWalkingOnly() { + void testDerivedFieldsWithWalkingOnly() { Itinerary result = newItinerary(A, T11_00).walk(D5m, B).build(); // Expected fields on itinerary set @@ -43,12 +48,12 @@ public void testDerivedFieldsWithWalkingOnly() { } @Test - public void testDerivedFieldsWithBusAllTheWay() { + void testDerivedFieldsWithBusAllTheWay() { Itinerary result = newItinerary(A).bus(55, T11_00, T11_10, B).build(); assertEquals(ofMinutes(10), result.getDuration()); assertEquals(0, result.getNumberOfTransfers()); - assertEquals(720, result.getGeneralizedCost()); + assertEquals(DEFAULT_COST, result.getGeneralizedCost()); assertEquals(ofMinutes(10), result.getTransitDuration()); assertEquals(ZERO, result.getNonTransitDuration()); assertEquals(ZERO, result.getWaitingDuration()); @@ -67,12 +72,12 @@ public void testDerivedFieldsWithBusAllTheWay() { } @Test - public void testDerivedFieldsWithTrainAllTheWay() { + void testDerivedFieldsWithTrainAllTheWay() { Itinerary result = newItinerary(A).rail(20, T11_05, T11_15, B).build(); assertEquals(ofMinutes(10), result.getDuration()); assertEquals(0, result.getNumberOfTransfers()); - assertEquals(720, result.getGeneralizedCost()); + assertEquals(DEFAULT_COST, result.getGeneralizedCost()); assertEquals(ofMinutes(10), result.getTransitDuration()); assertEquals(ZERO, result.getNonTransitDuration()); assertEquals(ZERO, result.getWaitingDuration()); @@ -91,7 +96,7 @@ public void testDerivedFieldsWithTrainAllTheWay() { } @Test - public void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { + void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { Itinerary itinerary = TestItineraryBuilder .newItinerary(A, T11_02) .walk(D1m, B) @@ -112,7 +117,7 @@ public void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { } @Test - public void testDerivedFieldsWithBusAndWalkingAccessAndEgress() { + void testDerivedFieldsWithBusAndWalkingAccessAndEgress() { Itinerary result = newItinerary(A, T11_05) .walk(D2m, B) // 3 minutes wait @@ -133,7 +138,7 @@ public void testDerivedFieldsWithBusAndWalkingAccessAndEgress() { } @Test - public void walkBusBusWalkTrainWalk() { + void walkBusBusWalkTrainWalk() { Itinerary result = newItinerary(A, T11_00) .walk(D2m, B) .bus(55, T11_04, T11_14, C) @@ -148,7 +153,7 @@ public void walkBusBusWalkTrainWalk() { assertEquals(ofMinutes(34), result.getTransitDuration()); assertEquals(ofMinutes(6), result.getNonTransitDuration()); assertEquals(ofMinutes(11), result.getWaitingDuration()); - assertEquals(720 + 528 + 360 + 2040, result.getGeneralizedCost()); + assertEquals(DEFAULT_COST + 528 + 360 + 2040, result.getGeneralizedCost()); assertFalse(result.isWalkOnly()); assertSameLocation(A, result.firstLeg().getFrom()); assertSameLocation(G, result.lastLeg().getTo()); @@ -161,7 +166,7 @@ public void walkBusBusWalkTrainWalk() { } @Test - public void legIndex() { + void legIndex() { var itinerary = newItinerary(A, T11_00) .walk(D2m, B) .bus(55, T11_04, T11_14, C) @@ -181,12 +186,58 @@ public void legIndex() { } @Test - public void hasSystemTag() { + void hasSystemTag() { var subject = newItinerary(A).bus(1, T11_04, T11_14, B).build(); subject.flagForDeletion(new SystemNotice("MY-TAG", "Text")); assertTrue(subject.hasSystemNoticeTag("MY-TAG")); } + @Nested + class AccessEgressPenalty { + + private static final TimeAndCost PENALTY = new TimeAndCost( + Duration.ofMinutes(10), + Cost.costOfMinutes(2) + ); + private static final int COST_MINUS_TWO_MINUTES = DEFAULT_COST - 120; + + @Test + void noPenalty() { + var subject = itinerary(); + assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); + assertEquals(DEFAULT_COST, subject.getGeneralizedCostIncludingPenalty()); + } + + @Test + void accessPenalty() { + var subject = itinerary(); + subject.setAccessPenalty(PENALTY); + assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); + assertEquals(COST_MINUS_TWO_MINUTES, subject.getGeneralizedCostIncludingPenalty()); + } + + @Test + void egressPenalty() { + var subject = itinerary(); + subject.setEgressPenalty(PENALTY); + assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); + assertEquals(COST_MINUS_TWO_MINUTES, subject.getGeneralizedCostIncludingPenalty()); + } + + @Test + void bothPenalties() { + var subject = itinerary(); + subject.setAccessPenalty(PENALTY); + subject.setEgressPenalty(PENALTY); + assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); + assertEquals(480, subject.getGeneralizedCostIncludingPenalty()); + } + + private static Itinerary itinerary() { + return newItinerary(A).bus(1, T11_04, T11_14, B).build(); + } + } + private void assertSameLocation(Place expected, Place actual) { assertTrue( expected.sameLocation(actual), From bee9dcd8a85cf8639b80fba1c0656cbbeec63b84 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 6 Nov 2023 15:27:44 +0100 Subject: [PATCH 254/356] Add test for RemoveTransitIfStreetOnlyIsBetterFilter --- .../RemoveTransitIfStreetOnlyIsBetter.java | 2 ++ .../RemoveTransitIfWalkingIsBetter.java | 2 ++ ...RemoveTransitIfStreetOnlyIsBetterTest.java | 28 +++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java index 0e60836ae1c..df40bd47e27 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java @@ -52,6 +52,8 @@ public List flagForRemoval(List itineraries) { // Filter away itineraries that have higher cost than limit cost computed above return itineraries .stream() + // we use the cost including the access/egress penalty since we don't want to give + // searches that are only on the street network an unfair advantage .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCostIncludingPenalty() >= limit) .collect(Collectors.toList()); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java index f37743af0eb..e51e17a72e5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java @@ -38,6 +38,8 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() + // we use the cost including the access/egress penalty since we don't want to give + // searches that are only on the street network an unfair advantage .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCostIncludingPenalty() >= limit) .collect(Collectors.toList()); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java index df45bcf4538..ea4ca272304 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java @@ -7,6 +7,8 @@ import java.time.Duration; import java.util.List; import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; @@ -15,7 +17,7 @@ public class RemoveTransitIfStreetOnlyIsBetterTest implements PlanTestConstants { @Test - public void filterAwayNothingIfNoWalking() { + void filterAwayNothingIfNoWalking() { // Given: Itinerary i1 = newItinerary(A).bus(21, 6, 7, E).build(); Itinerary i2 = newItinerary(A).rail(110, 6, 9, E).build(); @@ -31,7 +33,7 @@ public void filterAwayNothingIfNoWalking() { } @Test - public void filterAwayLongTravelTimeWithoutWaitTime() { + void filterAwayLongTravelTimeWithoutWaitTime() { // Given: a walk itinerary with high cost - do not have any effect on filtering Itinerary walk = newItinerary(A, 6).walk(1, E).build(); walk.setGeneralizedCost(300); @@ -57,4 +59,26 @@ public void filterAwayLongTravelTimeWithoutWaitTime() { // Then: assertEquals(toStr(List.of(bicycle, walk, i1)), toStr(result)); } + + @Test + void considerPenalties() { + Itinerary walk = newItinerary(A, 6).walk(1, E).build(); + walk.setGeneralizedCost(300); + + // transit has a much higher cost than walking, however it also has a high penalty which is + // subtracted when comparing the itineraries + Itinerary busWithPenalty = newItinerary(A).bus(21, 6, 8, E).build(); + busWithPenalty.setGeneralizedCost(600); + busWithPenalty.setAccessPenalty(new TimeAndCost(Duration.ZERO, Cost.costOfSeconds(400))); + + // When: + var itineraries = List.of(walk, busWithPenalty); + List result = DeletionFlaggerTestHelper.process( + itineraries, + new RemoveTransitIfStreetOnlyIsBetterFilter(CostLinearFunction.of(Duration.ZERO, 1.0)) + ); + + // Then: + assertEquals(toStr(itineraries), toStr(result)); + } } From 8059506a3f2208e50c58f7dd6029920c994c86f3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 7 Nov 2023 16:44:50 +0100 Subject: [PATCH 255/356] Invert relationship of generalized cost and penalty --- .../opentripplanner/model/plan/Itinerary.java | 8 ++--- ...nsitItinerariesBasedOnGeneralizedCost.java | 4 +-- .../RemoveTransitIfStreetOnlyIsBetter.java | 4 +-- .../RemoveTransitIfWalkingIsBetter.java | 2 +- .../mapping/RaptorPathToItineraryMapper.java | 6 +++- .../model/plan/ItineraryTest.java | 13 ++++---- .../raptor/_data/api/TestPathBuilder.java | 9 ++++-- .../_data/transit/TestAccessEgress.java | 18 +++++++++++ ...RemoveTransitIfStreetOnlyIsBetterTest.java | 6 ++-- .../RaptorPathToItineraryMapperTest.java | 30 ++++++++++++++++--- 10 files changed, 76 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index f54a5067f89..9854facdf5e 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -499,8 +499,8 @@ public int getGeneralizedCost() { } /** - * If a generalized cost is used in the routing algorithm, this should be the cost computed minus - * the artificial penalty added for car access/egresses. This is useful so that itineraries + * If a generalized cost is used in the routing algorithm, this is the cost computed plus + * the artificial penalty added for access/egresses. This is useful so that itineraries * using only on-street legs don't have an unfair advantage over those combining access/egress with * transit and using a penalty when being processed by the itinerary filter chain. * @@ -510,8 +510,8 @@ public int getGeneralizedCost() { * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfStreetOnlyIsBetterFilter * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfWalkingIsBetterFilter */ - public int getGeneralizedCostIncludingPenalty() { - return generalizedCost - penaltyCost(accessPenalty) - penaltyCost(egressPenalty); + public int getGeneralizedCostPlusPenalty() { + return generalizedCost + penaltyCost(accessPenalty) + penaltyCost(egressPenalty); } public void setGeneralizedCost(int generalizedCost) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java index 1980838bec0..427084a55f6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java @@ -43,7 +43,7 @@ public List flagForRemoval(List itineraries) { // ALL itineraries are considered here. Both transit and non-transit OptionalInt minGeneralizedCost = itineraries .stream() - .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) + .mapToInt(Itinerary::getGeneralizedCost) .min(); if (minGeneralizedCost.isEmpty()) { @@ -58,7 +58,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - .filter(it -> !it.hasTransit() && it.getGeneralizedCostIncludingPenalty() > maxLimit) + .filter(it -> !it.hasTransit() && it.getGeneralizedCost() > maxLimit) .collect(Collectors.toList()); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java index df40bd47e27..535676f4574 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java @@ -38,7 +38,7 @@ public List flagForRemoval(List itineraries) { OptionalInt minStreetCost = itineraries .stream() .filter(Itinerary::isOnStreetAllTheWay) - .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) + .mapToInt(Itinerary::getGeneralizedCost) .min(); if (minStreetCost.isEmpty()) { @@ -54,7 +54,7 @@ public List flagForRemoval(List itineraries) { .stream() // we use the cost including the access/egress penalty since we don't want to give // searches that are only on the street network an unfair advantage - .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCostIncludingPenalty() >= limit) + .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) .collect(Collectors.toList()); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java index e51e17a72e5..19f6970affb 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java @@ -40,7 +40,7 @@ public List flagForRemoval(List itineraries) { .stream() // we use the cost including the access/egress penalty since we don't want to give // searches that are only on the street network an unfair advantage - .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCostIncludingPenalty() >= limit) + .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) .collect(Collectors.toList()); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index a399047271c..6e365b4cd49 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -134,7 +134,6 @@ else if (pathLeg.isTransferLeg()) { Itinerary itinerary = new Itinerary(legs); // Map general itinerary fields - itinerary.setGeneralizedCost(toOtpDomainCost(path.c1())); itinerary.setArrivedAtDestinationWithRentedVehicle( mapped != null && mapped.isArrivedAtDestinationWithRentedVehicle() ); @@ -146,17 +145,22 @@ else if (pathLeg.isTransferLeg()) { itinerary.setTransferPriorityCost(toOtpDomainCost(optimizedPath.transferPriorityCost())); } + var penaltyCost = 0; if (accessPathLeg.access() instanceof DefaultAccessEgress ae) { itinerary.setAccessPenalty(ae.penalty()); + penaltyCost += ae.penalty().cost().toSeconds(); } if (egressPathLeg.egress() instanceof DefaultAccessEgress ae) { itinerary.setEgressPenalty(ae.penalty()); + penaltyCost += ae.penalty().cost().toSeconds(); } if (path.isC2Set()) { itinerary.setGeneralizedCost2(path.c2()); } + itinerary.setGeneralizedCost(toOtpDomainCost(path.c1()) - penaltyCost); + return itinerary; } diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index 15b1978dea8..ee8f776c7ab 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -199,13 +199,13 @@ class AccessEgressPenalty { Duration.ofMinutes(10), Cost.costOfMinutes(2) ); - private static final int COST_MINUS_TWO_MINUTES = DEFAULT_COST - 120; + private static final int COST_PLUS_TWO_MINUTES = DEFAULT_COST + 120; @Test void noPenalty() { var subject = itinerary(); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(DEFAULT_COST, subject.getGeneralizedCostIncludingPenalty()); + assertEquals(DEFAULT_COST, subject.getGeneralizedCostPlusPenalty()); } @Test @@ -213,7 +213,7 @@ void accessPenalty() { var subject = itinerary(); subject.setAccessPenalty(PENALTY); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(COST_MINUS_TWO_MINUTES, subject.getGeneralizedCostIncludingPenalty()); + assertEquals(COST_PLUS_TWO_MINUTES, subject.getGeneralizedCostPlusPenalty()); } @Test @@ -221,7 +221,7 @@ void egressPenalty() { var subject = itinerary(); subject.setEgressPenalty(PENALTY); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(COST_MINUS_TWO_MINUTES, subject.getGeneralizedCostIncludingPenalty()); + assertEquals(COST_PLUS_TWO_MINUTES, subject.getGeneralizedCostPlusPenalty()); } @Test @@ -230,7 +230,10 @@ void bothPenalties() { subject.setAccessPenalty(PENALTY); subject.setEgressPenalty(PENALTY); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(480, subject.getGeneralizedCostIncludingPenalty()); + assertEquals( + DEFAULT_COST + PENALTY.cost().toSeconds() + PENALTY.cost().toSeconds(), + subject.getGeneralizedCostPlusPenalty() + ); } private static Itinerary itinerary() { diff --git a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java b/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java index 19d9904cd5b..007018ca6c4 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java +++ b/src/test/java/org/opentripplanner/raptor/_data/api/TestPathBuilder.java @@ -122,8 +122,13 @@ public RaptorPath egress(int duration) { ); } - public RaptorPath egress(TestAccessEgress transfer) { - builder.egress(transfer); + public PathBuilder access(TestAccessEgress access) { + builder.access(access); + return builder; + } + + public RaptorPath egress(TestAccessEgress egress) { + builder.egress(egress); builder.c2(c2); return builder.build(); } diff --git a/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java b/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java index 56957e2e33a..ed0702f39d5 100644 --- a/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java +++ b/src/test/java/org/opentripplanner/raptor/_data/transit/TestAccessEgress.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; @@ -32,6 +33,7 @@ public class TestAccessEgress implements RaptorAccessEgress { private final Integer opening; private final Integer closing; private final boolean closed; + private final TimeAndCost penalty; private TestAccessEgress(Builder builder) { this.stop = builder.stop; @@ -43,6 +45,7 @@ private TestAccessEgress(Builder builder) { this.opening = builder.opening; this.closing = builder.closing; this.closed = builder.closed; + this.penalty = builder.penalty; if (free) { assertEquals(0, durationInSeconds); @@ -119,6 +122,14 @@ public static TestAccessEgress flexAndWalk(int stop, int durationInSeconds, int return flexAndWalk(stop, durationInSeconds, nRides, walkCost(durationInSeconds)); } + public static TestAccessEgress car(int stop, int durationInSeconds, TimeAndCost penalty) { + return new Builder(stop, durationInSeconds) + .withFree() + .withCost(durationInSeconds) + .withPenalty(penalty) + .build(); + } + /** Create a flex access arriving at given stop by walking. */ public static TestAccessEgress flexAndWalk( int stop, @@ -272,6 +283,7 @@ protected static class Builder { Integer closing = null; private boolean free = false; private boolean closed = false; + private TimeAndCost penalty; Builder(int stop, int durationInSeconds) { this.stop = stop; @@ -289,6 +301,7 @@ protected static class Builder { this.opening = original.opening; this.closing = original.closing; this.closed = original.closed; + this.penalty = original.penalty; } Builder withFree() { @@ -312,6 +325,11 @@ Builder stopReachedOnBoard() { return this; } + Builder withPenalty(TimeAndCost penalty) { + this.penalty = penalty; + return this; + } + Builder withOpeningHours(int opening, int closing) { if (opening > closing) { throw new IllegalStateException( diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java index ea4ca272304..ee9e347c5a0 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java @@ -65,10 +65,10 @@ void considerPenalties() { Itinerary walk = newItinerary(A, 6).walk(1, E).build(); walk.setGeneralizedCost(300); - // transit has a much higher cost than walking, however it also has a high penalty which is - // subtracted when comparing the itineraries + // transit slightly lower cost, however it also has a high penalty which is + // not taken into account when comparing the itineraries Itinerary busWithPenalty = newItinerary(A).bus(21, 6, 8, E).build(); - busWithPenalty.setGeneralizedCost(600); + busWithPenalty.setGeneralizedCost(299); busWithPenalty.setAccessPenalty(new TimeAndCost(Duration.ZERO, Cost.costOfSeconds(400))); // When: diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java index ffd2a5f8591..674a57ccd15 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java @@ -1,9 +1,11 @@ package org.opentripplanner.routing.algorithm.mapping; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.opentripplanner.raptor._data.RaptorTestConstants.BOARD_SLACK; +import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; import java.time.Month; @@ -14,6 +16,8 @@ import org.junit.jupiter.params.provider.ValueSource; import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.ext.flex.FlexAccessEgress; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; @@ -82,13 +86,13 @@ public class RaptorPathToItineraryMapperTest { private static final RegularStop S2 = TEST_MODEL.stop("STOP2", 1.0, 1.0).build(); @ParameterizedTest - @ValueSource(strings = { "0", "3000", "-3000" }) - public void createItineraryTestZeroDurationEgress(int LAST_LEG_COST) { + @ValueSource(ints = { 0, 3000, -3000 }) + void createItineraryTestZeroDurationEgress(int lastLegCost) { // Arrange RaptorPathToItineraryMapper mapper = getRaptorPathToItineraryMapper(); RaptorPath path = createTestTripSchedulePath(getTestTripSchedule()) - .egress(TestAccessEgress.free(2, RaptorCostConverter.toRaptorCost(LAST_LEG_COST))); + .egress(TestAccessEgress.free(2, RaptorCostConverter.toRaptorCost(lastLegCost))); int transitLegCost = path.accessLeg().nextLeg().c1(); int egressLegCost = path.accessLeg().nextLeg().nextLeg().c1(); @@ -106,12 +110,30 @@ public void createItineraryTestZeroDurationEgress(int LAST_LEG_COST) { ); } + @Test + void penalty() { + // Arrange + RaptorPathToItineraryMapper mapper = getRaptorPathToItineraryMapper(); + + var penalty = new TimeAndCost(Duration.ofMinutes(10), Cost.costOfMinutes(10)); + RaptorPath path = createTestTripSchedulePath(getTestTripSchedule()) + .egress(TestAccessEgress.car(2, RaptorCostConverter.toRaptorCost(1000), penalty)); + + // Act + var itinerary = mapper.createItinerary(path); + + // Assert + assertNotNull(itinerary); + assertEquals(4708, itinerary.getGeneralizedCost()); + assertNotEquals(4708, itinerary.getGeneralizedCostPlusPenalty()); + } + /** * Create a minimalist path FlexAccess-->Transfer-->Egress (without transit) and check that the 3 legs * are properly mapped in the itinerary. */ @Test - public void createItineraryWithOnBoardFlexAccess() { + void createItineraryWithOnBoardFlexAccess() { RaptorPathToItineraryMapper mapper = getRaptorPathToItineraryMapper(); State state = TestStateBuilder.ofWalking().streetEdge().streetEdge().build(); From 984d5804f6b971a785922608484376b87193588b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 20 Dec 2023 13:14:07 +0100 Subject: [PATCH 256/356] Document fix tests --- .../transit/RemoveTransitIfStreetOnlyIsBetter.java | 5 +++-- .../filters/transit/RemoveTransitIfWalkingIsBetter.java | 2 +- .../transit/RemoveTransitIfStreetOnlyIsBetterTest.java | 9 +++++---- .../mapping/RaptorPathToItineraryMapperTest.java | 2 ++ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java index 535676f4574..1cea1d1f2ba 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java @@ -52,8 +52,9 @@ public List flagForRemoval(List itineraries) { // Filter away itineraries that have higher cost than limit cost computed above return itineraries .stream() - // we use the cost including the access/egress penalty since we don't want to give - // searches that are only on the street network an unfair advantage + // we use the cost without the access/egress penalty since we don't want to give + // searches that are only on the street network an unfair advantage (they don't have + // access/egress so cannot have these penalties) .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) .collect(Collectors.toList()); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java index 19f6970affb..01ffef0efa4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfWalkingIsBetter.java @@ -38,7 +38,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - // we use the cost including the access/egress penalty since we don't want to give + // we use the cost without the access/egress penalty since we don't want to give // searches that are only on the street network an unfair advantage .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) .collect(Collectors.toList()); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java index ee9e347c5a0..91ab7cfcea6 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java @@ -65,7 +65,7 @@ void considerPenalties() { Itinerary walk = newItinerary(A, 6).walk(1, E).build(); walk.setGeneralizedCost(300); - // transit slightly lower cost, however it also has a high penalty which is + // transit has slightly lower cost, however it also has a high penalty which is // not taken into account when comparing the itineraries Itinerary busWithPenalty = newItinerary(A).bus(21, 6, 8, E).build(); busWithPenalty.setGeneralizedCost(299); @@ -73,11 +73,12 @@ void considerPenalties() { // When: var itineraries = List.of(walk, busWithPenalty); - List result = DeletionFlaggerTestHelper.process( - itineraries, - new RemoveTransitIfStreetOnlyIsBetterFilter(CostLinearFunction.of(Duration.ZERO, 1.0)) + var flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( + CostLinearFunction.of(Duration.ZERO, 1.0) ); + List result = flagger.removeMatchesForTest(itineraries); + // Then: assertEquals(toStr(itineraries), toStr(result)); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java index 674a57ccd15..87566172b1a 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java @@ -11,6 +11,7 @@ import java.time.Month; import java.util.ArrayList; import java.util.HashMap; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -111,6 +112,7 @@ void createItineraryTestZeroDurationEgress(int lastLegCost) { } @Test + @Disabled("Need to write a general test framework to enable this.") void penalty() { // Arrange RaptorPathToItineraryMapper mapper = getRaptorPathToItineraryMapper(); From d0be3015bdd46c372b3b7cea5f5f2050a102501f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 20 Dec 2023 13:23:23 +0100 Subject: [PATCH 257/356] Flesh out test --- ...RemoveTransitIfStreetOnlyIsBetterTest.java | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java index 91ab7cfcea6..a2759a3bac4 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java @@ -6,6 +6,7 @@ import java.time.Duration; import java.util.List; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.TimeAndCost; @@ -60,26 +61,50 @@ void filterAwayLongTravelTimeWithoutWaitTime() { assertEquals(toStr(List.of(bicycle, walk, i1)), toStr(result)); } - @Test - void considerPenalties() { - Itinerary walk = newItinerary(A, 6).walk(1, E).build(); - walk.setGeneralizedCost(300); - - // transit has slightly lower cost, however it also has a high penalty which is - // not taken into account when comparing the itineraries - Itinerary busWithPenalty = newItinerary(A).bus(21, 6, 8, E).build(); - busWithPenalty.setGeneralizedCost(299); - busWithPenalty.setAccessPenalty(new TimeAndCost(Duration.ZERO, Cost.costOfSeconds(400))); + @Nested + class AccessEgressPenalties { - // When: - var itineraries = List.of(walk, busWithPenalty); - var flagger = new RemoveTransitIfStreetOnlyIsBetterFilter( + private static final RemoveTransitIfStreetOnlyIsBetterFilter FLAGGER = new RemoveTransitIfStreetOnlyIsBetterFilter( CostLinearFunction.of(Duration.ZERO, 1.0) ); - List result = flagger.removeMatchesForTest(itineraries); + @Test + void keepBusWithLowCostAndPenalty() { + Itinerary walk = newItinerary(A, 6).walk(1, E).build(); + walk.setGeneralizedCost(300); - // Then: - assertEquals(toStr(itineraries), toStr(result)); + // transit has slightly lower cost, however it also has a high penalty which is + // not taken into account when comparing the itineraries + Itinerary busWithPenalty = newItinerary(A).bus(21, 6, 8, E).build(); + busWithPenalty.setGeneralizedCost(299); + busWithPenalty.setAccessPenalty(new TimeAndCost(Duration.ZERO, Cost.costOfSeconds(360))); + + // When: + var itineraries = List.of(walk, busWithPenalty); + + List result = FLAGGER.removeMatchesForTest(itineraries); + + // Then: + assertEquals(toStr(itineraries), toStr(result)); + } + + @Test + void removeBusWithHighCostAndNoPenalty() { + Itinerary walk = newItinerary(A, 6).walk(1, E).build(); + walk.setGeneralizedCost(300); + + // transit has slightly lower cost, however it also has a high penalty which is + // not taken into account when comparing the itineraries + Itinerary bus = newItinerary(A).bus(21, 6, 8, E).build(); + bus.setGeneralizedCost(301); + + // When: + var itineraries = List.of(walk, bus); + + List result = FLAGGER.removeMatchesForTest(itineraries); + + // Then: + assertEquals(toStr(List.of(walk)), toStr(result)); + } } } From b766ff9bac925a2b1070d7dc6a0c17ab8354a825 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 20 Dec 2023 22:20:27 +0100 Subject: [PATCH 258/356] Fix transmodel API type --- .../transmodel/model/framework/PenaltyForStreetModeType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java index 9fd91832117..6d945ae912f 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/framework/PenaltyForStreetModeType.java @@ -2,6 +2,7 @@ import graphql.Scalars; import graphql.language.ArrayValue; +import graphql.language.EnumValue; import graphql.language.FloatValue; import graphql.language.ObjectField; import graphql.language.ObjectValue; @@ -139,7 +140,7 @@ private static Value mapPenaltyForStreetMode( ObjectField .newObjectField() .name(FIELD_STREET_MODE) - .value((Value) streetModeGQL.getValue()) + .value(EnumValue.of(streetModeGQL.getName())) .build() ) .objectField( From 37a5d12b7aa561342b6ea275ff02babe85c8d6a3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 11:08:26 +0100 Subject: [PATCH 259/356] Update all relevant filters to use correct method --- .../org/opentripplanner/model/plan/Itinerary.java | 9 +++++---- .../model/plan/ItinerarySortKey.java | 4 ++-- .../plan/paging/cursor/DeduplicationPageCut.java | 2 +- .../plan/paging/cursor/PageCursorSerializer.java | 2 +- .../RemoveTransitIfStreetOnlyIsBetter.java | 2 +- .../transit/TransitGeneralizedCostFilter.java | 6 +++--- ...RemoveOtherThanSameLegsMaxGeneralizedCost.java | 6 +++--- .../framework/sort/SortOnGeneralizedCost.java | 15 --------------- .../framework/sort/SortOrderComparator.java | 2 +- .../opentripplanner/model/plan/ItineraryTest.java | 8 ++++---- .../RemoveTransitIfStreetOnlyIsBetterTest.java | 2 +- .../mapping/RaptorPathToItineraryMapperTest.java | 2 +- 12 files changed, 23 insertions(+), 37 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 9854facdf5e..3da1b20e4db 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -506,11 +506,12 @@ public int getGeneralizedCost() { * * @see Itinerary#getGeneralizedCost() * @see org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressPenaltyDecorator - * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.NonTransitGeneralizedCostFilter - * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfStreetOnlyIsBetterFilter - * @see org.opentripplanner.routing.algorithm.filterchain.deletionflagger.RemoveTransitIfWalkingIsBetterFilter + * @see org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveNonTransitItinerariesBasedOnGeneralizedCost + * @see org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfStreetOnlyIsBetter + * @see org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfWalkingIsBetter */ - public int getGeneralizedCostPlusPenalty() { + @Override + public int getGeneralizedCostIncludingPenalty() { return generalizedCost + penaltyCost(accessPenalty) + penaltyCost(egressPenalty); } diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java index 0ad62927d9a..18939c95f8c 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerarySortKey.java @@ -16,7 +16,7 @@ public interface ItinerarySortKey { Instant startTimeAsInstant(); Instant endTimeAsInstant(); - int getGeneralizedCost(); + int getGeneralizedCostIncludingPenalty(); int getNumberOfTransfers(); boolean isOnStreetAllTheWay(); @@ -28,7 +28,7 @@ default String keyAsString() { .addText(", ") .addTime(endTimeAsInstant()) .addText(", ") - .addCost(getGeneralizedCost()) + .addCost(getGeneralizedCostIncludingPenalty()) .addText(", Tx") .addNum(getNumberOfTransfers()) .addText(", ") diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java b/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java index 611b8116b8b..8fb32e6291a 100644 --- a/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java +++ b/src/main/java/org/opentripplanner/model/plan/paging/cursor/DeduplicationPageCut.java @@ -29,7 +29,7 @@ public Instant endTimeAsInstant() { } @Override - public int getGeneralizedCost() { + public int getGeneralizedCostIncludingPenalty() { return generalizedCost; } diff --git a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java b/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java index 98f64c68062..396c7499d2f 100644 --- a/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java +++ b/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorSerializer.java @@ -58,7 +58,7 @@ public static String encode(PageCursor cursor) { .withTimeInstant(CUT_DEPARTURE_TIME_FIELD, cut.startTimeAsInstant()) .withTimeInstant(CUT_ARRIVAL_TIME_FIELD, cut.endTimeAsInstant()) .withInt(CUT_N_TRANSFERS_FIELD, cut.getNumberOfTransfers()) - .withInt(CUT_COST_FIELD, cut.getGeneralizedCost()); + .withInt(CUT_COST_FIELD, cut.getGeneralizedCostIncludingPenalty()); } return tokenBuilder.build(); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java index 1cea1d1f2ba..5fa57ee0801 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java @@ -56,7 +56,7 @@ public List flagForRemoval(List itineraries) { // searches that are only on the street network an unfair advantage (they don't have // access/egress so cannot have these penalties) .filter(it -> !it.isOnStreetAllTheWay() && it.getGeneralizedCost() >= limit) - .collect(Collectors.toList()); + .toList(); } @Override diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java index f4516421889..14670038512 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java @@ -37,7 +37,7 @@ public List flagForRemoval(List itineraries) { List transitItineraries = itineraries .stream() .filter(Itinerary::hasTransit) - .sorted(Comparator.comparingInt(Itinerary::getGeneralizedCost)) + .sorted(Comparator.comparingInt(Itinerary::getGeneralizedCostIncludingPenalty)) .toList(); return transitItineraries @@ -47,13 +47,13 @@ public List flagForRemoval(List itineraries) { } private boolean generalizedCostExceedsLimit(Itinerary subject, Itinerary transitItinerary) { - return subject.getGeneralizedCost() > calculateLimit(subject, transitItinerary); + return subject.getGeneralizedCostIncludingPenalty() > calculateLimit(subject, transitItinerary); } private int calculateLimit(Itinerary subject, Itinerary transitItinerary) { return ( costLimitFunction - .calculate(Cost.costOfSeconds(transitItinerary.getGeneralizedCost())) + .calculate(Cost.costOfSeconds(transitItinerary.getGeneralizedCostIncludingPenalty())) .toSeconds() + getWaitTimeCost(transitItinerary, subject) ); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java index 0194cfa2bbc..52d09161947 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/group/RemoveOtherThanSameLegsMaxGeneralizedCost.java @@ -12,7 +12,7 @@ import org.opentripplanner.transit.model.timetable.Trip; /** - * This filter remove itineraries, which use the same trips for most of their legs, but where some + * This filter removes itineraries, which use the same trips for most of their legs, but where some * itineraries have a much higher cost for the other legs. This is similar to {@link * org.opentripplanner.routing.algorithm.filterchain.filters.transit.TransitGeneralizedCostFilter}, * but is used together with {@link GroupByFilter} to filter within the groups. @@ -79,7 +79,7 @@ public List flagForRemoval(List itineraries) { // Find the lowest cost for any itinerary OptionalInt minimumCost = itineraries .stream() - .mapToInt(itinerary -> itinerary.getGeneralizedCost()) + .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) .min(); if (minimumCost.isEmpty()) { @@ -93,7 +93,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - .filter(it -> it.getGeneralizedCost() > maxLimit) + .filter(it -> it.getGeneralizedCostIncludingPenalty() > maxLimit) .collect(Collectors.toList()); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java deleted file mode 100644 index 10c10362c46..00000000000 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOnGeneralizedCost.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.opentripplanner.routing.algorithm.filterchain.framework.sort; - -import org.opentripplanner.framework.collection.CompositeComparator; -import org.opentripplanner.model.plan.ItinerarySortKey; - -/** - * This comparator sorts itineraries based on the generalized-cost. If the cost is the same then the - * filter pick the itinerary with the lowest number-of-transfers. - */ -public class SortOnGeneralizedCost extends CompositeComparator { - - public SortOnGeneralizedCost() { - super(SortOrderComparator.GENERALIZED_COST_COMP, SortOrderComparator.NUM_OF_TRANSFERS_COMP); - } -} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java index 475309eeae4..f11caf5ceaa 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/framework/sort/SortOrderComparator.java @@ -36,7 +36,7 @@ public class SortOrderComparator extends CompositeComparator { .reversed(); static final Comparator GENERALIZED_COST_COMP = comparingInt( - ItinerarySortKey::getGeneralizedCost + ItinerarySortKey::getGeneralizedCostIncludingPenalty ); static final Comparator NUM_OF_TRANSFERS_COMP = comparingInt( diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index ee8f776c7ab..952479353c2 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -205,7 +205,7 @@ class AccessEgressPenalty { void noPenalty() { var subject = itinerary(); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(DEFAULT_COST, subject.getGeneralizedCostPlusPenalty()); + assertEquals(DEFAULT_COST, subject.getGeneralizedCostIncludingPenalty()); } @Test @@ -213,7 +213,7 @@ void accessPenalty() { var subject = itinerary(); subject.setAccessPenalty(PENALTY); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(COST_PLUS_TWO_MINUTES, subject.getGeneralizedCostPlusPenalty()); + assertEquals(COST_PLUS_TWO_MINUTES, subject.getGeneralizedCostIncludingPenalty()); } @Test @@ -221,7 +221,7 @@ void egressPenalty() { var subject = itinerary(); subject.setEgressPenalty(PENALTY); assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); - assertEquals(COST_PLUS_TWO_MINUTES, subject.getGeneralizedCostPlusPenalty()); + assertEquals(COST_PLUS_TWO_MINUTES, subject.getGeneralizedCostIncludingPenalty()); } @Test @@ -232,7 +232,7 @@ void bothPenalties() { assertEquals(DEFAULT_COST, subject.getGeneralizedCost()); assertEquals( DEFAULT_COST + PENALTY.cost().toSeconds() + PENALTY.cost().toSeconds(), - subject.getGeneralizedCostPlusPenalty() + subject.getGeneralizedCostIncludingPenalty() ); } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java index a2759a3bac4..4da3e83b460 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java @@ -64,7 +64,7 @@ void filterAwayLongTravelTimeWithoutWaitTime() { @Nested class AccessEgressPenalties { - private static final RemoveTransitIfStreetOnlyIsBetterFilter FLAGGER = new RemoveTransitIfStreetOnlyIsBetterFilter( + private static final RemoveTransitIfStreetOnlyIsBetter FLAGGER = new RemoveTransitIfStreetOnlyIsBetter( CostLinearFunction.of(Duration.ZERO, 1.0) ); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java index 87566172b1a..2b8f792a455 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapperTest.java @@ -127,7 +127,7 @@ void penalty() { // Assert assertNotNull(itinerary); assertEquals(4708, itinerary.getGeneralizedCost()); - assertNotEquals(4708, itinerary.getGeneralizedCostPlusPenalty()); + assertNotEquals(4708, itinerary.getGeneralizedCostIncludingPenalty()); } /** From 37986ea733b1805e178c8e4c4f40a57375d34289 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 11:10:25 +0100 Subject: [PATCH 260/356] Update documentation --- src/main/java/org/opentripplanner/model/plan/Itinerary.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 3da1b20e4db..f4b3b8b4f67 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -504,11 +504,7 @@ public int getGeneralizedCost() { * using only on-street legs don't have an unfair advantage over those combining access/egress with * transit and using a penalty when being processed by the itinerary filter chain. * - * @see Itinerary#getGeneralizedCost() * @see org.opentripplanner.routing.algorithm.raptoradapter.router.street.AccessEgressPenaltyDecorator - * @see org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveNonTransitItinerariesBasedOnGeneralizedCost - * @see org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfStreetOnlyIsBetter - * @see org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfWalkingIsBetter */ @Override public int getGeneralizedCostIncludingPenalty() { From 6346062fd6f0c52b712bad5f69b142564d23ae91 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 11:44:25 +0100 Subject: [PATCH 261/356] Add tests and documentation --- .../org/opentripplanner/model/fare/ItineraryFares.java | 6 ++++++ .../opentripplanner/routing/core/ItineraryFaresTest.java | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java index 3f4cb04e01c..1a64f21c41b 100644 --- a/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java +++ b/src/main/java/org/opentripplanner/model/fare/ItineraryFares.java @@ -104,11 +104,17 @@ public void addFareProductUses(Multimap fareProducts) { legProducts.putAll(fareProducts); } + /** + * Add the contents of another instance to this one. + */ public void add(ItineraryFares fare) { itineraryProducts.addAll(fare.itineraryProducts); legProducts.putAll(fare.legProducts); } + /** + * Does this instance contain any fare products? + */ public boolean isEmpty() { return itineraryProducts.isEmpty() && legProducts.isEmpty(); } diff --git a/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java b/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java index 2b22bc9e41f..43bad94131f 100644 --- a/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java +++ b/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java @@ -1,6 +1,7 @@ package org.opentripplanner.routing.core; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.model.plan.PlanTestConstants.A; import static org.opentripplanner.model.plan.PlanTestConstants.B; import static org.opentripplanner.model.plan.PlanTestConstants.C; @@ -59,6 +60,12 @@ void legProduct() { ); } + @Test + void empty(){ + assertTrue(ItineraryFares.empty().isEmpty()); + } + + @Nonnull private static FareProduct fareProduct(String id) { return new FareProduct(id(id), id, Money.euros(10), null, null, null); From 73e66d987654fca6cfad9217763367ab14dfd52b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 12:04:48 +0100 Subject: [PATCH 262/356] Simplify GraphQL data fetcher --- .../apis/gtfs/datafetchers/ItineraryImpl.java | 14 ++------------ .../apis/gtfs/generated/GraphQLDataFetchers.java | 2 +- .../routing/core/ItineraryFaresTest.java | 3 +-- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java index a7ae7954cd6..a93360e920d 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java @@ -2,14 +2,10 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.mapping.NumberMapper; import org.opentripplanner.model.SystemNotice; -import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Emissions; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Leg; @@ -42,14 +38,8 @@ public DataFetcher endTime() { } @Override - public DataFetcher>> fares() { - return environment -> { - ItineraryFares fare = getSource(environment).getFares(); - if (fare == null) { - return null; - } - return List.of(); - }; + public DataFetcher> fares() { + return environment -> List.of(); } @Override diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index cd002ec187b..2f39f7f4030 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -402,7 +402,7 @@ public interface GraphQLItinerary { public DataFetcher endTime(); - public DataFetcher>> fares(); + public DataFetcher> fares(); public DataFetcher generalizedCost(); diff --git a/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java b/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java index 43bad94131f..3ad3b918ce1 100644 --- a/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java +++ b/src/test/java/org/opentripplanner/routing/core/ItineraryFaresTest.java @@ -61,11 +61,10 @@ void legProduct() { } @Test - void empty(){ + void empty() { assertTrue(ItineraryFares.empty().isEmpty()); } - @Nonnull private static FareProduct fareProduct(String id) { return new FareProduct(id(id), id, Money.euros(10), null, null, null); From 5b52c8b56681ac6f37ad70cea939cbdf68320535 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 12:09:40 +0100 Subject: [PATCH 263/356] Update tests --- .../opentripplanner/ext/fares/impl/FaresIntegrationTest.java | 2 +- .../ext/flex/trip/ScheduledDeviatedTripTest.java | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 90df7481720..7e114dae5ce 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -46,7 +46,7 @@ public void testBasic() { ItineraryFares fare = getFare(from, to, start, serverContext); var product = fare.getLegProducts().values().iterator().next().product(); assertEquals(Money.usDollars(4.25f), product.price()); - assertEquals("1:OW_2", product.id().toString()); + assertEquals("OW_2", product.id().getId().toString()); } @Test diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java index 85b533cbf69..e0f85676034 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/ScheduledDeviatedTripTest.java @@ -148,10 +148,7 @@ void calculateDirectFare() { var itinerary = itineraries.getFirst(); - assertEquals( - "[FareProductUse[id=1532715d-bffe-310c-9c76-842f3c74bbd3, product=FareProduct{id: '1:flex-adult', name: 'regular', amount: $2.50}]]", - itinerary.getFares().getLegProducts().values().toString() - ); + assertFalse(itinerary.getFares().getLegProducts().isEmpty()); OTPFeature.enableFeatures(Map.of(OTPFeature.FlexRouting, false)); } From bc8ac75b4a9182d3bd646940339e2ab3df76bdb3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 25 Jan 2024 12:14:16 +0100 Subject: [PATCH 264/356] Add schema documentation --- .../org/opentripplanner/apis/gtfs/schema.graphqls | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index ac2413caeae..daeb57d655e 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -933,6 +933,10 @@ type Emissions { co2: Grams } +""" +This type is only here for backwards-compatibility and this API will never return it anymore. +Please use the leg's `fareProducts` instead. +""" type fare { type: String @deprecated @@ -949,7 +953,10 @@ type fare { components: [fareComponent] @deprecated } -"""Component of the fare (i.e. ticket) for a part of the itinerary""" +""" +This type is only here for backwards-compatibility and this API will never return it anymore. +Please use the leg's `fareProducts` instead. +""" type fareComponent { """ID of the ticket type. Corresponds to `fareId` in **TicketType**.""" fareId: String @deprecated @@ -1574,7 +1581,7 @@ type Itinerary { """ Information about the fares for this itinerary. This is primarily a GTFS Fares V1 interface - will be removed in the future. + and always returns an empty list. Use the leg's `fareProducts` instead. """ fares: [fare] @deprecated(reason: "Use the leg's `fareProducts`.") } From fa33a47dfe7423a2cab56f70d899b77d7c7c38fb Mon Sep 17 00:00:00 2001 From: eibakke Date: Thu, 25 Jan 2024 13:20:55 +0100 Subject: [PATCH 265/356] Changes the StopType field in the GraphQL API from enum to String. This allows for backward compatibility. --- .../apis/transmodel/model/stop/QuayType.java | 6 +++-- .../transmodel/model/stop/StopTypeMapper.java | 25 ++++++------------- .../apis/transmodel/schema.graphql | 11 +------- 3 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java index 46b09956eb2..0b22086dfaf 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayType.java @@ -350,8 +350,10 @@ public static GraphQLObjectType create( GraphQLFieldDefinition .newFieldDefinition() .name("stopType") - .type(StopTypeMapper.STOP_TYPE) - .dataFetcher(env -> ((StopLocation) env.getSource()).getStopType()) + .type(Scalars.GraphQLString) + .dataFetcher(env -> + StopTypeMapper.getStopType(((StopLocation) env.getSource()).getStopType()) + ) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java index bde676bec59..e94347b72e5 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopTypeMapper.java @@ -1,26 +1,17 @@ package org.opentripplanner.apis.transmodel.model.stop; -import graphql.schema.GraphQLEnumType; import org.opentripplanner.transit.model.site.StopType; /** - * Maps the StopType enum to a GraphQL enum. + * Maps the StopType enum to a String used in the GraphQL API. */ public class StopTypeMapper { - public static final GraphQLEnumType STOP_TYPE = GraphQLEnumType - .newEnum() - .name("StopType") - .value("regular", StopType.REGULAR, "A regular stop defined geographically as a point.") - .value( - "flexible_area", - StopType.FLEXIBLE_AREA, - "Boarding and alighting is allowed anywhere within the geographic area of this stop." - ) - .value( - "flexible_group", - StopType.FLEXIBLE_GROUP, - "A stop that consists of multiple other stops, area or regular." - ) - .build(); + public static String getStopType(StopType stopType) { + return switch (stopType) { + case REGULAR -> "regular"; + case FLEXIBLE_AREA -> "flexible_area"; + case FLEXIBLE_GROUP -> "flexible_group"; + }; + } } diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index a1e971d66ef..25cf95ca2f9 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -600,7 +600,7 @@ type Quay implements PlaceInterface { situations: [PtSituationElement!]! "The stop place to which this quay belongs to." stopPlace: StopPlace - stopType: StopType + stopType: String tariffZones: [TariffZone]! timeZone: String "Whether this quay is suitable for wheelchair boarding." @@ -1697,15 +1697,6 @@ enum StopCondition { startPoint } -enum StopType { - "Boarding and alighting is allowed anywhere within the geographic area of this stop." - flexible_area - "A stop that consists of multiple other stops, area or regular." - flexible_group - "A regular stop defined geographically as a point." - regular -} - enum StreetMode { "Bike only. This can be used as access/egress, but transfers will still be walk only." bicycle From 1696118f2cec9ab721436586456f7a5038e6c812 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 25 Jan 2024 12:43:12 +0000 Subject: [PATCH 266/356] Add changelog entry for #5636 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 4cfb1176773..981f453fced 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -79,6 +79,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582) - Revert REST API spelling change of real-time [#5629](https://github.com/opentripplanner/OpenTripPlanner/pull/5629) - Remove `FareComponent` [#5613](https://github.com/opentripplanner/OpenTripPlanner/pull/5613) +- Add AreaStop layer to new debug frontend [#5636](https://github.com/opentripplanner/OpenTripPlanner/pull/5636) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 317960b34986fbf689fb2653e2283166177d1983 Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 25 Jan 2024 12:44:17 +0000 Subject: [PATCH 267/356] Upgrade debug client to version 2024/01/2024-01-25T12:43 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index e9443e240c4..2653fdf36c2 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +

      From fa484cbc519ccf93557ba96ee821a29ebf56066e Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 25 Jan 2024 21:33:39 +0000 Subject: [PATCH 268/356] Add changelog entry for #5627 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 981f453fced..7fc6a512c7a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -80,6 +80,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Revert REST API spelling change of real-time [#5629](https://github.com/opentripplanner/OpenTripPlanner/pull/5629) - Remove `FareComponent` [#5613](https://github.com/opentripplanner/OpenTripPlanner/pull/5613) - Add AreaStop layer to new debug frontend [#5636](https://github.com/opentripplanner/OpenTripPlanner/pull/5636) +- Allow configuration of vector tiles base path [#5627](https://github.com/opentripplanner/OpenTripPlanner/pull/5627) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From f38447c98f37215702300ce91f2e54ba56cab9c1 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Thu, 25 Jan 2024 21:33:56 +0000 Subject: [PATCH 269/356] Bump serialization version id for #5627 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3f7fc0dd2bb..c4737cc592b 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 138 + 139 30.1 2.50 From 3b9dd5b438db2baa068fb8ca4bf59b20edd38c2c Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Fri, 26 Jan 2024 11:39:55 +0100 Subject: [PATCH 270/356] fix: Log trip and pattern id when negative trip-times occurs in routing. --- .../framework/lang/ObjectUtils.java | 13 ++++++++++++ .../framework/tostring/ToStringBuilder.java | 14 +++++++++++-- .../request/TripScheduleWithOffset.java | 4 +++- .../model/network/RoutingTripPattern.java | 2 +- .../framework/lang/ObjectUtilsTest.java | 13 ++++++++++++ .../tostring/ToStringBuilderTest.java | 20 +++++++++++++++++++ 6 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java b/src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java index 1e67b8f253e..a3f18748987 100644 --- a/src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java +++ b/src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java @@ -1,6 +1,7 @@ package org.opentripplanner.framework.lang; import java.util.function.Function; +import java.util.function.Supplier; import javax.annotation.Nullable; /** @@ -33,6 +34,18 @@ public static T ifNotNull( return ifNotNull(getter.apply(entity), defaultValue); } + /** + * Get the value or {@code null}, ignore any exceptions. This is useful if you must traverse + * a long call-chain like {@code a.b().c().d()...} when e.g. logging. + */ + public static T safeGetOrNull(Supplier body) { + try { + return body.get(); + } catch (Exception ignore) { + return null; + } + } + public static T requireNotInitialized(T oldValue, T newValue) { return requireNotInitialized(null, oldValue, newValue); } diff --git a/src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java b/src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java index cb5d26294db..6480b6f1187 100644 --- a/src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java +++ b/src/main/java/org/opentripplanner/framework/tostring/ToStringBuilder.java @@ -13,9 +13,11 @@ import java.util.Collection; import java.util.Objects; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.framework.lang.OtpNumberFormat; import org.opentripplanner.framework.time.DurationUtils; import org.opentripplanner.framework.time.TimeUtils; @@ -134,12 +136,20 @@ public ToStringBuilder addObj(String name, Object value, @Nullable Object ignore return addIfNotIgnored(name, value, ignoreValue, Object::toString); } + /** + * Add the result of the given supplier. If the supplier return {@code null} or an exceptions + * is thrown, then nothing is added - the result is ignored. + */ + public ToStringBuilder addObjOpSafe(String name, Supplier body) { + return addObj(name, ObjectUtils.safeGetOrNull(body)); + } + /** * Use this if you would like a custom toString function to convert the value. If the given value * is null, then the value is not printed. *

      * Implementation note! The "Op" (Operation) suffix is necessary to separate this from - * {@link #addObj(String, Object, Object)}, when the last argument is null. + * {@link #addObj(String, Object, Object)}, when the last argument is null. */ public ToStringBuilder addObjOp( String name, @@ -176,7 +186,7 @@ public ToStringBuilder addDoubles(String name, double[] value, double ignoreValu return addIt(name, Arrays.toString(value)); } - /** Add collection if not null or not empty, all elements are added */ + /** Add the collection if not null or not empty, all elements are added */ public ToStringBuilder addCol(String name, Collection c) { return addIfNotNull(name, c == null || c.isEmpty() ? null : c); } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java index 3eb26150d97..642dbd2d6e5 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/request/TripScheduleWithOffset.java @@ -107,7 +107,9 @@ public int getSecondsOffset() { public String toString() { return ToStringBuilder .of(TripScheduleWithOffset.class) - .addObj("trip", pattern.debugInfo()) + .addObj("info", pattern.debugInfo()) + .addObjOpSafe("id", () -> tripTimes.getTrip().getId()) + .addObjOpSafe("pattern.id", () -> pattern.getTripPattern().getPattern().getId()) .addServiceTime("depart", secondsOffset + getOriginalTripTimes().getDepartureTime(0)) .toString(); } diff --git a/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java b/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java index 00033b5f798..98d30432b32 100644 --- a/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java +++ b/src/main/java/org/opentripplanner/transit/model/network/RoutingTripPattern.java @@ -117,7 +117,7 @@ public Route route() { @Override public String debugInfo() { - return pattern.logName() + " @" + index; + return pattern.logName() + " #" + index; } @Override diff --git a/src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java b/src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java index 9237b221fe5..274fb3e8700 100644 --- a/src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java +++ b/src/test/java/org/opentripplanner/framework/lang/ObjectUtilsTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.time.Duration; import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; @@ -48,6 +49,18 @@ void requireNotInitialized() { assertEquals("Field is already set! Old value: old, new value: new.", ex.getMessage()); } + @Test + void safeGetOrNull() { + assertEquals("test", ObjectUtils.safeGetOrNull(() -> "test")); + assertEquals(3000, ObjectUtils.safeGetOrNull(() -> Duration.ofSeconds(3).toMillis())); + assertNull(ObjectUtils.safeGetOrNull(() -> null)); + assertNull( + ObjectUtils.safeGetOrNull(() -> { + throw new NullPointerException("Something went wrong - ignore"); + }) + ); + } + @Test void toStringTest() { assertEquals("1", ObjectUtils.toString(1)); diff --git a/src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java b/src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java index 3e87006e953..90254c321a1 100644 --- a/src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java +++ b/src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java @@ -111,6 +111,26 @@ public void addObj() { ); } + @Test + public void addObjOpSafe() { + assertEquals( + "ToStringBuilderTest{obj: Foo{a: 5, b: 'X'}}", + subject().addObjOpSafe("obj", () -> new Foo(5, "X")).toString() + ); + assertEquals("ToStringBuilderTest{}", subject().addObjOpSafe("obj", () -> null).toString()); + assertEquals( + "ToStringBuilderTest{}", + subject() + .addObjOpSafe( + "obj", + () -> { + throw new IllegalStateException("Ignore"); + } + ) + .toString() + ); + } + @Test public void addObjOp() { var duration = Duration.ofMinutes(1); From 273309ec3fb8bfec800a1d6d210bb9210a02cd53 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 26 Jan 2024 19:32:54 +0100 Subject: [PATCH 271/356] Update src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java Co-authored-by: Thomas Gran --- .../filters/transit/TransitGeneralizedCostFilter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java index 14670038512..430f00372d0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/transit/TransitGeneralizedCostFilter.java @@ -12,7 +12,6 @@ /** * This filter removes all transit results which have a generalized-cost higher than the max-limit - * This filter removes all transit results that have a generalized-cost higher than the max-limit * computed by the {@link #costLimitFunction} plus the wait cost given by * {@link TransitGeneralizedCostFilter#getWaitTimeCost}. */ From b0a400f7b67afea3c6e8d6860bef4086797c136e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 26 Jan 2024 19:33:35 +0100 Subject: [PATCH 272/356] Simplify penalty calculation --- .../org/opentripplanner/model/plan/Itinerary.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index f4b3b8b4f67..34a8117b58e 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -5,6 +5,7 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Function; @@ -45,8 +46,8 @@ public class Itinerary implements ItinerarySortKey { private Double elevationGained = 0.0; private int generalizedCost = UNKNOWN; private Integer generalizedCost2 = null; - private TimeAndCost accessPenalty = null; - private TimeAndCost egressPenalty = null; + private TimeAndCost accessPenalty = TimeAndCost.ZERO; + private TimeAndCost egressPenalty = TimeAndCost.ZERO; private int waitTimeOptimizedCost = UNKNOWN; private int transferPriorityCost = UNKNOWN; private boolean tooSloped = false; @@ -539,6 +540,7 @@ public TimeAndCost getAccessPenalty() { } public void setAccessPenalty(TimeAndCost accessPenalty) { + Objects.requireNonNull(accessPenalty); this.accessPenalty = accessPenalty; } @@ -548,6 +550,7 @@ public TimeAndCost getEgressPenalty() { } public void setEgressPenalty(TimeAndCost egressPenalty) { + Objects.requireNonNull(egressPenalty); this.egressPenalty = egressPenalty; } @@ -678,10 +681,6 @@ public Emissions getEmissionsPerPerson() { } private static int penaltyCost(TimeAndCost penalty) { - if (penalty == null) { - return 0; - } else { - return penalty.cost().toSeconds(); - } + return penalty.cost().toSeconds(); } } From dd9ec7000f49332e6ff39ad867b48e69a6ed7589 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Fri, 26 Jan 2024 19:16:49 +0000 Subject: [PATCH 273/356] Add changelog entry for #5637 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 7fc6a512c7a..28a5e9b8ee5 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -81,6 +81,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Remove `FareComponent` [#5613](https://github.com/opentripplanner/OpenTripPlanner/pull/5613) - Add AreaStop layer to new debug frontend [#5636](https://github.com/opentripplanner/OpenTripPlanner/pull/5636) - Allow configuration of vector tiles base path [#5627](https://github.com/opentripplanner/OpenTripPlanner/pull/5627) +- Change Transmodel API path to `/otp/transmodel/v3` [#5637](https://github.com/opentripplanner/OpenTripPlanner/pull/5637) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 4412c7fe3ab1ad36f5b5d27dafcaee6c47a0f6eb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 26 Jan 2024 22:33:05 +0100 Subject: [PATCH 274/356] Update chat badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4486818745b..2f2e910862c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ## Overview -[![Join the chat at https://gitter.im/opentripplanner/OpenTripPLanner](https://badges.gitter.im/opentripplanner/OpenTripPlanner.svg)](https://gitter.im/opentripplanner/OpenTripPlanner) +[![Join the chat at https://gitter.im/opentripplanner/OpenTripPlanner](https://img.shields.io/matrix/opentripplanner%3Amatrix.org?label=Gitter%20chat&color=%2342ac8c +)](https://gitter.im/opentripplanner/OpenTripPlanner) [![codecov](https://codecov.io/gh/opentripplanner/OpenTripPlanner/branch/dev-2.x/graph/badge.svg?token=ak4PbIKgZ1)](https://codecov.io/gh/opentripplanner/OpenTripPlanner) [![Docker Pulls](https://img.shields.io/docker/pulls/opentripplanner/opentripplanner)](https://hub.docker.com/r/opentripplanner/opentripplanner) From 5e05d21ccb1e2f43069efe2929fcad45a823748d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 26 Jan 2024 22:34:18 +0100 Subject: [PATCH 275/356] Revert "Update chat badge" This reverts commit 4412c7fe3ab1ad36f5b5d27dafcaee6c47a0f6eb. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2f2e910862c..4486818745b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ ## Overview -[![Join the chat at https://gitter.im/opentripplanner/OpenTripPlanner](https://img.shields.io/matrix/opentripplanner%3Amatrix.org?label=Gitter%20chat&color=%2342ac8c -)](https://gitter.im/opentripplanner/OpenTripPlanner) +[![Join the chat at https://gitter.im/opentripplanner/OpenTripPLanner](https://badges.gitter.im/opentripplanner/OpenTripPlanner.svg)](https://gitter.im/opentripplanner/OpenTripPlanner) [![codecov](https://codecov.io/gh/opentripplanner/OpenTripPlanner/branch/dev-2.x/graph/badge.svg?token=ak4PbIKgZ1)](https://codecov.io/gh/opentripplanner/OpenTripPlanner) [![Docker Pulls](https://img.shields.io/docker/pulls/opentripplanner/opentripplanner)](https://hub.docker.com/r/opentripplanner/opentripplanner) From 40c99421cf4f8336ffaaefb2f211fb9174423251 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 27 Jan 2024 10:40:09 +0100 Subject: [PATCH 276/356] Update Github Actions --- .github/workflows/cibuild.yml | 28 +++++++++++++------------- .github/workflows/debug-client.yml | 2 +- .github/workflows/performance-test.yml | 4 ++-- .github/workflows/post-merge.yml | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index c2979504992..28a84953af2 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -20,20 +20,20 @@ jobs: timeout-minutes: 20 steps: # Starting in v2.2 checkout action fetches all tags when fetch-depth=0, for auto-versioning. - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v4 with: fetch-depth: 0 # nodejs is needed because the dynamic download of it via the prettier maven plugin often # times out # Example: https://github.com/opentripplanner/OpenTripPlanner/actions/runs/4490450225/jobs/7897533439 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18 # Java setup step completes very fast, no need to run in a preconfigured docker container - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin @@ -65,9 +65,9 @@ jobs: timeout-minutes: 20 runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin @@ -91,7 +91,7 @@ jobs: steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v4 # this is necessary so that the correct credentials are put into the git configuration # when we push to dev-2.x and push the HTML to the git repo if: github.event_name == 'push' && (github.ref == 'refs/heads/dev-2.x' || github.ref == 'refs/heads/master') @@ -101,7 +101,7 @@ jobs: # was modified last fetch-depth: 1000 - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v4 # for a simple PR where we don't push, we don't need any credentials if: github.event_name == 'pull_request' @@ -113,7 +113,7 @@ jobs: if: github.event_name == 'pull_request' run: mkdocs build - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18 @@ -174,8 +174,8 @@ jobs: if: github.repository_owner == 'opentripplanner' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.1.0 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: 16 - name: Run code generator @@ -184,7 +184,7 @@ jobs: yarn install yarn generate - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin @@ -199,16 +199,16 @@ jobs: - build-windows - build-linux steps: - - uses: actions/checkout@v3.1.0 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK 21 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin cache: maven - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18 - name: Build container image with Jib, push to Dockerhub diff --git a/.github/workflows/debug-client.yml b/.github/workflows/debug-client.yml index aed7943e63a..de92c121db7 100644 --- a/.github/workflows/debug-client.yml +++ b/.github/workflows/debug-client.yml @@ -30,7 +30,7 @@ jobs: - uses: actions/checkout@v4 if: github.event_name == 'pull_request' - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18 diff --git a/.github/workflows/performance-test.yml b/.github/workflows/performance-test.yml index a5274d9839f..1b8201a01ae 100644 --- a/.github/workflows/performance-test.yml +++ b/.github/workflows/performance-test.yml @@ -60,14 +60,14 @@ jobs: profile: extended steps: - - uses: actions/checkout@v3.1.0 + - uses: actions/checkout@v4 if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x' with: fetch-depth: 0 - name: Set up JDK if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 1500a0f9d9e..a2f29f0d1b0 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4 with: token: ${{ secrets.CHANGELOG_TOKEN }} @@ -62,7 +62,7 @@ jobs: git config --global user.email 'serialization-version-bot@opentripplanner.org' - name: Checkout - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4 with: token: ${{ secrets.CHANGELOG_TOKEN }} From 4ecf8de9c7cb182832be747ac7fcdd1b8d9293b4 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Mon, 29 Jan 2024 07:45:26 +0000 Subject: [PATCH 277/356] Add changelog entry for #5625 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 28a5e9b8ee5..40b91bf47a6 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -82,6 +82,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Add AreaStop layer to new debug frontend [#5636](https://github.com/opentripplanner/OpenTripPlanner/pull/5636) - Allow configuration of vector tiles base path [#5627](https://github.com/opentripplanner/OpenTripPlanner/pull/5627) - Change Transmodel API path to `/otp/transmodel/v3` [#5637](https://github.com/opentripplanner/OpenTripPlanner/pull/5637) +- Add flexibleArea to GroupStop Quays [#5625](https://github.com/opentripplanner/OpenTripPlanner/pull/5625) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 7d36193a16a97dbdca89ad24afe4a6736f659b49 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Mon, 29 Jan 2024 07:45:46 +0000 Subject: [PATCH 278/356] Bump serialization version id for #5625 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c4737cc592b..ce77a303d7d 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 139 + 140 30.1 2.50 From 773ed216c401a754e5ea57357bd1f2ce6cde232a Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 12:59:18 +0100 Subject: [PATCH 279/356] Remove 'street corners' [ci skip] --- docs/apis/Apis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/apis/Apis.md b/docs/apis/Apis.md index 48b530a57e1..dd9280a047f 100644 --- a/docs/apis/Apis.md +++ b/docs/apis/Apis.md @@ -18,7 +18,7 @@ entities on a vector map. The [Actuator API](../sandbox/ActuatorAPI.md) provides endpoints for checking the health status of the OTP instance and reading live application metrics. -The [Geocoder API](../sandbox/GeocoderAPI.md) allows you to geocode street corners and stop names. +The [Geocoder API](../sandbox/GeocoderAPI.md) allows you to geocode stop names. ## Legacy APIs (to be removed) @@ -26,4 +26,4 @@ The OTP REST API used to power many apps and frontends. For years it was the onl OTP programmatically. Over time it has been replaced by the GraphQL APIs and is scheduled to be disabled by default -and eventually removed completely. It's therefore not recommended to use it. \ No newline at end of file +and eventually removed completely. It's therefore not recommended to use it. From 9e7c9bfe9bd5f481255261e71654346935544efa Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 13:26:46 +0100 Subject: [PATCH 280/356] Update docs, closes #5500 [ci skip] --- doc-templates/Configuration.md | 4 ++-- docs/Configuration.md | 4 ++-- docs/SandboxExtension.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc-templates/Configuration.md b/doc-templates/Configuration.md index eabd4895a1f..6344e270570 100644 --- a/doc-templates/Configuration.md +++ b/doc-templates/Configuration.md @@ -128,8 +128,8 @@ you can run the following bash command: - `head -c 29 Graph.obj ==> OpenTripPlannerGraph;0000007;` (file header) - `head -c 28 Graph.obj | tail -c 7 ==> 0000007` (version id) -The Maven _pom.xml_, the _META-INF/MANIFEST.MF_, the OTP command line(`--serVerId`), log start-up -messages and all OTP APIs can be used to get the OTP Serialization Version Id. +The Maven _pom.xml_, the _META-INF/MANIFEST.MF_, the OTP command line(`--serializationVersionId`), +log start-up messages and all OTP APIs can be used to get the OTP Serialization Version Id. ## Include file directive diff --git a/docs/Configuration.md b/docs/Configuration.md index d43ff150926..858edf0f9b4 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -155,8 +155,8 @@ you can run the following bash command: - `head -c 29 Graph.obj ==> OpenTripPlannerGraph;0000007;` (file header) - `head -c 28 Graph.obj | tail -c 7 ==> 0000007` (version id) -The Maven _pom.xml_, the _META-INF/MANIFEST.MF_, the OTP command line(`--serVerId`), log start-up -messages and all OTP APIs can be used to get the OTP Serialization Version Id. +The Maven _pom.xml_, the _META-INF/MANIFEST.MF_, the OTP command line(`--serializationVersionId`), +log start-up messages and all OTP APIs can be used to get the OTP Serialization Version Id. ## Include file directive diff --git a/docs/SandboxExtension.md b/docs/SandboxExtension.md index 38988f8245f..4b978313ca6 100644 --- a/docs/SandboxExtension.md +++ b/docs/SandboxExtension.md @@ -11,7 +11,7 @@ provided "as is". - [Google Cloud Storage](sandbox/GoogleCloudStorage.md) - Enable Google Cloud Storage as a OTP Data Source - [Actuator API](sandbox/ActuatorAPI.md) - API used to check the health status of the OTP instance. -- [Geocoder API](sandbox/GeocoderAPI.md) - Adds an API to search for corners, stops and stations. +- [Geocoder API](sandbox/GeocoderAPI.md) - Adds an API to search for stops and stations. - [Transfer analyser](sandbox/transferanalyzer.md) - Module used for analyzing the transfers between nearby stops generated by routing via OSM data. - [SIRI Updater](sandbox/SiriUpdater.md) - Update OTP with real-time information from a Transmodel SIRI data source. From bb2e7530f380d599dac479c1d769a673a8195b3b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 13:47:15 +0100 Subject: [PATCH 281/356] Separate walk from non-transit time --- .../apis/gtfs/datafetchers/ItineraryImpl.java | 4 ++-- .../model/plan/TripPatternType.java | 2 +- .../plan/ItinerariesCalculateLegTotals.java | 9 ++++++++- .../opentripplanner/model/plan/Itinerary.java | 19 +++++++++++++++++++ .../apis/gtfs/expectations/plan-extended.json | 2 ++ .../apis/gtfs/queries/plan-extended.graphql | 2 ++ 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java index 5399783bee0..63104ecc79a 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/ItineraryImpl.java @@ -94,12 +94,12 @@ public DataFetcher waitingTime() { @Override public DataFetcher walkDistance() { - return environment -> getSource(environment).getNonTransitDistanceMeters(); + return environment -> getSource(environment).walkDistanceMeters(); } @Override public DataFetcher walkTime() { - return environment -> (long) getSource(environment).getNonTransitDuration().toSeconds(); + return environment -> (long) getSource(environment).walkDuration().toSeconds(); } @Override diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java index 158d6a9a042..bbef4172c69 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java @@ -158,7 +158,7 @@ public static GraphQLObjectType create( .name("walkDistance") .deprecate("Replaced by `streetDistance`.") .type(Scalars.GraphQLFloat) - .dataFetcher(env -> itinerary(env).getNonTransitDistanceMeters()) + .dataFetcher(env -> itinerary(env).walkDistanceMeters()) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java index c512e47d732..50d859d821d 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java @@ -13,6 +13,8 @@ class ItinerariesCalculateLegTotals { int nTransitLegs = 0; Duration nonTransitDuration = Duration.ZERO; double nonTransitDistanceMeters = 0.0; + Duration walkDuration = Duration.ZERO; + double walkDistanceMeters = 0.0; Duration waitingDuration = Duration.ZERO; boolean walkOnly = true; boolean streetOnly = true; @@ -42,9 +44,14 @@ private void calculate(List legs) { if (!leg.isInterlinedWithPreviousLeg()) { ++nTransitLegs; } - } else if (leg.isStreetLeg()) { + } else if (leg instanceof StreetLeg streetLeg){ nonTransitDuration = nonTransitDuration.plus(dt); nonTransitDistanceMeters += leg.getDistanceMeters(); + + if(streetLeg.isWalkingLeg()){ + walkDuration = walkDuration.plus(streetLeg.getDuration()); + walkDistanceMeters = walkDistanceMeters + streetLeg.getDistanceMeters(); + } } else if (leg instanceof UnknownTransitPathLeg unknownTransitPathLeg) { nTransitLegs += unknownTransitPathLeg.getNumberOfTransfers() + 1; } diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 903e04c8b0c..2addae47413 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -39,6 +39,9 @@ public class Itinerary implements ItinerarySortKey { private final boolean walkOnly; private final boolean streetOnly; private final Duration nonTransitDuration; + private final Duration walkDuration; + private final double walkDistanceMeters; + /* mutable primitive properties */ private Double elevationLost = 0.0; @@ -75,6 +78,8 @@ public Itinerary(List legs) { this.transitDuration = totals.transitDuration; this.nonTransitDuration = totals.nonTransitDuration; this.nonTransitDistanceMeters = DoubleUtils.roundTo2Decimals(totals.nonTransitDistanceMeters); + this.walkDuration = totals.walkDuration; + this.walkDistanceMeters = totals.walkDistanceMeters; this.waitingDuration = totals.waitingDuration; this.walkOnly = totals.walkOnly; this.streetOnly = totals.streetOnly; @@ -663,4 +668,18 @@ public void setEmissionsPerPerson(Emissions emissionsPerPerson) { public Emissions getEmissionsPerPerson() { return this.emissionsPerPerson; } + + /** + * How much walking this itinerary contains, in meters. + */ + public double walkDistanceMeters() { + return walkDistanceMeters; + } + + /** + * How long the walking is contained in this itinerary. + */ + public Duration walkDuration() { + return walkDuration; + } } diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json index 681bb4715ab..557cdec8659 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/plan-extended.json @@ -11,6 +11,8 @@ "co2" : 123.0 }, "numberOfTransfers" : 1, + "walkDistance" : 28.0, + "walkTime" : 20, "legs" : [ { "mode" : "WALK", diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql index 76c8590ab30..db30d8489ef 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/plan-extended.graphql @@ -24,6 +24,8 @@ co2 } numberOfTransfers + walkDistance + walkTime legs { mode from { From 04c6949ef3e2f004ca27b335dc0789287f110361 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 13:49:10 +0100 Subject: [PATCH 282/356] Separate non-transit from walk time --- .../plan/ItinerariesCalculateLegTotals.java | 4 ++-- .../opentripplanner/model/plan/Itinerary.java | 3 +-- .../model/plan/ItineraryTest.java | 16 ++++++++-------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java index 50d859d821d..9bfd6d0757b 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java @@ -44,11 +44,11 @@ private void calculate(List legs) { if (!leg.isInterlinedWithPreviousLeg()) { ++nTransitLegs; } - } else if (leg instanceof StreetLeg streetLeg){ + } else if (leg instanceof StreetLeg streetLeg) { nonTransitDuration = nonTransitDuration.plus(dt); nonTransitDistanceMeters += leg.getDistanceMeters(); - if(streetLeg.isWalkingLeg()){ + if (streetLeg.isWalkingLeg()) { walkDuration = walkDuration.plus(streetLeg.getDuration()); walkDistanceMeters = walkDistanceMeters + streetLeg.getDistanceMeters(); } diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 2addae47413..2ccbb55235b 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -42,7 +42,6 @@ public class Itinerary implements ItinerarySortKey { private final Duration walkDuration; private final double walkDistanceMeters; - /* mutable primitive properties */ private Double elevationLost = 0.0; private Double elevationGained = 0.0; @@ -673,7 +672,7 @@ public Emissions getEmissionsPerPerson() { * How much walking this itinerary contains, in meters. */ public double walkDistanceMeters() { - return walkDistanceMeters; + return walkDistanceMeters; } /** diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index df67e3c2f44..b7f07e0cd0c 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -19,7 +19,7 @@ public class ItineraryTest implements PlanTestConstants { @Test - public void testDerivedFieldsWithWalkingOnly() { + void testDerivedFieldsWithWalkingOnly() { Itinerary result = newItinerary(A, T11_00).walk(D5m, B).build(); // Expected fields on itinerary set @@ -43,7 +43,7 @@ public void testDerivedFieldsWithWalkingOnly() { } @Test - public void testDerivedFieldsWithBusAllTheWay() { + void testDerivedFieldsWithBusAllTheWay() { Itinerary result = newItinerary(A).bus(55, T11_00, T11_10, B).build(); assertEquals(ofMinutes(10), result.getDuration()); @@ -67,7 +67,7 @@ public void testDerivedFieldsWithBusAllTheWay() { } @Test - public void testDerivedFieldsWithTrainAllTheWay() { + void testDerivedFieldsWithTrainAllTheWay() { Itinerary result = newItinerary(A).rail(20, T11_05, T11_15, B).build(); assertEquals(ofMinutes(10), result.getDuration()); @@ -91,7 +91,7 @@ public void testDerivedFieldsWithTrainAllTheWay() { } @Test - public void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { + void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { Itinerary itinerary = TestItineraryBuilder .newItinerary(A, T11_02) .walk(D1m, B) @@ -112,7 +112,7 @@ public void testDerivedFieldsWithWalAccessAndTwoTransitLegs() { } @Test - public void testDerivedFieldsWithBusAndWalkingAccessAndEgress() { + void testDerivedFieldsWithBusAndWalkingAccessAndEgress() { Itinerary result = newItinerary(A, T11_05) .walk(D2m, B) // 3 minutes wait @@ -133,7 +133,7 @@ public void testDerivedFieldsWithBusAndWalkingAccessAndEgress() { } @Test - public void walkBusBusWalkTrainWalk() { + void walkBusBusWalkTrainWalk() { Itinerary result = newItinerary(A, T11_00) .walk(D2m, B) .bus(55, T11_04, T11_14, C) @@ -161,7 +161,7 @@ public void walkBusBusWalkTrainWalk() { } @Test - public void legIndex() { + void legIndex() { var itinerary = newItinerary(A, T11_00) .walk(D2m, B) .bus(55, T11_04, T11_14, C) @@ -181,7 +181,7 @@ public void legIndex() { } @Test - public void hasSystemTag() { + void hasSystemTag() { var subject = newItinerary(A).bus(1, T11_04, T11_14, B).build(); subject.flagForDeletion(new SystemNotice("MY-TAG", "Text")); assertTrue(subject.hasSystemNoticeTag("MY-TAG")); From aab15b63053f90d7a32a02120a346d6bc71c8788 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 13:57:11 +0100 Subject: [PATCH 283/356] Add tests --- .../model/plan/ItineraryTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index b7f07e0cd0c..595da58de5a 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -160,6 +160,28 @@ void walkBusBusWalkTrainWalk() { ); } + @Test + void walkSeparateFromBike() { + var itin = newItinerary(A, T11_00).walk(D2m, B).bicycle(T11_05, T11_15, D).walk(D3m, E).build(); + + assertEquals(ofMinutes(15), itin.getNonTransitDuration()); + assertEquals(ofMinutes(5), itin.walkDuration()); + + assertEquals(420, itin.walkDistanceMeters()); + assertEquals(3420, itin.getNonTransitDistanceMeters()); + } + + @Test + void walkSeparateFromCar() { + var itin = newItinerary(A, T11_00).walk(D2m, B).carHail(D10m, D).walk(D3m, E).build(); + + assertEquals(ofMinutes(15), itin.getNonTransitDuration()); + assertEquals(ofMinutes(5), itin.walkDuration()); + + assertEquals(420, itin.walkDistanceMeters()); + assertEquals(15420.0, itin.getNonTransitDistanceMeters()); + } + @Test void legIndex() { var itinerary = newItinerary(A, T11_00) From c7631ff7e89d21b17a1d1f2bf2dc960bbf2db73d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 16:18:40 +0100 Subject: [PATCH 284/356] Use getFirst and getLast --- .../model/plan/ItinerariesCalculateLegTotals.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java index 9bfd6d0757b..5274b005be3 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java @@ -33,8 +33,7 @@ int transfers() { } private void calculate(List legs) { - totalDuration = - Duration.between(legs.get(0).getStartTime(), legs.get(legs.size() - 1).getEndTime()); + totalDuration = Duration.between(legs.getFirst().getStartTime(), legs.getLast().getEndTime()); for (Leg leg : legs) { Duration dt = leg.getDuration(); From a8762307d6ad1daae85737de58a67d2039e983c7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 29 Jan 2024 21:16:14 +0100 Subject: [PATCH 285/356] Replace toString with full objects --- .../fares/impl/DefaultFareServiceTest.java | 73 ++++++++++++------- .../ext/fares/impl/FaresIntegrationTest.java | 8 +- 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 3fca4b949e4..5f4317a5f4f 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -18,6 +18,8 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.opentripplanner.model.fare.FareProduct; +import org.opentripplanner.model.fare.FareProductUse; import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.PlanTestConstants; @@ -28,6 +30,12 @@ class DefaultFareServiceTest implements PlanTestConstants { private static final Money TEN_DOLLARS = Money.usDollars(10); + private static final FareProduct OTHER_FEED_PRODUCT = FareProduct + .of(OTHER_FEED_ATTRIBUTE.getId(), "regular", TEN_DOLLARS) + .build(); + private static final FareProduct AIRPORT_TO_CITY_CENTER_PRODUCT = FareProduct + .of(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), "regular", TEN_DOLLARS) + .build(); @Test void noRules() { @@ -50,8 +58,10 @@ void simpleZoneBasedFare() { var legProducts = fare.getLegProducts().get(itin.getTransitLeg(0)); assertEquals( - "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", - legProducts.toString() + List.of( + new FareProductUse("1d270201-412b-3b86-80f6-92ab144fa2e5", AIRPORT_TO_CITY_CENTER_PRODUCT) + ), + legProducts ); } @@ -76,10 +86,20 @@ void applyToSeveralLegs() { var secondProducts = legProducts.get(secondLeg); assertEquals(firstProducts, secondProducts); - assertEquals( - "[FareProductUse[id=ddbf1572-18bc-3724-8b64-e1c7d5c8b6c6, product=FareProduct{id: 'F:free-transfers', name: 'regular', amount: $20.00}]]", - firstProducts.toString() + List.of( + new FareProductUse( + "ddbf1572-18bc-3724-8b64-e1c7d5c8b6c6", + FareProduct + .of( + FREE_TRANSFERS_IN_CITY_SET.getFareAttribute().getId(), + "regular", + TEN_DOLLARS.plus(TEN_DOLLARS) + ) + .build() + ) + ), + firstProducts ); } @@ -108,16 +128,18 @@ void shouldNotCombineInterlinedLegs() { var legProducts = fare.getLegProducts(); var firstLeg = itin.getLegs().getFirst(); - + var secondLeg = itin.getLegs().get(1); assertEquals( - "[FareProductUse[id=ccadd1d3-f284-31a4-9d58-0a300198950f, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", - legProducts.get(firstLeg).toString() + List.of( + new FareProductUse("ccadd1d3-f284-31a4-9d58-0a300198950f", AIRPORT_TO_CITY_CENTER_PRODUCT) + ), + legProducts.get(firstLeg) ); - - var secondLeg = itin.getLegs().get(1); assertEquals( - "[FareProductUse[id=c58974dd-9a2f-3f42-90ec-c62a7b0dfd51, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", - legProducts.get(secondLeg).toString() + List.of( + new FareProductUse("c58974dd-9a2f-3f42-90ec-c62a7b0dfd51", AIRPORT_TO_CITY_CENTER_PRODUCT) + ), + legProducts.get(secondLeg) ); } @@ -141,9 +163,6 @@ void unknownLeg() { assertEquals(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), fp.id()); assertEquals(TEN_DOLLARS, fp.price()); - var firstBusLeg = itin.firstTransitLeg().get(); - //assertEquals(List.of(firstBusLeg), fp.legs()); - var legProducts = fare.getLegProducts(); assertEquals(1, legProducts.size()); } @@ -174,13 +193,15 @@ void multipleFeeds() { var legProducts = result.getLegProducts(); var firstBusLeg = itin.getTransitLeg(0); assertEquals( - "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", - legProducts.get(firstBusLeg).toString() + List.of( + new FareProductUse("1d270201-412b-3b86-80f6-92ab144fa2e5", AIRPORT_TO_CITY_CENTER_PRODUCT) + ), + legProducts.get(firstBusLeg) ); var secondBusLeg = itin.getTransitLeg(2); assertEquals( - "[FareProductUse[id=678d201c-e839-35c3-ae7b-1bc3834da5e5, product=FareProduct{id: 'F2:other-feed-attribute', name: 'regular', amount: $10.00}]]", - legProducts.get(secondBusLeg).toString() + List.of(new FareProductUse("678d201c-e839-35c3-ae7b-1bc3834da5e5", OTHER_FEED_PRODUCT)), + legProducts.get(secondBusLeg) ); } @@ -204,16 +225,18 @@ void multipleFeedsWithTransfersWithinFeed() { var finalBusLeg = itin.getTransitLeg(4); assertEquals( - "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', name: 'regular', amount: $10.00}]]", - legProducts.get(firstBusLeg).toString() + List.of(new FareProductUse("5d0d58f4-b97a-38db-921c-8b5fc6392b54", OTHER_FEED_PRODUCT)), + legProducts.get(firstBusLeg) ); assertEquals( - "[FareProductUse[id=1d270201-412b-3b86-80f6-92ab144fa2e5, product=FareProduct{id: 'F:airport-to-city-center', name: 'regular', amount: $10.00}]]", - legProducts.get(secondBusLeg).toString() + List.of( + new FareProductUse("1d270201-412b-3b86-80f6-92ab144fa2e5", AIRPORT_TO_CITY_CENTER_PRODUCT) + ), + legProducts.get(secondBusLeg) ); assertEquals( - "[FareProductUse[id=5d0d58f4-b97a-38db-921c-8b5fc6392b54, product=FareProduct{id: 'F2:other-feed-attribute', name: 'regular', amount: $10.00}]]", - legProducts.get(finalBusLeg).toString() + List.of(new FareProductUse("5d0d58f4-b97a-38db-921c-8b5fc6392b54", OTHER_FEED_PRODUCT)), + legProducts.get(finalBusLeg) ); } diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index 7e114dae5ce..a7dd4a92311 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -76,11 +76,11 @@ public void testPortland() { .toInstant(); ItineraryFares fare = getFare(from, to, startTime, serverContext); + var fpu = List.copyOf(fare.getLegProducts().values()).getFirst(); + assertEquals(List.of(fpu), List.copyOf(fare.getLegProducts().values())); - assertEquals( - "[FareProductUse[id=26a5a5ee-c7db-37ad-be09-fa3afdce748b, product=FareProduct{id: 'prt:19', name: 'regular', amount: $2.00}]]", - fare.getLegProducts().values().toString() - ); + assertEquals(Money.usDollars(2f), fpu.product().price()); + assertEquals("prt:19", fpu.product().id().toString()); // long trip From 79218be5aa8fb8d74fd7c3bbd5d335225180f997 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 30 Jan 2024 10:25:39 +0100 Subject: [PATCH 286/356] Use walkDuration in Transmodel API --- .../apis/transmodel/model/plan/TripPatternType.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java index bbef4172c69..2238a39c139 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/plan/TripPatternType.java @@ -136,8 +136,7 @@ public static GraphQLObjectType create( .name("walkTime") .description("How much time is spent walking, in seconds.") .type(ExtendedScalars.GraphQLLong) - // TODO This unfortunately include BIKE and CAR - .dataFetcher(env -> itinerary(env).getNonTransitDuration().toSeconds()) + .dataFetcher(env -> itinerary(env).walkDuration().toSeconds()) .build() ) .field( From 698076700bc9d54e615892e6c94f7104510b675d Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Tue, 30 Jan 2024 10:01:00 +0000 Subject: [PATCH 287/356] Add changelog entry for #5638 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 40b91bf47a6..35fc86ec3bc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -83,6 +83,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Allow configuration of vector tiles base path [#5627](https://github.com/opentripplanner/OpenTripPlanner/pull/5627) - Change Transmodel API path to `/otp/transmodel/v3` [#5637](https://github.com/opentripplanner/OpenTripPlanner/pull/5637) - Add flexibleArea to GroupStop Quays [#5625](https://github.com/opentripplanner/OpenTripPlanner/pull/5625) +- Pass-through should override transit-group-priority [#5638](https://github.com/opentripplanner/OpenTripPlanner/pull/5638) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 391b643f436635c3d883290375a0046107309aa4 Mon Sep 17 00:00:00 2001 From: Henrik Abrahamsson Date: Tue, 30 Jan 2024 14:30:28 +0100 Subject: [PATCH 288/356] Siri azure updaters: Reduce some log levels --- .../ext/siri/updater/azure/SiriAzureETUpdater.java | 4 ++-- .../ext/siri/updater/azure/SiriAzureSXUpdater.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java b/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java index 4ceaa0d3106..4b9a86618a5 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureETUpdater.java @@ -57,7 +57,7 @@ protected void messageConsumer(ServiceBusReceivedMessageContext messageContext) MESSAGE_COUNTER.incrementAndGet(); if (MESSAGE_COUNTER.get() % 100 == 0) { - LOG.info("Total SIRI-ET messages received={}", MESSAGE_COUNTER.get()); + LOG.debug("Total SIRI-ET messages received={}", MESSAGE_COUNTER.get()); } processMessage(message.getBody().toString(), message.getMessageId()); @@ -169,7 +169,7 @@ private List getUpdates(String message, Str siri.getServiceDelivery().getEstimatedTimetableDeliveries().isEmpty() ) { if (siri.getHeartbeatNotification() != null) { - LOG.info("Received SIRI heartbeat message"); + LOG.debug("Received SIRI heartbeat message"); } else { LOG.warn("Empty Siri message {}: {}", id, message); } diff --git a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java b/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java index a86145e79ea..8d33035b971 100644 --- a/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java +++ b/src/ext/java/org/opentripplanner/ext/siri/updater/azure/SiriAzureSXUpdater.java @@ -111,7 +111,7 @@ private Siri getSiri(String message, String id) throws XMLStreamException, JAXBE siri.getServiceDelivery().getSituationExchangeDeliveries().isEmpty() ) { if (siri.getHeartbeatNotification() != null) { - LOG.info("Received SIRI heartbeat message"); + LOG.debug("Received SIRI heartbeat message"); } else { LOG.warn("Empty Siri message for messageId {}", id); LOG.debug(message); From 4410fb10d519007e0c45a87928e00022149cac73 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 30 Jan 2024 16:08:42 +0200 Subject: [PATCH 289/356] Rename hopCost/Time -> mountDismountCost/Time in prefs --- docs/RouteRequest.md | 8 +-- .../resources/RequestToPreferencesMapper.java | 4 +- .../apis/gtfs/mapping/RouteRequestMapper.java | 4 +- .../preference/VehicleWalkingPreferences.java | 50 +++++++++---------- .../routerequest/VehicleWalkingConfig.java | 12 ++--- .../street/model/edge/BikeWalkableEdge.java | 12 +++-- .../VehicleWalkingPreferencesTest.java | 20 ++++---- .../street/integration/BikeWalkingTest.java | 5 +- .../street/model/edge/StreetEdgeTest.java | 4 +- 9 files changed, 63 insertions(+), 56 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 199eda8a332..4cae701db57 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -78,8 +78,8 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | |       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | |    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | -|       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle. | *Optional* | `"PT0S"` | 2.0 | +|       [mountDismountCost](#rd_bicycle_walk_mountDismountCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [mountDismountTime](#rd_bicycle_walk_mountDismountTime) | `duration` | The time it takes the user to hop on or off a vehicle. | *Optional* | `"PT0S"` | 2.0 | |       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | |       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | |       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | @@ -525,7 +525,7 @@ This factor can also include other concerns such as convenience and general cycl preferences by taking into account road surface etc. -

      hopCost

      +

      mountDismountCost

      **Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` **Path:** /routingDefaults/bicycle/walk @@ -536,7 +536,7 @@ There are different parameters for the cost of renting or parking a vehicle and not meant for controlling the cost of those events. -

      hopTime

      +

      mountDismountTime

      **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` **Path:** /routingDefaults/bicycle/walk diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index bfac498ff8c..bf44da6be00 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -89,8 +89,8 @@ private void mapBike() { bike.withWalking(walk -> { setIfNotNull(req.bikeWalkingSpeed, walk::withSpeed); setIfNotNull(req.bikeWalkingReluctance, walk::withReluctance); - setIfNotNull(req.bikeSwitchTime, walk::withHopTime); - setIfNotNull(req.bikeSwitchCost, walk::withHopCost); + setIfNotNull(req.bikeSwitchTime, walk::withMountDismountTime); + setIfNotNull(req.bikeSwitchCost, walk::withMountDismountCost); }); }); } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index 212bfbcf380..5bc00cb7a85 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -340,8 +340,8 @@ private static void setVehicleWalkingPreferences( ) { callWith.argument("bikeWalkingReluctance", walking::withReluctance); callWith.argument("bikeWalkingSpeed", walking::withSpeed); - callWith.argument("bikeSwitchTime", time -> walking.withHopTime((int) time)); - callWith.argument("bikeSwitchCost", cost -> walking.withHopCost((int) cost)); + callWith.argument("bikeSwitchTime", time -> walking.withMountDismountTime((int) time)); + callWith.argument("bikeSwitchCost", cost -> walking.withMountDismountCost((int) cost)); } private static class CallerWithEnvironment { diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java index aa3631e1c6b..b7adc04df1c 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java @@ -19,15 +19,15 @@ public class VehicleWalkingPreferences implements Serializable { private final double speed; private final double reluctance; - private final Duration hopTime; - private final Cost hopCost; + private final Duration mountDismountTime; + private final Cost mountDismountCost; private final double stairsReluctance; private VehicleWalkingPreferences() { this.speed = 1.33; this.reluctance = 5.0; - this.hopTime = Duration.ZERO; - this.hopCost = Cost.ZERO; + this.mountDismountTime = Duration.ZERO; + this.mountDismountCost = Cost.ZERO; // very high reluctance to carry the bike up/down a flight of stairs this.stairsReluctance = 10; } @@ -39,8 +39,8 @@ private VehicleWalkingPreferences() { private VehicleWalkingPreferences(Builder builder) { this.speed = Units.speed(builder.speed); this.reluctance = Units.reluctance(builder.reluctance); - this.hopTime = Duration.ofSeconds(Units.duration(builder.hopTime)); - this.hopCost = Cost.costOfSeconds(builder.hopCost); + this.mountDismountTime = Duration.ofSeconds(Units.duration(builder.mountDismountTime)); + this.mountDismountCost = Cost.costOfSeconds(builder.mountDismountCost); this.stairsReluctance = Units.reluctance(builder.stairsReluctance); } @@ -73,13 +73,13 @@ public double reluctance() { } /** Time to get on and off your own vehicle. */ - public Duration hopTime() { - return hopTime; + public Duration mountDismountTime() { + return mountDismountTime; } /** Cost of getting on and off your own vehicle. */ - public Cost hopCost() { - return hopCost; + public Cost mountDismountCost() { + return mountDismountCost; } /** Reluctance of walking carrying a vehicle up a flight of stairs. */ @@ -95,15 +95,15 @@ public boolean equals(Object o) { return ( speed == that.speed && reluctance == that.reluctance && - Objects.equals(hopTime, that.hopTime) && - Objects.equals(hopCost, that.hopCost) && + Objects.equals(mountDismountTime, that.mountDismountTime) && + Objects.equals(mountDismountCost, that.mountDismountCost) && stairsReluctance == that.stairsReluctance ); } @Override public int hashCode() { - return Objects.hash(speed, reluctance, hopTime, hopCost, stairsReluctance); + return Objects.hash(speed, reluctance, mountDismountTime, mountDismountCost, stairsReluctance); } @Override @@ -112,8 +112,8 @@ public String toString() { .of(VehicleWalkingPreferences.class) .addNum("speed", speed, DEFAULT.speed) .addNum("reluctance", reluctance, DEFAULT.reluctance) - .addObj("hopTime", hopTime, DEFAULT.hopTime) - .addObj("hopCost", hopCost, DEFAULT.hopCost) + .addObj("mountDismountTime", mountDismountTime, DEFAULT.mountDismountTime) + .addObj("mountDismountCost", mountDismountCost, DEFAULT.mountDismountCost) .addNum("stairsReluctance", stairsReluctance, DEFAULT.stairsReluctance) .toString(); } @@ -123,16 +123,16 @@ public static class Builder { private final VehicleWalkingPreferences original; private double speed; private double reluctance; - private int hopTime; - private int hopCost; + private int mountDismountTime; + private int mountDismountCost; private double stairsReluctance; private Builder(VehicleWalkingPreferences original) { this.original = original; this.speed = original.speed; this.reluctance = original.reluctance; - this.hopTime = (int) original.hopTime.toSeconds(); - this.hopCost = original.hopCost.toSeconds(); + this.mountDismountTime = (int) original.mountDismountTime.toSeconds(); + this.mountDismountCost = original.mountDismountCost.toSeconds(); this.stairsReluctance = original.stairsReluctance; } @@ -146,18 +146,18 @@ public VehicleWalkingPreferences.Builder withReluctance(double reluctance) { return this; } - public VehicleWalkingPreferences.Builder withHopTime(Duration hopTime) { - this.hopTime = (int) hopTime.toSeconds(); + public VehicleWalkingPreferences.Builder withMountDismountTime(Duration mountDismountTime) { + this.mountDismountTime = (int) mountDismountTime.toSeconds(); return this; } - public VehicleWalkingPreferences.Builder withHopTime(int hopTime) { - this.hopTime = hopTime; + public VehicleWalkingPreferences.Builder withMountDismountTime(int mountDismountTime) { + this.mountDismountTime = mountDismountTime; return this; } - public VehicleWalkingPreferences.Builder withHopCost(int hopCost) { - this.hopCost = hopCost; + public VehicleWalkingPreferences.Builder withMountDismountCost(int mountDismountCost) { + this.mountDismountCost = mountDismountCost; return this; } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index f2ba922c8e3..2b20e12f755 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -43,9 +43,9 @@ private static void mapVehicleWalkingPreferences( ) .asDouble(dft.reluctance()) ) - .withHopTime( + .withMountDismountTime( c - .of("hopTime") + .of("mountDismountTime") .since(V2_0) .summary("The time it takes the user to hop on or off a vehicle.") .description( @@ -54,11 +54,11 @@ private static void mapVehicleWalkingPreferences( for controlling the duration of those events. """ ) - .asDuration(dft.hopTime()) + .asDuration(dft.mountDismountTime()) ) - .withHopCost( + .withMountDismountCost( c - .of("hopCost") + .of("mountDismountCost") .since(V2_0) .summary("The cost of hopping on or off a vehicle.") .description( @@ -67,7 +67,7 @@ private static void mapVehicleWalkingPreferences( not meant for controlling the cost of those events. """ ) - .asInt(dft.hopCost().toSeconds()) + .asInt(dft.mountDismountCost().toSeconds()) ) .withStairsReluctance( c diff --git a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java b/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java index 799a5b006e6..7f61982434d 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java @@ -17,8 +17,10 @@ default void switchToWalkingBike(RoutingPreferences preferences, StateEditor edi editor.setBackWalkingBike(true); if (shouldIncludeCost) { - editor.incrementWeight(preferences.bike().walking().hopCost().toSeconds()); - editor.incrementTimeInSeconds((int) preferences.bike().walking().hopTime().toSeconds()); + editor.incrementWeight(preferences.bike().walking().mountDismountCost().toSeconds()); + editor.incrementTimeInSeconds( + (int) preferences.bike().walking().mountDismountTime().toSeconds() + ); } } @@ -28,8 +30,10 @@ default void switchToBiking(RoutingPreferences preferences, StateEditor editor) editor.setBackWalkingBike(false); if (shouldIncludeCost) { - editor.incrementWeight(preferences.bike().walking().hopCost().toSeconds()); - editor.incrementTimeInSeconds((int) preferences.bike().walking().hopTime().toSeconds()); + editor.incrementWeight(preferences.bike().walking().mountDismountCost().toSeconds()); + editor.incrementTimeInSeconds( + (int) preferences.bike().walking().mountDismountTime().toSeconds() + ); } } diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java index 9571eee8cc5..fdc416d7c0f 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java @@ -11,8 +11,8 @@ class VehicleWalkingPreferencesTest { private static final double SPEED = 1.45; private static final double RELUCTANCE = 5.5; - private static final Duration HOP_TIME = Duration.ofSeconds(15); - private static final Cost HOP_COST = Cost.costOfSeconds(20); + private static final Duration MOUNT_DISMOUNT_TIME = Duration.ofSeconds(15); + private static final Cost MOUNT_DISMOUNT_COST = Cost.costOfSeconds(20); private static final double STAIRS_RELUCTANCE = 11; private final VehicleWalkingPreferences subject = createPreferences(); @@ -28,13 +28,13 @@ void reluctance() { } @Test - void hopTime() { - assertEquals(HOP_TIME, subject.hopTime()); + void mountDismountTime() { + assertEquals(MOUNT_DISMOUNT_TIME, subject.mountDismountTime()); } @Test - void hopCost() { - assertEquals(HOP_COST, subject.hopCost()); + void mountDismountCost() { + assertEquals(MOUNT_DISMOUNT_COST, subject.mountDismountCost()); } @Test @@ -57,8 +57,8 @@ void testToString() { "VehicleWalkingPreferences{" + "speed: 1.45, " + "reluctance: 5.5, " + - "hopTime: PT15S, " + - "hopCost: $20, " + + "mountDismountTime: PT15S, " + + "mountDismountCost: $20, " + "stairsReluctance: 11.0}", subject.toString() ); @@ -69,8 +69,8 @@ private VehicleWalkingPreferences createPreferences() { .of() .withSpeed(SPEED) .withReluctance(RELUCTANCE) - .withHopTime(HOP_TIME) - .withHopCost(HOP_COST.toSeconds()) + .withMountDismountTime(MOUNT_DISMOUNT_TIME) + .withMountDismountCost(MOUNT_DISMOUNT_COST.toSeconds()) .withStairsReluctance(STAIRS_RELUCTANCE) .build(); } diff --git a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java b/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java index 417f1b87347..41ec677b3bb 100644 --- a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java @@ -375,7 +375,10 @@ private List runStreetSearchAndCreateDescriptor( preferences .withWalk(w -> w.withSpeed(10)) .withBike(it -> - it.withSpeed(20d).withWalking(w -> w.withSpeed(5d).withHopTime(100).withHopCost(1000)) + it + .withSpeed(20d) + .withWalking(w -> w.withSpeed(5d).withMountDismountTime(100).withMountDismountCost(1000) + ) ) ); request.setArriveBy(arriveBy); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index 42d841b9fa3..ed5768d4a1a 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -221,7 +221,7 @@ public void testBikeSwitch() { StreetSearchRequestBuilder noPenalty = StreetSearchRequest.copyOf(proto); noPenalty.withPreferences(p -> - p.withBike(it -> it.withWalking(w -> w.withHopTime(0).withHopCost(0))) + p.withBike(it -> it.withWalking(w -> w.withMountDismountTime(0).withMountDismountCost(0))) ); State s0 = new State(v0, noPenalty.withMode(StreetMode.BIKE).build()); @@ -231,7 +231,7 @@ public void testBikeSwitch() { StreetSearchRequestBuilder withPenalty = StreetSearchRequest.copyOf(proto); withPenalty.withPreferences(p -> - p.withBike(it -> it.withWalking(w -> w.withHopTime(42).withHopCost(23))) + p.withBike(it -> it.withWalking(w -> w.withMountDismountTime(42).withMountDismountCost(23))) ); State s4 = new State(v0, withPenalty.withMode(StreetMode.BIKE).build()); From 923551847bfd2aea2971ef5fadaf72b8d6872cfd Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 30 Jan 2024 23:36:22 +0100 Subject: [PATCH 290/356] Fix spelling of realtimeArrival --- .../org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java | 2 +- .../org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java index 46607cccb6a..38041304c1c 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java @@ -29,7 +29,7 @@ public static ApiTripTimeShort mapToApi(TripTimeOnDate domain) { api.stopCount = domain.getStopCount(); api.scheduledArrival = domain.getScheduledArrival(); api.scheduledDeparture = domain.getScheduledDeparture(); - api.realimeArrival = domain.getRealtimeArrival(); + api.realtimeArrival = domain.getRealtimeArrival(); api.realtimeDeparture = domain.getRealtimeDeparture(); api.arrivalDelay = domain.getArrivalDelay(); api.departureDelay = domain.getDepartureDelay(); diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java index c0337ba18d4..bab8e9a6977 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java @@ -11,7 +11,7 @@ public class ApiTripTimeShort implements Serializable { public int stopCount; public int scheduledArrival = UNDEFINED; public int scheduledDeparture = UNDEFINED; - public int realimeArrival = UNDEFINED; + public int realtimeArrival = UNDEFINED; public int realtimeDeparture = UNDEFINED; public int arrivalDelay = UNDEFINED; public int departureDelay = UNDEFINED; From 4596d2d78675e9b7ed2ee5556d7c3b64027bea38 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 31 Jan 2024 14:24:11 +0100 Subject: [PATCH 291/356] Remove instanceOf --- .../model/plan/ItinerariesCalculateLegTotals.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java index 5274b005be3..77287990496 100644 --- a/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java +++ b/src/main/java/org/opentripplanner/model/plan/ItinerariesCalculateLegTotals.java @@ -43,13 +43,13 @@ private void calculate(List legs) { if (!leg.isInterlinedWithPreviousLeg()) { ++nTransitLegs; } - } else if (leg instanceof StreetLeg streetLeg) { + } else if (leg.isStreetLeg()) { nonTransitDuration = nonTransitDuration.plus(dt); nonTransitDistanceMeters += leg.getDistanceMeters(); - if (streetLeg.isWalkingLeg()) { - walkDuration = walkDuration.plus(streetLeg.getDuration()); - walkDistanceMeters = walkDistanceMeters + streetLeg.getDistanceMeters(); + if (leg.isWalkingLeg()) { + walkDuration = walkDuration.plus(leg.getDuration()); + walkDistanceMeters = walkDistanceMeters + leg.getDistanceMeters(); } } else if (leg instanceof UnknownTransitPathLeg unknownTransitPathLeg) { nTransitLegs += unknownTransitPathLeg.getNumberOfTransfers() + 1; From 961013204cbea9df1239d32bad16a1684bfe24b4 Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 31 Jan 2024 15:46:53 +0100 Subject: [PATCH 292/356] Refactors GroupStopBuilder addLocation method. It now simply adds the geometry of the location to the geometry collection of the GroupStop. It was unclear what the large (100x100 degree) envelopes around regular stops were doing. It looked like a bug, and the geometry of GroupStops appears unused so it should be safe to change. --- .../transit/model/site/GroupStopBuilder.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 8873e6ede99..a8db22b1368 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.function.IntSupplier; import javax.annotation.Nonnull; -import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryCollection; import org.opentripplanner.framework.geometry.GeometryUtils; @@ -69,6 +68,17 @@ public I18NString name() { } public GroupStopBuilder addLocation(StopLocation location) { + if ( + !( + location.getStopType() == StopType.REGULAR || + location.getStopType() == StopType.FLEXIBLE_AREA + ) + ) { + throw new RuntimeException( + "Unsupported location for GroupStop. Must be Regular or FlexibleArea." + ); + } + stopLocations.add(location); int numGeometries = geometry.getNumGeometries(); @@ -76,17 +86,8 @@ public GroupStopBuilder addLocation(StopLocation location) { for (int i = 0; i < numGeometries; i++) { newGeometries[i] = geometry.getGeometryN(i); } - if (location instanceof RegularStop) { - WgsCoordinate coordinate = location.getCoordinate(); - Envelope envelope = new Envelope(coordinate.asJtsCoordinate()); - double xscale = Math.cos(coordinate.latitude() * Math.PI / 180); - envelope.expandBy(100 / xscale, 100); - newGeometries[numGeometries] = GeometryUtils.getGeometryFactory().toGeometry(envelope); - } else if (location instanceof AreaStop) { - newGeometries[numGeometries] = location.getGeometry(); - } else { - throw new RuntimeException("Unknown location type"); - } + newGeometries[numGeometries] = location.getGeometry(); + geometry = new GeometryCollection(newGeometries, GeometryUtils.getGeometryFactory()); centroid = new WgsCoordinate(geometry.getCentroid()); From 195bb633401b3f400bc112303f866805b49a7d7d Mon Sep 17 00:00:00 2001 From: eibakke Date: Wed, 31 Jan 2024 15:46:53 +0100 Subject: [PATCH 293/356] Refactors GroupStopBuilder addLocation method. It now simply adds the geometry of the location to the geometry collection of the GroupStop. It was unclear what the large (100x100 degree) envelopes around regular stops were doing. It looked like a bug, and the geometry of GroupStops appears unused so it should be safe to change. --- .../transit/model/site/GroupStopBuilder.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index 8873e6ede99..a8db22b1368 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.function.IntSupplier; import javax.annotation.Nonnull; -import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryCollection; import org.opentripplanner.framework.geometry.GeometryUtils; @@ -69,6 +68,17 @@ public I18NString name() { } public GroupStopBuilder addLocation(StopLocation location) { + if ( + !( + location.getStopType() == StopType.REGULAR || + location.getStopType() == StopType.FLEXIBLE_AREA + ) + ) { + throw new RuntimeException( + "Unsupported location for GroupStop. Must be Regular or FlexibleArea." + ); + } + stopLocations.add(location); int numGeometries = geometry.getNumGeometries(); @@ -76,17 +86,8 @@ public GroupStopBuilder addLocation(StopLocation location) { for (int i = 0; i < numGeometries; i++) { newGeometries[i] = geometry.getGeometryN(i); } - if (location instanceof RegularStop) { - WgsCoordinate coordinate = location.getCoordinate(); - Envelope envelope = new Envelope(coordinate.asJtsCoordinate()); - double xscale = Math.cos(coordinate.latitude() * Math.PI / 180); - envelope.expandBy(100 / xscale, 100); - newGeometries[numGeometries] = GeometryUtils.getGeometryFactory().toGeometry(envelope); - } else if (location instanceof AreaStop) { - newGeometries[numGeometries] = location.getGeometry(); - } else { - throw new RuntimeException("Unknown location type"); - } + newGeometries[numGeometries] = location.getGeometry(); + geometry = new GeometryCollection(newGeometries, GeometryUtils.getGeometryFactory()); centroid = new WgsCoordinate(geometry.getCentroid()); From c0ebcbef4a88af8752ad3dd26bc866932edd5bf2 Mon Sep 17 00:00:00 2001 From: eibakke Date: Thu, 1 Feb 2024 13:56:49 +0100 Subject: [PATCH 294/356] Adds unit test for GroupStop's geometry and encompassingAreaGeometry. --- .../transit/model/site/GroupStopBuilder.java | 7 ++- .../transit/model/site/GroupStopTest.java | 58 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java index a8db22b1368..64cad9325d1 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStopBuilder.java @@ -75,7 +75,12 @@ public GroupStopBuilder addLocation(StopLocation location) { ) ) { throw new RuntimeException( - "Unsupported location for GroupStop. Must be Regular or FlexibleArea." + String.format( + "Unsupported location for %s. Must be %s or %s.", + GroupStop.class.getSimpleName(), + StopType.REGULAR, + StopType.FLEXIBLE_AREA + ) ); } diff --git a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java b/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java index 17938131eef..dcf9bc3aeed 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java +++ b/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java @@ -6,7 +6,12 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.List; +import java.util.Objects; import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.transit.model._data.TransitModelForTest; @@ -14,7 +19,7 @@ class GroupStopTest { - private static TransitModelForTest TEST_MODEL = TransitModelForTest.of(); + private static final TransitModelForTest TEST_MODEL = TransitModelForTest.of(); private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); @@ -27,6 +32,57 @@ class GroupStopTest { .addLocation(STOP_LOCATION) .build(); + @Test + void testGroupStopGeometry() { + StopLocation stopLocation1 = TEST_MODEL.stop("1:stop", 1d, 1d).build(); + StopLocation stopLocation2 = TEST_MODEL.stop("2:stop", 2d, 2d).build(); + + GroupStop groupStop = StopModel + .of() + .groupStop(TransitModelForTest.id(ID)) + .withName(NAME) + .addLocation(stopLocation1) + .addLocation(stopLocation2) + .build(); + + Geometry groupStopGeometry1 = Objects.requireNonNull(groupStop.getGeometry()).getGeometryN(0); + assertEquals(stopLocation1.getGeometry(), groupStopGeometry1); + + Geometry groupStopGeometry2 = Objects.requireNonNull(groupStop.getGeometry()).getGeometryN(1); + assertEquals(stopLocation2.getGeometry(), groupStopGeometry2); + } + + @Test + void testGroupStopEncompassingAreaGeometry() { + Geometry encompassingAreaGeometry = GeometryUtils + .getGeometryFactory() + .toGeometry(new Envelope(1d, 2d, 1d, 2d)); + + StopLocation stopLocation = TEST_MODEL + .stop( + "1:stop", + encompassingAreaGeometry.getCentroid().getX(), + encompassingAreaGeometry.getCentroid().getY() + ) + .build(); + + GroupStop groupStop = StopModel + .of() + .groupStop(TransitModelForTest.id(ID)) + .withName(NAME) + .addLocation(stopLocation) + .withEncompassingAreaGeometries(List.of(encompassingAreaGeometry)) + .build(); + + Geometry groupStopGeometry = Objects.requireNonNull(groupStop.getGeometry()).getGeometryN(0); + assertEquals(stopLocation.getGeometry(), groupStopGeometry); + + assertEquals( + encompassingAreaGeometry, + groupStop.getEncompassingAreaGeometry().orElseThrow().getGeometryN(0) + ); + } + @Test void copy() { assertEquals(ID, subject.getId().getId()); From 006bcbec5695eb1e09fdf2df9888ea8c36827158 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 1 Feb 2024 13:05:35 +0000 Subject: [PATCH 295/356] Add changelog entry for #5483 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 35fc86ec3bc..59d762fb58c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -84,6 +84,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Change Transmodel API path to `/otp/transmodel/v3` [#5637](https://github.com/opentripplanner/OpenTripPlanner/pull/5637) - Add flexibleArea to GroupStop Quays [#5625](https://github.com/opentripplanner/OpenTripPlanner/pull/5625) - Pass-through should override transit-group-priority [#5638](https://github.com/opentripplanner/OpenTripPlanner/pull/5638) +- Introduce `generalizedCostPlusPenalty` to make cost comparsion fairer [#5483](https://github.com/opentripplanner/OpenTripPlanner/pull/5483) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 34bd9bb35e1f30ba2f19be2e0ed4f11c1316039f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 28 Sep 2023 10:58:23 +0200 Subject: [PATCH 296/356] Remove VehicleToStopHeuristics --- docs/Configuration.md | 1 - docs/SandboxExtension.md | 1 - docs/examples/entur/otp-config.json | 3 +- docs/sandbox/VehicleToStopHeuristics.md | 77 ------------- mkdocs.yml | 1 - .../BikeToStopSkipEdgeStrategy.java | 58 ---------- .../VehicleToStopSkipEdgeStrategy.java | 109 ------------------ .../framework/application/OTPFeature.java | 3 +- .../module/NearbyStopFinder.java | 47 ++------ 9 files changed, 9 insertions(+), 291 deletions(-) delete mode 100644 docs/sandbox/VehicleToStopHeuristics.md delete mode 100644 src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/BikeToStopSkipEdgeStrategy.java delete mode 100644 src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/VehicleToStopSkipEdgeStrategy.java diff --git a/docs/Configuration.md b/docs/Configuration.md index 858edf0f9b4..93ca1fa6c1e 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -250,7 +250,6 @@ Here is a list of all features which can be toggled on/off and their default val | `SandboxAPIParkAndRideApi` | Enable park-and-ride endpoint. | | ✓️ | | `SandboxAPITravelTime` | Enable the isochrone/travel time surface API. | | ✓️ | | `TransferAnalyzer` | Analyze transfers during graph build. | | ✓️ | -| `VehicleToStopHeuristics` | Enable improved heuristic for park-and-ride queries. | | ✓️ | diff --git a/docs/SandboxExtension.md b/docs/SandboxExtension.md index 4b978313ca6..914be238da4 100644 --- a/docs/SandboxExtension.md +++ b/docs/SandboxExtension.md @@ -23,7 +23,6 @@ nearby stops generated by routing via OSM data. - [Park and Ride API](sandbox/ParkAndRideApi.md) - Park and Ride API - [Data Overlay](sandbox/DataOverlay.md) - StreetEdge grid data populating affecting the route planning - [Vehicle Parking](sandbox/VehicleParking.md) - Vehicle Parking updaters -- [Vehicle-to-stop heuristics](sandbox/VehicleToStopHeuristics.md) - Speeding up Park+Ride, Bike+Ride and Bike+Transit searches - [Travel Time (Isochrone & Surface) API](sandbox/TravelTime.md) - Travel Time API - [IBI accessibility score](sandbox/IBIAccessibilityScore.md) - IBI accessibility score - [Fares](sandbox/Fares.md) - Fare calculation diff --git a/docs/examples/entur/otp-config.json b/docs/examples/entur/otp-config.json index 1746cd186d4..a072a3d4f30 100644 --- a/docs/examples/entur/otp-config.json +++ b/docs/examples/entur/otp-config.json @@ -6,7 +6,6 @@ "OptimizeTransfers": true, "TransferConstraints": true, "ParallelRouting": false, - "ReportApi" : true, - "VehicleToStopHeuristics": true + "ReportApi" : true } } \ No newline at end of file diff --git a/docs/sandbox/VehicleToStopHeuristics.md b/docs/sandbox/VehicleToStopHeuristics.md deleted file mode 100644 index 3197bbdca9d..00000000000 --- a/docs/sandbox/VehicleToStopHeuristics.md +++ /dev/null @@ -1,77 +0,0 @@ -# Vehicle-to-Stop heuristics - OTP Sandbox Extension - -## Contact Info - -- Leonard Ehrenfried ([mail@leonard.io](mailto:mail@leonard.io)) - -## Changelog - -- Create initial - implementation [#3906](https://github.com/opentripplanner/OpenTripPlanner/pull/3906) - -## Documentation - -This feature is meant to improve the performance and result quality for routing requests where a -vehicle (car, bike, scooter) is ridden to a stop where transit is boarded. - -Before this feature existed a search for nearby stops was executed finding all candidate stops for -boarding transit. For walking this yields a low number of stops but when driving a car this can -easily mean to an entire city of stops, since the default was a drive of 45 minutes. - -Having a very long driving time has several problems: - -- the access search itself is comparatively slow -- having many candidate stops slows down the transit search as many routes have to be checked -- often the quickest route would be to drive almost all the way to the destination and board transit - for a single stop - -We did not want to lower the maximum access time since in rural regions 45 minutes might be a useful -maximum, but we want it to scale with the density of well-connected stops. - -### Vehicle-to-stop heuristic - -In order to improve the Park+Ride and Bike+Ride results we reduced the number of candidate stops -with the following heuristic: - -1. When a stop is encountered check which routes depart from it -2. Each route adds to an "importance score" -3. Modes which are fast (RAIL, SUBWAY, FERRY) have a higher score than for example BUS -4. Once a maximum score is reached, the search is complete - -The code for this is located in `VehicleToStopSkipEdgeStrategy.java`. - -### Bicycle-on-transit heuristic - -This heuristic works slightly differently in that it doesn't assign a score but simply stops the -access search when a certain number of routes were encountered that allow you to take your bike onto -transit. - -The code for this is located in `BikeToStopSkipEdgeStrategy.java`. - -### Configuration - -Enable the feature by adding it to the ```otp-config.json```: - -```json -// otp-config.json -{ - "otpFeatures": { - "VehicleToStopHeuristics": true - } -} -``` - -### Collaborators wanted - -Since the current settings, scores and weights are hardcoded in the source code we are looking for -collaborators that can help to make it more adaptable for different environments. - -These are some the goals for the future: - -- make the scores that are assigned for routes of a certain mode configurable in JSON -- pre-calculate stop importance scores during the graph build - -If you want to help making this feature more flexible, please -contact [Leonard Ehrenfried](mailto:mail@leonard.io) -or use the regular channels of communication outlined -in [CONTRIBUTING.md](https://github.com/opentripplanner/OpenTripPlanner/blob/dev-2.x/CONTRIBUTING.md#primary-channels-of-communication) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index e4341b296fc..c4717d4d2e0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -106,7 +106,6 @@ nav: - Park and Ride API: 'sandbox/ParkAndRideApi.md' - Data Overlay: 'sandbox/DataOverlay.md' - Vehicle Parking Updaters: 'sandbox/VehicleParking.md' - - Vehicle-to-stop Heuristics: 'sandbox/VehicleToStopHeuristics.md' - Geocoder API: 'sandbox/GeocoderAPI.md' - Travel Time Isochrones: 'sandbox/TravelTime.md' - IBI Accessibility Score: 'sandbox/IBIAccessibilityScore.md' diff --git a/src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/BikeToStopSkipEdgeStrategy.java b/src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/BikeToStopSkipEdgeStrategy.java deleted file mode 100644 index ad503b1212d..00000000000 --- a/src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/BikeToStopSkipEdgeStrategy.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.opentripplanner.ext.vehicletostopheuristics; - -import java.util.Collection; -import java.util.function.Function; -import org.opentripplanner.astar.spi.SkipEdgeStrategy; -import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.vertex.TransitStopVertex; -import org.opentripplanner.street.search.state.State; -import org.opentripplanner.transit.model.network.BikeAccess; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.timetable.Trip; - -/** - * When wanting to take a bike onto transit we want to improve the performance by limiting the - * number of accesses to those stops which actually have trips where you can take the bike on. Once - * we have reached enough of trips we skip all further edges. - */ -public class BikeToStopSkipEdgeStrategy implements SkipEdgeStrategy { - - private static final int LIMIT = 100; - private static final double MAX_FACTOR = 1.2; - - private final Function> getTripsForStop; - - int numberOfBikeableTripsReached = 0; - double distanceLimit = Double.MAX_VALUE; - - public BikeToStopSkipEdgeStrategy(Function> getTripsForStop) { - this.getTripsForStop = getTripsForStop; - } - - public static boolean bikeAccessForTrip(Trip trip) { - if (trip.getBikesAllowed() != BikeAccess.UNKNOWN) { - return trip.getBikesAllowed() == BikeAccess.ALLOWED; - } - - return trip.getRoute().getBikesAllowed() == BikeAccess.ALLOWED; - } - - @Override - public boolean shouldSkipEdge(State current, Edge edge) { - if ( - current.getVertex() instanceof TransitStopVertex stopVertex && - distanceLimit == Double.MAX_VALUE - ) { - numberOfBikeableTripsReached += - getTripsForStop - .apply(stopVertex.getStop()) - .stream() - .filter(BikeToStopSkipEdgeStrategy::bikeAccessForTrip) - .count(); - if (numberOfBikeableTripsReached >= LIMIT) { - distanceLimit = current.getWalkDistance() * MAX_FACTOR; - } - } - return current.getWalkDistance() > distanceLimit; - } -} diff --git a/src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/VehicleToStopSkipEdgeStrategy.java b/src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/VehicleToStopSkipEdgeStrategy.java deleted file mode 100644 index 3eb466f97b9..00000000000 --- a/src/ext/java/org/opentripplanner/ext/vehicletostopheuristics/VehicleToStopSkipEdgeStrategy.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.opentripplanner.ext.vehicletostopheuristics; - -import static org.opentripplanner.routing.api.request.StreetMode.BIKE_RENTAL; -import static org.opentripplanner.routing.api.request.StreetMode.BIKE_TO_PARK; -import static org.opentripplanner.routing.api.request.StreetMode.CAR_HAILING; -import static org.opentripplanner.routing.api.request.StreetMode.CAR_PICKUP; -import static org.opentripplanner.routing.api.request.StreetMode.CAR_RENTAL; -import static org.opentripplanner.routing.api.request.StreetMode.CAR_TO_PARK; -import static org.opentripplanner.routing.api.request.StreetMode.SCOOTER_RENTAL; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Function; -import org.opentripplanner.astar.spi.SkipEdgeStrategy; -import org.opentripplanner.routing.api.request.StreetMode; -import org.opentripplanner.routing.api.request.request.filter.TransitFilter; -import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.vertex.TransitStopVertex; -import org.opentripplanner.street.search.state.State; -import org.opentripplanner.transit.model.basic.TransitMode; -import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.site.RegularStop; - -/** - * This strategy terminates when enough "important" stops are found. - *

      - * The definition of important is a stop where many routes of mode RAIL, SUBWAY or FERRY depart. - *

      - * This means that the search radius scales with density of "important" stops: - *

      - *

    2. in a city the radius is quite small - *
    3. in more rural regions the radius is bigger and stops further away are considered - *

      - * The strategy is useful when you want to limit the number of accesses of Park+Ride, Bike+Ride and - * Bike+Transit: it improves both performance the quality of results. - *

      - * {@see https://github.com/opentripplanner/OpenTripPlanner/pull/3906} - */ -public class VehicleToStopSkipEdgeStrategy implements SkipEdgeStrategy { - - public static final Set applicableModes = Set.of( - BIKE_TO_PARK, - BIKE_RENTAL, - CAR_TO_PARK, - CAR_PICKUP, - CAR_HAILING, - CAR_RENTAL, - SCOOTER_RENTAL - ); - private final Function> getPatternsForStop; - private final int maxScore; - private final List filters; - private double sumOfScores; - - private final Set stopsCounted = new HashSet<>(); - - public VehicleToStopSkipEdgeStrategy( - Function> getPatternsForStop, - Collection filters - ) { - this.filters = new ArrayList<>(filters); - this.maxScore = 300; - this.getPatternsForStop = getPatternsForStop; - } - - @Override - public boolean shouldSkipEdge(State current, Edge edge) { - if (current.currentMode().isWalking()) { - if ( - current.getVertex() instanceof TransitStopVertex stopVertex && - !stopsCounted.contains(stopVertex.getStop().getId()) - ) { - // TODO: 2022-12-05 filters: check performance on that and verify that this is right. Previously we were filtering just on modes - var stop = stopVertex.getStop(); - - // Not using streams. Performance is important here - var patterns = getPatternsForStop.apply(stop); - var score = 0; - for (var pattern : patterns) { - for (var filter : filters) { - if (filter.matchTripPattern(pattern)) { - score += VehicleToStopSkipEdgeStrategy.score(pattern.getMode()); - break; - } - } - } - - stopsCounted.add(stop.getId()); - - sumOfScores = sumOfScores + score; - } - return false; - } else { - return sumOfScores >= maxScore; - } - } - - private static int score(TransitMode mode) { - return switch (mode) { - case RAIL, FERRY, SUBWAY -> 20; - case BUS -> 1; - default -> 2; - }; - } -} diff --git a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java index 4847b204077..4ae5004cf6b 100644 --- a/src/main/java/org/opentripplanner/framework/application/OTPFeature.java +++ b/src/main/java/org/opentripplanner/framework/application/OTPFeature.java @@ -105,8 +105,7 @@ public enum OTPFeature { SandboxAPIMapboxVectorTilesApi(false, true, "Enable Mapbox vector tiles API."), SandboxAPIParkAndRideApi(false, true, "Enable park-and-ride endpoint."), SandboxAPITravelTime(false, true, "Enable the isochrone/travel time surface API."), - TransferAnalyzer(false, true, "Analyze transfers during graph build."), - VehicleToStopHeuristics(false, true, "Enable improved heuristic for park-and-ride queries."); + TransferAnalyzer(false, true, "Analyze transfers during graph build."); private static final Object TEST_LOCK = new Object(); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index 360cdaee363..0cac2a21308 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -18,8 +18,6 @@ import org.opentripplanner.astar.strategy.MaxCountSkipEdgeStrategy; import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext; import org.opentripplanner.ext.flex.trip.FlexTrip; -import org.opentripplanner.ext.vehicletostopheuristics.BikeToStopSkipEdgeStrategy; -import org.opentripplanner.ext.vehicletostopheuristics.VehicleToStopSkipEdgeStrategy; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.application.OTPRequestTimeoutException; import org.opentripplanner.routing.api.request.RouteRequest; @@ -205,7 +203,7 @@ public List findNearbyStopsViaStreets( ShortestPathTree spt = StreetSearchBuilder .of() - .setSkipEdgeStrategy(getSkipEdgeStrategy(reverseDirection, request)) + .setSkipEdgeStrategy(getSkipEdgeStrategy()) .setDominanceFunction(new DominanceFunctions.MinimumWeight()) .setRequest(request) .setArriveBy(reverseDirection) @@ -271,48 +269,17 @@ private List findNearbyStopsViaDirectTransfers(Vertex vertex) { return directGraphFinder.findClosestStops(c0, limitMeters); } - private SkipEdgeStrategy getSkipEdgeStrategy( - boolean reverseDirection, - RouteRequest routingRequest - ) { + private SkipEdgeStrategy getSkipEdgeStrategy() { var durationSkipEdgeStrategy = new DurationSkipEdgeStrategy(durationLimit); - // if we compute the accesses for Park+Ride, Bike+Ride and Bike+Transit we don't want to - // search the full durationLimit as this returns way too many stops. - // this is both slow and returns suboptimal results as it favours long drives with short - // transit legs. - // therefore, we use a heuristic based on the number of routes and their mode to determine - // what are "good" stops for those accesses. if we have reached a threshold of "good" stops - // we stop the access search. - if ( - !reverseDirection && - OTPFeature.VehicleToStopHeuristics.isOn() && - VehicleToStopSkipEdgeStrategy.applicableModes.contains( - routingRequest.journey().access().mode() - ) - ) { - var strategy = new VehicleToStopSkipEdgeStrategy( - transitService::getPatternsForStop, - routingRequest.journey().transit().filters() + if (maxStopCount > 0) { + var strategy = new MaxCountSkipEdgeStrategy<>( + maxStopCount, + NearbyStopFinder::hasReachedStop ); - - return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); - } else if ( - OTPFeature.VehicleToStopHeuristics.isOn() && - routingRequest.journey().access().mode() == StreetMode.BIKE - ) { - var strategy = new BikeToStopSkipEdgeStrategy(transitService::getTripsForStop); return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); - } else { - if (maxStopCount > 0) { - var strategy = new MaxCountSkipEdgeStrategy<>( - maxStopCount, - NearbyStopFinder::hasReachedStop - ); - return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); - } - return durationSkipEdgeStrategy; } + return durationSkipEdgeStrategy; } private static List createDirectlyConnectedStops( From fa30c9c069883a910f14933c2d89b89df79320ce Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Oct 2023 18:24:27 +0200 Subject: [PATCH 297/356] Set default cost for penalty --- .../framework/TimeAndCostPenaltyForEnum.java | 7 +++++++ .../preference/AccessEgressPreferences.java | 16 ++++++++++++++-- .../config/framework/json/ParameterBuilder.java | 5 +++-- .../config/routerequest/RouteRequestConfig.java | 6 +++++- .../config/framework/json/NodeAdapterTest.java | 12 ++++++++++-- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java b/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java index 60bd4d4c769..c45fc3e33a8 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java +++ b/src/main/java/org/opentripplanner/routing/api/request/framework/TimeAndCostPenaltyForEnum.java @@ -81,6 +81,13 @@ private EnumMap copyValues() { return values.isEmpty() ? new EnumMap<>(type) : new EnumMap<>(values); } + /** + * Convert the values to an {@link EnumMap}. + */ + public EnumMap asEnumMap() { + return copyValues(); + } + private static > String toString( Class clazz, Map values diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java index db8845e7c41..54d761d1030 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java @@ -7,12 +7,12 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import org.opentripplanner.framework.model.Units; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.framework.DurationForEnum; import org.opentripplanner.routing.api.request.framework.TimeAndCostPenalty; import org.opentripplanner.routing.api.request.framework.TimeAndCostPenaltyForEnum; +import org.opentripplanner.routing.api.request.framework.TimePenalty; /** * Preferences for access/egress routing on street network @@ -21,14 +21,26 @@ */ public final class AccessEgressPreferences implements Serializable { + private static final TimeAndCostPenalty DEFAULT_PENALTY = TimeAndCostPenalty.of( + TimePenalty.of(ofMinutes(10), 1.5f), + 2.5 + ); + private static final TimeAndCostPenaltyForEnum DEFAULT_TIME_AND_COST = TimeAndCostPenaltyForEnum + .of(StreetMode.class) + .with(StreetMode.CAR_TO_PARK, DEFAULT_PENALTY) + .with(StreetMode.CAR_HAILING, DEFAULT_PENALTY) + .with(StreetMode.CAR_RENTAL, DEFAULT_PENALTY) + .build(); + public static final AccessEgressPreferences DEFAULT = new AccessEgressPreferences(); + private final TimeAndCostPenaltyForEnum penalty; private final DurationForEnum maxDuration; private final int maxStopCount; private AccessEgressPreferences() { this.maxDuration = durationForStreetModeOf(ofMinutes(45)); - this.penalty = TimeAndCostPenaltyForEnum.ofDefault(StreetMode.class); + this.penalty = DEFAULT_TIME_AND_COST; this.maxStopCount = 500; } diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java b/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java index f1d90d0ec40..088a7794585 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java +++ b/src/main/java/org/opentripplanner/standalone/config/framework/json/ParameterBuilder.java @@ -303,14 +303,15 @@ public > Map asEnumMap(Class enumType, Class el */ public > Map asEnumMap( Class enumType, - Function typeMapper + Function typeMapper, + Map defaultValue ) { info.withOptional().withEnumMap(enumType, OBJECT); var mapNode = buildObject(); if (mapNode.isEmpty()) { - return Map.of(); + return defaultValue; } EnumMap result = new EnumMap<>(enumType); diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 4538f6de84d..264e50a6df1 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -472,7 +472,11 @@ the access legs used. In other cases where the access(CAR) is faster than transi extra cost, while 1.0 will add the same amount to both time and cost. """ ) - .asEnumMap(StreetMode.class, TimeAndCostPenaltyMapper::map) + .asEnumMap( + StreetMode.class, + TimeAndCostPenaltyMapper::map, + dftAccessEgress.penalty().asEnumMap() + ) ) .withMaxDuration( cae diff --git a/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java b/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java index f975579cbf5..be44d1ea86f 100644 --- a/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java +++ b/src/test/java/org/opentripplanner/standalone/config/framework/json/NodeAdapterTest.java @@ -225,15 +225,23 @@ public void asEnumMapWithCustomType() { NodeAdapter subject = newNodeAdapterForTest("{ key : { A: {a:'Foo'} } }"); assertEquals( Map.of(AnEnum.A, new ARecord("Foo")), - subject.of("key").asEnumMap(AnEnum.class, ARecord::fromJson) + subject.of("key").asEnumMap(AnEnum.class, ARecord::fromJson, Map.of()) ); assertEquals( Collections.emptyMap(), - subject.of("missing-key").asEnumMap(AnEnum.class, ARecord::fromJson) + subject.of("missing-key").asEnumMap(AnEnum.class, ARecord::fromJson, Map.of()) ); assertEquals(NON_UNUSED_PARAMETERS, unusedParams(subject)); } + @Test + public void asEnumMapWithDefaultValue() { + var subject = newNodeAdapterForTest("{}"); + final Map dflt = Map.of(AnEnum.A, new ARecord("Foo")); + assertEquals(dflt, subject.of("key").asEnumMap(AnEnum.class, ARecord::fromJson, dflt)); + assertEquals(NON_UNUSED_PARAMETERS, unusedParams(subject)); + } + @Test public void asEnumMapWithUnknownKey() { NodeAdapter subject = newNodeAdapterForTest("{ enumMap : { unknown : 7 } }"); From 2a63edf8c22cc44668c8261cdd78458a5ce39012 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Oct 2023 23:27:19 +0200 Subject: [PATCH 298/356] Finetune default values --- docs/RouteRequest.md | 6 +++++- .../preference/AccessEgressPreferences.java | 4 ++-- .../config/routerequest/RouteRequestConfig.java | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 199eda8a332..791df446c89 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -406,7 +406,11 @@ since the search-window is increased with the same amount as the maximum penalty the access legs used. In other cases where the access(CAR) is faster than transit the performance will be better. -The default is no penalty, if not configured. +The default values are + +- CAR_TO_PARK = (timePenalty: 30m + 2.0 t, costFactor: 2.0) +- CAR_RENTAL = (timePenalty: 30m + 2.0 t, costFactor: 2.0) +- CAR_HAILING = (timePenalty: 30m + 2.0 t, costFactor: 2.0) Example: `"car-to-park" : { "timePenalty": "10m + 1.5t", "costFactor": 2.5 }` diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java index 54d761d1030..b967bd34f58 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java @@ -22,8 +22,8 @@ public final class AccessEgressPreferences implements Serializable { private static final TimeAndCostPenalty DEFAULT_PENALTY = TimeAndCostPenalty.of( - TimePenalty.of(ofMinutes(10), 1.5f), - 2.5 + TimePenalty.of(ofMinutes(30), 2f), + 2 ); private static final TimeAndCostPenaltyForEnum DEFAULT_TIME_AND_COST = TimeAndCostPenaltyForEnum .of(StreetMode.class) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 264e50a6df1..49596759063 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -15,6 +15,8 @@ import static org.opentripplanner.standalone.config.routerequest.WheelchairConfig.mapWheelchairPreferences; import java.time.Duration; +import java.util.List; +import java.util.stream.Collectors; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.routing.api.request.RequestModes; @@ -455,7 +457,9 @@ private static void mapStreetPreferences(NodeAdapter c, StreetPreferences.Builde the access legs used. In other cases where the access(CAR) is faster than transit the performance will be better. - The default is no penalty, if not configured. + The default values are + + %s Example: `"car-to-park" : { "timePenalty": "10m + 1.5t", "costFactor": 2.5 }` @@ -470,7 +474,15 @@ the access legs used. In other cases where the access(CAR) is faster than transi The `costFactor` is used to add an additional cost to the leg´s generalized-cost. The time-penalty is multiplied with the cost-factor. A cost-factor of zero, gives no extra cost, while 1.0 will add the same amount to both time and cost. - """ + """.formatted( + dftAccessEgress + .penalty() + .asEnumMap() + .entrySet() + .stream() + .map(s -> "- %s = %s".formatted(s.getKey(), s.getValue())) + .collect(Collectors.joining("\n")) + ) ) .asEnumMap( StreetMode.class, From f5e7caef0b778c9279f29c75ca9bf7c1b4feed92 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Oct 2023 23:52:57 +0200 Subject: [PATCH 299/356] Improve tests and documentation --- docs/RouteRequest.md | 6 +++--- .../org/opentripplanner/framework/lang/StringUtils.java | 9 +++++++++ .../standalone/config/framework/json/EnumMapper.java | 7 ++----- .../standalone/config/framework/json/NodeInfo.java | 3 ++- .../config/routerequest/RouteRequestConfig.java | 8 +++++++- .../api/request/preference/StreetPreferencesTest.java | 5 ++--- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 791df446c89..e90ea91b549 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -408,9 +408,9 @@ performance will be better. The default values are -- CAR_TO_PARK = (timePenalty: 30m + 2.0 t, costFactor: 2.0) -- CAR_RENTAL = (timePenalty: 30m + 2.0 t, costFactor: 2.0) -- CAR_HAILING = (timePenalty: 30m + 2.0 t, costFactor: 2.0) +- `car-to-park` = (timePenalty: 30m + 2.0 t, costFactor: 2.0) +- `car-rental` = (timePenalty: 30m + 2.0 t, costFactor: 2.0) +- `car-hailing` = (timePenalty: 30m + 2.0 t, costFactor: 2.0) Example: `"car-to-park" : { "timePenalty": "10m + 1.5t", "costFactor": 2.5 }` diff --git a/src/main/java/org/opentripplanner/framework/lang/StringUtils.java b/src/main/java/org/opentripplanner/framework/lang/StringUtils.java index c726d03c66c..87613d61294 100644 --- a/src/main/java/org/opentripplanner/framework/lang/StringUtils.java +++ b/src/main/java/org/opentripplanner/framework/lang/StringUtils.java @@ -110,4 +110,13 @@ public static String padRight(String value, char ch, int width) { public static String quoteReplace(@Nonnull String text) { return text.replace('\'', '\"'); } + + /** + * Convert "HELLO_WORLD" or "Hello_World" to "hello-world". + *

      + * https://developer.mozilla.org/en-US/docs/Glossary/Kebab_case + */ + public static String kebabCase(String input) { + return input.toLowerCase().replace('_', '-'); + } } diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java b/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java index ce880058005..0e048a2e3e7 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java +++ b/src/main/java/org/opentripplanner/standalone/config/framework/json/EnumMapper.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.Optional; import org.opentripplanner.framework.doc.DocumentedEnum; +import org.opentripplanner.framework.lang.StringUtils; public class EnumMapper { @@ -23,11 +24,7 @@ public static Optional> mapToEnum2(String text, Class en) { - return kebabCase(en.name()); - } - - public static String kebabCase(String input) { - return input.toLowerCase().replace('_', '-'); + return StringUtils.kebabCase(en.name()); } /** diff --git a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java b/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java index 296c07805f9..06675475fd1 100644 --- a/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java +++ b/src/main/java/org/opentripplanner/standalone/config/framework/json/NodeInfo.java @@ -7,6 +7,7 @@ import java.util.Objects; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.tostring.ValueObjectToStringBuilder; /** @@ -137,7 +138,7 @@ public List> enumTypeValues() { */ public String toMarkdownString(Object value) { if (enumType != null) { - value = EnumMapper.kebabCase(value.toString()); + value = StringUtils.kebabCase(value.toString()); } return type.quote(value); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 49596759063..600579f5513 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -19,6 +19,7 @@ import java.util.stream.Collectors; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.framework.application.OTPFeature; +import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.routing.api.request.RequestModes; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; @@ -480,7 +481,12 @@ the access legs used. In other cases where the access(CAR) is faster than transi .asEnumMap() .entrySet() .stream() - .map(s -> "- %s = %s".formatted(s.getKey(), s.getValue())) + .map(s -> + "- `%s` = %s".formatted( + StringUtils.kebabCase(s.getKey().toString()), + s.getValue() + ) + ) .collect(Collectors.joining("\n")) ) ) diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java index 1d47337a312..08b102ea1bb 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java @@ -109,10 +109,9 @@ void testToString() { "routingTimeout: 3s, " + "elevator: ElevatorPreferences{boardTime: 2m}, " + "intersectionTraversalModel: CONSTANT, " + - "accessEgress: AccessEgressPreferences{" + - "penalty: TimeAndCostPenaltyForEnum{CAR_TO_PARK: " + + "accessEgress: AccessEgressPreferences{penalty: TimeAndCostPenaltyForEnum{CAR_TO_PARK: " + CAR_PENALTY + - "}, " + + ", CAR_RENTAL: (timePenalty: 30m + 2.0 t, costFactor: 2.0), CAR_HAILING: (timePenalty: 30m + 2.0 t, costFactor: 2.0)}, " + "maxDuration: DurationForStreetMode{default:5m}" + "}, " + "maxDirectDuration: DurationForStreetMode{default:10m}" + From 0ba3b9067b051a1e6a1ff6708acec0b186c4c587 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Oct 2023 15:08:48 +0200 Subject: [PATCH 300/356] Decorate direct itineraries with accessEgressPenalty --- docs/RouteRequest.md | 7 +-- .../framework/lang/StringUtils.java | 2 +- .../DirectItineraryPenaltyDecorator.java | 54 +++++++++++++++++++ .../router/street/DirectStreetRouter.java | 7 ++- .../preference/AccessEgressPreferences.java | 5 +- .../__snapshots__/CarSnapshotTest.snap | 6 +-- 6 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index e90ea91b549..6e19d72564b 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -408,9 +408,10 @@ performance will be better. The default values are -- `car-to-park` = (timePenalty: 30m + 2.0 t, costFactor: 2.0) -- `car-rental` = (timePenalty: 30m + 2.0 t, costFactor: 2.0) -- `car-hailing` = (timePenalty: 30m + 2.0 t, costFactor: 2.0) +- `car-to-park` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) +- `car-rental` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) +- `car-hailing` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) +- `flexible` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) Example: `"car-to-park" : { "timePenalty": "10m + 1.5t", "costFactor": 2.5 }` diff --git a/src/main/java/org/opentripplanner/framework/lang/StringUtils.java b/src/main/java/org/opentripplanner/framework/lang/StringUtils.java index 87613d61294..cbb32b9eaca 100644 --- a/src/main/java/org/opentripplanner/framework/lang/StringUtils.java +++ b/src/main/java/org/opentripplanner/framework/lang/StringUtils.java @@ -112,7 +112,7 @@ public static String quoteReplace(@Nonnull String text) { } /** - * Convert "HELLO_WORLD" or "Hello_World" to "hello-world". + * Convert "HELLO_WORLD" or "HellO_WorlD" to "hello-world". *

      * https://developer.mozilla.org/en-US/docs/Glossary/Kebab_case */ diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java new file mode 100644 index 00000000000..ec6a89ee64a --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java @@ -0,0 +1,54 @@ +package org.opentripplanner.routing.algorithm.raptoradapter.router.street; + +import java.util.List; +import java.util.Objects; +import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.model.plan.Leg; +import org.opentripplanner.model.plan.StreetLegBuilder; +import org.opentripplanner.routing.api.request.StreetMode; +import org.opentripplanner.routing.api.request.framework.TimeAndCostPenaltyForEnum; + +public class DirectItineraryPenaltyDecorator { + + private final StreetMode directMode; + private final TimeAndCostPenaltyForEnum penalty; + + public DirectItineraryPenaltyDecorator( + StreetMode directMode, + TimeAndCostPenaltyForEnum penalty + ) { + Objects.requireNonNull(directMode); + Objects.requireNonNull(penalty); + this.directMode = directMode; + this.penalty = penalty; + } + + public List applyPenalty(List itineraries) { + return itineraries + .stream() + .map(itin -> { + if (itin.hasTransit()) { + throw new IllegalArgumentException( + "The itinerary %s contains transit legs. No direct penalty can be applied.".formatted( + itin + ) + ); + } + var penalty = this.penalty.valueOf(directMode); + if (!penalty.isEmpty()) { + itin.transformStreetLegs(sl -> + StreetLegBuilder + .of(sl) + .withGeneralizedCost((int) (sl.getGeneralizedCost() * penalty.costFactor())) + .build() + ); + + var cost = itin.getLegs().stream().mapToInt(Leg::getGeneralizedCost).sum(); + + itin.setGeneralizedCost(cost); + } + return itin; + }) + .toList(); + } +} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java index 2c6b09c2fb2..af004a66b1f 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java @@ -61,7 +61,12 @@ public static List route(OtpServerRequestContext serverContext, Route directRequest.wheelchair(), directRequest.preferences().wheelchair() ); - return response; + + var decorator = new DirectItineraryPenaltyDecorator( + request.journey().modes().directMode, + request.preferences().street().accessEgress().penalty() + ); + return decorator.applyPenalty(response); } catch (PathNotFoundException e) { return Collections.emptyList(); } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java index b967bd34f58..ada495b19ba 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java @@ -22,14 +22,15 @@ public final class AccessEgressPreferences implements Serializable { private static final TimeAndCostPenalty DEFAULT_PENALTY = TimeAndCostPenalty.of( - TimePenalty.of(ofMinutes(30), 2f), - 2 + TimePenalty.of(ofMinutes(20), 2f), + 1.5 ); private static final TimeAndCostPenaltyForEnum DEFAULT_TIME_AND_COST = TimeAndCostPenaltyForEnum .of(StreetMode.class) .with(StreetMode.CAR_TO_PARK, DEFAULT_PENALTY) .with(StreetMode.CAR_HAILING, DEFAULT_PENALTY) .with(StreetMode.CAR_RENTAL, DEFAULT_PENALTY) + .with(StreetMode.FLEXIBLE, DEFAULT_PENALTY) .build(); public static final AccessEgressPreferences DEFAULT = new AccessEgressPreferences(); diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap index 8f527b15bf7..0ae0e948250 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap @@ -10,7 +10,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "details" : { }, "fare" : { } }, - "generalizedCost" : 467, + "generalizedCost": 518, "legs" : [ { "agencyTimeZoneOffset" : -25200000, @@ -25,7 +25,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "name" : "NW Pettygrove Ave. & NW 24th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost" : 61, + "generalizedCost": 91, "interlineWithPreviousLeg" : false, "legGeometry" : { "length" : 5, @@ -144,7 +144,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ }, "vertexType" : "BIKEPARK" }, - "generalizedCost" : 285, + "generalizedCost": 427, "interlineWithPreviousLeg" : false, "legGeometry" : { "length" : 5, From 64cff4a6198d02e909e34b3681759b351d6a09ad Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 19 Oct 2023 11:30:33 +0200 Subject: [PATCH 301/356] Use correct enum value in Transmodel schema --- .../org/opentripplanner/apis/transmodel/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 25cf95ca2f9..dad106418fe 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -774,7 +774,7 @@ type QueryType { "Input type for executing a travel search for a trip between two locations. Returns trip patterns describing suggested alternatives for the trip." trip( "Time and cost penalty on access/egress modes." - accessEgressPenalty: [PenaltyForStreetMode!] = [], + accessEgressPenalty: [PenaltyForStreetMode!] = [{streetMode : car_park, timePenalty : "20m + 2.0 t", costFactor : 1.5}, {streetMode : flexible, timePenalty : "20m + 2.0 t", costFactor : 1.5}], "The alightSlack is the minimum extra time after exiting a public transport vehicle. This is the default value used, if not overridden by the 'alightSlackList'." alightSlackDefault: Int = 0, "List of alightSlack for a given set of modes. Defaults: []" From a4fed172e1fd507dc49c3842e6c22551be46f15f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 20 Oct 2023 10:47:05 +0200 Subject: [PATCH 302/356] Remove penalty for direct itineraries --- .../DirectItineraryPenaltyDecorator.java | 54 ------------------- .../router/street/DirectStreetRouter.java | 6 +-- 2 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java deleted file mode 100644 index ec6a89ee64a..00000000000 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectItineraryPenaltyDecorator.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.opentripplanner.routing.algorithm.raptoradapter.router.street; - -import java.util.List; -import java.util.Objects; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; -import org.opentripplanner.model.plan.StreetLegBuilder; -import org.opentripplanner.routing.api.request.StreetMode; -import org.opentripplanner.routing.api.request.framework.TimeAndCostPenaltyForEnum; - -public class DirectItineraryPenaltyDecorator { - - private final StreetMode directMode; - private final TimeAndCostPenaltyForEnum penalty; - - public DirectItineraryPenaltyDecorator( - StreetMode directMode, - TimeAndCostPenaltyForEnum penalty - ) { - Objects.requireNonNull(directMode); - Objects.requireNonNull(penalty); - this.directMode = directMode; - this.penalty = penalty; - } - - public List applyPenalty(List itineraries) { - return itineraries - .stream() - .map(itin -> { - if (itin.hasTransit()) { - throw new IllegalArgumentException( - "The itinerary %s contains transit legs. No direct penalty can be applied.".formatted( - itin - ) - ); - } - var penalty = this.penalty.valueOf(directMode); - if (!penalty.isEmpty()) { - itin.transformStreetLegs(sl -> - StreetLegBuilder - .of(sl) - .withGeneralizedCost((int) (sl.getGeneralizedCost() * penalty.costFactor())) - .build() - ); - - var cost = itin.getLegs().stream().mapToInt(Leg::getGeneralizedCost).sum(); - - itin.setGeneralizedCost(cost); - } - return itin; - }) - .toList(); - } -} diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java index af004a66b1f..3c51f84fda4 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java @@ -62,11 +62,7 @@ public static List route(OtpServerRequestContext serverContext, Route directRequest.preferences().wheelchair() ); - var decorator = new DirectItineraryPenaltyDecorator( - request.journey().modes().directMode, - request.preferences().street().accessEgress().penalty() - ); - return decorator.applyPenalty(response); + return response; } catch (PathNotFoundException e) { return Collections.emptyList(); } From a2d84d72176702190cf9c79426cfcd2ed761c5a2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 20 Oct 2023 10:53:06 +0200 Subject: [PATCH 303/356] Extract method for formatting default values --- .../routerequest/RouteRequestConfig.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 600579f5513..c4b0b0bd8cb 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -24,6 +24,7 @@ import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.StreetMode; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; +import org.opentripplanner.routing.api.request.preference.AccessEgressPreferences; import org.opentripplanner.routing.api.request.preference.BikePreferences; import org.opentripplanner.routing.api.request.preference.CarPreferences; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; @@ -476,18 +477,7 @@ the access legs used. In other cases where the access(CAR) is faster than transi time-penalty is multiplied with the cost-factor. A cost-factor of zero, gives no extra cost, while 1.0 will add the same amount to both time and cost. """.formatted( - dftAccessEgress - .penalty() - .asEnumMap() - .entrySet() - .stream() - .map(s -> - "- `%s` = %s".formatted( - StringUtils.kebabCase(s.getKey().toString()), - s.getValue() - ) - ) - .collect(Collectors.joining("\n")) + formatPenaltyDefaultValues(dftAccessEgress) ) ) .asEnumMap( @@ -591,6 +581,16 @@ The street search(AStar) aborts after this duration and any paths found are retu ); } + private static String formatPenaltyDefaultValues(AccessEgressPreferences dftAccessEgress) { + return dftAccessEgress + .penalty() + .asEnumMap() + .entrySet() + .stream() + .map(s -> "- `%s` = %s".formatted(StringUtils.kebabCase(s.getKey().toString()), s.getValue())) + .collect(Collectors.joining("\n")); + } + private static void mapCarPreferences(NodeAdapter root, CarPreferences.Builder builder) { var dft = builder.original(); NodeAdapter c = root.of("car").since(V2_5).summary("Car preferences.").asObject(); From 3f909f03b37dc3757878d0c58ece31e93567e007 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 20 Oct 2023 11:06:14 +0200 Subject: [PATCH 304/356] Set penalty to zero in test --- .../org/opentripplanner/ext/flex/FlexIntegrationTest.java | 6 ++++++ .../api/request/preference/StreetPreferencesTest.java | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java index a0585a9e6f2..f414572ecf2 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/FlexIntegrationTest.java @@ -32,6 +32,7 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.routing.api.RoutingService; import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.framework.TimeAndCostPenalty; import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.transit.service.TransitModel; @@ -224,6 +225,11 @@ private static List getItineraries( request.setTo(to); request.setNumItineraries(10); request.setSearchWindow(Duration.ofHours(2)); + request.withPreferences(p -> + p.withStreet(s -> + s.withAccessEgress(ae -> ae.withPenalty(Map.of(FLEXIBLE, TimeAndCostPenalty.ZERO))) + ) + ); var modes = request.journey().modes().copyOf(); modes.withEgressMode(FLEXIBLE); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java index 08b102ea1bb..0289c24e837 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java @@ -111,7 +111,8 @@ void testToString() { "intersectionTraversalModel: CONSTANT, " + "accessEgress: AccessEgressPreferences{penalty: TimeAndCostPenaltyForEnum{CAR_TO_PARK: " + CAR_PENALTY + - ", CAR_RENTAL: (timePenalty: 30m + 2.0 t, costFactor: 2.0), CAR_HAILING: (timePenalty: 30m + 2.0 t, costFactor: 2.0)}, " + + ", CAR_RENTAL: (timePenalty: 20m + 2.0 t, costFactor: 1.50), CAR_HAILING: (timePenalty: 20m + 2.0 t, costFactor: 1.50), " + + "FLEXIBLE: (timePenalty: 20m + 2.0 t, costFactor: 1.50)}, " + "maxDuration: DurationForStreetMode{default:5m}" + "}, " + "maxDirectDuration: DurationForStreetMode{default:10m}" + From 3f2084fc0c5c0f0dd110f7e1c7a56bd116964ce4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 1 Nov 2023 15:03:38 +0100 Subject: [PATCH 305/356] Subtract generalized cost that was previously added --- .../RemoveNonTransitItinerariesBasedOnGeneralizedCost.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java index 427084a55f6..1980838bec0 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java @@ -43,7 +43,7 @@ public List flagForRemoval(List itineraries) { // ALL itineraries are considered here. Both transit and non-transit OptionalInt minGeneralizedCost = itineraries .stream() - .mapToInt(Itinerary::getGeneralizedCost) + .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) .min(); if (minGeneralizedCost.isEmpty()) { @@ -58,7 +58,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - .filter(it -> !it.hasTransit() && it.getGeneralizedCost() > maxLimit) + .filter(it -> !it.hasTransit() && it.getGeneralizedCostIncludingPenalty() > maxLimit) .collect(Collectors.toList()); } } From 16f21df832748a4eba7bcc49121f7ce392eacc7f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 30 Jan 2024 22:24:11 +0100 Subject: [PATCH 306/356] Fix merge artifacts --- .../graph_builder/module/NearbyStopFinder.java | 5 +---- .../algorithm/mapping/__snapshots__/CarSnapshotTest.snap | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index 0cac2a21308..22a00258e87 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -273,10 +273,7 @@ private SkipEdgeStrategy getSkipEdgeStrategy() { var durationSkipEdgeStrategy = new DurationSkipEdgeStrategy(durationLimit); if (maxStopCount > 0) { - var strategy = new MaxCountSkipEdgeStrategy<>( - maxStopCount, - NearbyStopFinder::hasReachedStop - ); + var strategy = new MaxCountSkipEdgeStrategy<>(maxStopCount, NearbyStopFinder::hasReachedStop); return new ComposingSkipEdgeStrategy<>(strategy, durationSkipEdgeStrategy); } return durationSkipEdgeStrategy; diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap index 0ae0e948250..8f527b15bf7 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap @@ -10,7 +10,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "details" : { }, "fare" : { } }, - "generalizedCost": 518, + "generalizedCost" : 467, "legs" : [ { "agencyTimeZoneOffset" : -25200000, @@ -25,7 +25,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "name" : "NW Pettygrove Ave. & NW 24th Ave. (P1)", "vertexType" : "NORMAL" }, - "generalizedCost": 91, + "generalizedCost" : 61, "interlineWithPreviousLeg" : false, "legGeometry" : { "length" : 5, @@ -144,7 +144,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ }, "vertexType" : "BIKEPARK" }, - "generalizedCost": 427, + "generalizedCost" : 285, "interlineWithPreviousLeg" : false, "legGeometry" : { "length" : 5, From d06a4dbb6c59ad3a355269bb276750e3eb3aa0ed Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 1 Feb 2024 14:27:11 +0100 Subject: [PATCH 307/356] Revert changes, done in other PR --- .../RemoveNonTransitItinerariesBasedOnGeneralizedCost.java | 4 ++-- .../raptoradapter/router/street/DirectStreetRouter.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java index 1980838bec0..427084a55f6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/street/RemoveNonTransitItinerariesBasedOnGeneralizedCost.java @@ -43,7 +43,7 @@ public List flagForRemoval(List itineraries) { // ALL itineraries are considered here. Both transit and non-transit OptionalInt minGeneralizedCost = itineraries .stream() - .mapToInt(Itinerary::getGeneralizedCostIncludingPenalty) + .mapToInt(Itinerary::getGeneralizedCost) .min(); if (minGeneralizedCost.isEmpty()) { @@ -58,7 +58,7 @@ public List flagForRemoval(List itineraries) { return itineraries .stream() - .filter(it -> !it.hasTransit() && it.getGeneralizedCostIncludingPenalty() > maxLimit) + .filter(it -> !it.hasTransit() && it.getGeneralizedCost() > maxLimit) .collect(Collectors.toList()); } } diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java index 3c51f84fda4..2c6b09c2fb2 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DirectStreetRouter.java @@ -61,7 +61,6 @@ public static List route(OtpServerRequestContext serverContext, Route directRequest.wheelchair(), directRequest.preferences().wheelchair() ); - return response; } catch (PathNotFoundException e) { return Collections.emptyList(); From 7fc2e8767dca535fca6e2fb35ede82b80f2b74b3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 1 Feb 2024 14:42:50 +0100 Subject: [PATCH 308/356] Resolve merge artifact --- src/test/java/org/opentripplanner/model/plan/ItineraryTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java index a406ef69dcb..142ced31504 100644 --- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java +++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java @@ -166,7 +166,6 @@ void walkBusBusWalkTrainWalk() { } @Test - void legIndex() { void walkSeparateFromBike() { var itin = newItinerary(A, T11_00).walk(D2m, B).bicycle(T11_05, T11_15, D).walk(D3m, E).build(); From 488f34589d76a54bb307f98797330b3e0dc7eff7 Mon Sep 17 00:00:00 2001 From: eibakke Date: Thu, 1 Feb 2024 15:32:51 +0100 Subject: [PATCH 309/356] Uses BERLIN coordinates and polygon instead of non-sense ones in GroupStopTest. --- .../transit/model/site/GroupStopTest.java | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java b/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java index dcf9bc3aeed..b57566b68ed 100644 --- a/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java +++ b/src/test/java/org/opentripplanner/transit/model/site/GroupStopTest.java @@ -9,9 +9,9 @@ import java.util.List; import java.util.Objects; import org.junit.jupiter.api.Test; -import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.framework.geometry.GeometryUtils; +import org.opentripplanner._support.geometry.Coordinates; +import org.opentripplanner._support.geometry.Polygons; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.transit.model._data.TransitModelForTest; @@ -24,7 +24,9 @@ class GroupStopTest { private static final String ID = "1"; private static final I18NString NAME = new NonLocalizedString("name"); - private static final StopLocation STOP_LOCATION = TEST_MODEL.stop("1:stop", 1d, 1d).build(); + private static final StopLocation STOP_LOCATION = TEST_MODEL + .stop("1:stop", Coordinates.BERLIN.getX(), Coordinates.BERLIN.getY()) + .build(); private static final GroupStop subject = StopModel .of() .groupStop(TransitModelForTest.id(ID)) @@ -34,8 +36,12 @@ class GroupStopTest { @Test void testGroupStopGeometry() { - StopLocation stopLocation1 = TEST_MODEL.stop("1:stop", 1d, 1d).build(); - StopLocation stopLocation2 = TEST_MODEL.stop("2:stop", 2d, 2d).build(); + StopLocation stopLocation1 = TEST_MODEL + .stop("1:stop", Coordinates.BERLIN.getX(), Coordinates.BERLIN.getY()) + .build(); + StopLocation stopLocation2 = TEST_MODEL + .stop("2:stop", Coordinates.HAMBURG.getX(), Coordinates.HAMBURG.getY()) + .build(); GroupStop groupStop = StopModel .of() @@ -54,16 +60,8 @@ void testGroupStopGeometry() { @Test void testGroupStopEncompassingAreaGeometry() { - Geometry encompassingAreaGeometry = GeometryUtils - .getGeometryFactory() - .toGeometry(new Envelope(1d, 2d, 1d, 2d)); - StopLocation stopLocation = TEST_MODEL - .stop( - "1:stop", - encompassingAreaGeometry.getCentroid().getX(), - encompassingAreaGeometry.getCentroid().getY() - ) + .stop("1:stop", Coordinates.BERLIN.getX(), Coordinates.BERLIN.getY()) .build(); GroupStop groupStop = StopModel @@ -71,14 +69,14 @@ void testGroupStopEncompassingAreaGeometry() { .groupStop(TransitModelForTest.id(ID)) .withName(NAME) .addLocation(stopLocation) - .withEncompassingAreaGeometries(List.of(encompassingAreaGeometry)) + .withEncompassingAreaGeometries(List.of(Polygons.BERLIN)) .build(); Geometry groupStopGeometry = Objects.requireNonNull(groupStop.getGeometry()).getGeometryN(0); assertEquals(stopLocation.getGeometry(), groupStopGeometry); assertEquals( - encompassingAreaGeometry, + Polygons.BERLIN, groupStop.getEncompassingAreaGeometry().orElseThrow().getGeometryN(0) ); } From f35d8ca9b56e89c63d5414f7d3e25809f0cee364 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 31 Jan 2024 14:22:22 +0100 Subject: [PATCH 310/356] Swap out stop code --- .../DecorateConsolidatedStopNames.java | 21 +++++++++++++++++-- .../model/ConsolidatedStopLeg.java | 14 ++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 8fcba82a357..99c56bb3622 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -5,6 +5,10 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; +import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.RegularStopBuilder; +import org.opentripplanner.transit.model.site.StopLocation; /** * A decorating filter that checks if a transit leg contains any primary stops and if it does, @@ -34,10 +38,12 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { i.transformTransitLegs(leg -> { if (leg instanceof ScheduledTransitLeg stl && needsToRenameStops(stl)) { var agency = leg.getAgency(); + var from= modify(stl.getFrom().stop, agency); + var to = modify(stl.getTo().stop, agency); return new ConsolidatedStopLeg( stl, - service.agencySpecificName(stl.getFrom().stop, agency), - service.agencySpecificName(stl.getTo().stop, agency) + from, + to ); } else { return leg; @@ -45,6 +51,17 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { }); } + private StopLocation modify(StopLocation stop, Agency agency) { + if(stop instanceof RegularStop rs){ + return rs.copy() + .withName(service.agencySpecificName(stop, agency)) + .withCode("XXXXX").build(); + } + else { + return stop; + } + } + private boolean needsToRenameStops(ScheduledTransitLeg stl) { return (service.isPrimaryStop(stl.getFrom().stop) || service.isPrimaryStop(stl.getTo().stop)); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java index e201c7ed805..1ad12adee26 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java @@ -1,28 +1,28 @@ package org.opentripplanner.ext.stopconsolidation.model; -import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.model.plan.ScheduledTransitLegBuilder; +import org.opentripplanner.transit.model.site.StopLocation; public class ConsolidatedStopLeg extends ScheduledTransitLeg { - private final I18NString fromName; - private final I18NString toName; + private final StopLocation fromName; + private final StopLocation toName; - public ConsolidatedStopLeg(ScheduledTransitLeg original, I18NString fromName, I18NString toName) { + public ConsolidatedStopLeg(ScheduledTransitLeg original, StopLocation fromName, StopLocation toName) { super(new ScheduledTransitLegBuilder<>(original)); - this.fromName = fromName; + this.fromName= fromName; this.toName = toName; } @Override public Place getFrom() { - return Place.forStop(super.getFrom().stop, fromName); + return Place.forStop(fromName); } @Override public Place getTo() { - return Place.forStop(super.getTo().stop, toName); + return Place.forStop(toName); } } From 7a7b35af7085bd7f9d13f8fafce8baed9800accc Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 31 Jan 2024 18:32:17 +0100 Subject: [PATCH 311/356] Add agency-specific stop code --- .../DecorateConsolidatedStopNames.java | 20 +++++------ .../StopConsolidationService.java | 1 + .../DefaultStopConsolidationService.java | 34 +++++++++++++------ .../model/ConsolidatedStopLeg.java | 14 ++++---- .../org/opentripplanner/model/plan/Place.java | 6 +--- 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 99c56bb3622..887125697f9 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -7,7 +7,6 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.RegularStopBuilder; import org.opentripplanner.transit.model.site.StopLocation; /** @@ -38,13 +37,9 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { i.transformTransitLegs(leg -> { if (leg instanceof ScheduledTransitLeg stl && needsToRenameStops(stl)) { var agency = leg.getAgency(); - var from= modify(stl.getFrom().stop, agency); + var from = modify(stl.getFrom().stop, agency); var to = modify(stl.getTo().stop, agency); - return new ConsolidatedStopLeg( - stl, - from, - to - ); + return new ConsolidatedStopLeg(stl, from, to); } else { return leg; } @@ -52,12 +47,13 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { } private StopLocation modify(StopLocation stop, Agency agency) { - if(stop instanceof RegularStop rs){ - return rs.copy() + if (stop instanceof RegularStop rs) { + return rs + .copy() .withName(service.agencySpecificName(stop, agency)) - .withCode("XXXXX").build(); - } - else { + .withCode(service.agencySpecificCode(stop, agency)) + .build(); + } else { return stop; } } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java index 2418d8f5625..4f03095b0dc 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java @@ -33,4 +33,5 @@ public interface StopConsolidationService { * For a given primary stop look up the name as it was originally defined in the agency's feed. */ I18NString agencySpecificName(StopLocation stop, Agency agency); + String agencySpecificCode(StopLocation stop, Agency agency); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java index 54bd960d078..ee395df9497 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java @@ -2,7 +2,9 @@ import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; +import javax.annotation.Nonnull; import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; @@ -71,16 +73,28 @@ public I18NString agencySpecificName(StopLocation stop, Agency agency) { if (agency.getId().getFeedId().equals(stop.getId().getFeedId())) { return stop.getName(); } else { - return repo - .groups() - .stream() - .filter(r -> r.primary().equals(stop.getId())) - .flatMap(g -> g.secondaries().stream()) - .filter(secondary -> secondary.getFeedId().equals(agency.getId().getFeedId())) - .findAny() - .map(id -> transitModel.getStopModel().getRegularStop(id)) - .map(RegularStop::getName) - .orElseGet(stop::getName); + return agencySpecificStop(stop, agency).map(RegularStop::getName).orElseGet(stop::getName); } } + + @Override + public String agencySpecificCode(StopLocation stop, Agency agency) { + if (agency.getId().getFeedId().equals(stop.getId().getFeedId())) { + return stop.getCode(); + } else { + return agencySpecificStop(stop, agency).map(RegularStop::getCode).orElseGet(stop::getCode); + } + } + + @Nonnull + private Optional agencySpecificStop(StopLocation stop, Agency agency) { + return repo + .groups() + .stream() + .filter(r -> r.primary().equals(stop.getId())) + .flatMap(g -> g.secondaries().stream()) + .filter(secondary -> secondary.getFeedId().equals(agency.getId().getFeedId())) + .findAny() + .map(id -> transitModel.getStopModel().getRegularStop(id)); + } } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java index 1ad12adee26..39f06bd6347 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/model/ConsolidatedStopLeg.java @@ -7,22 +7,22 @@ public class ConsolidatedStopLeg extends ScheduledTransitLeg { - private final StopLocation fromName; - private final StopLocation toName; + private final StopLocation from; + private final StopLocation to; - public ConsolidatedStopLeg(ScheduledTransitLeg original, StopLocation fromName, StopLocation toName) { + public ConsolidatedStopLeg(ScheduledTransitLeg original, StopLocation from, StopLocation to) { super(new ScheduledTransitLegBuilder<>(original)); - this.fromName= fromName; - this.toName = toName; + this.from = from; + this.to = to; } @Override public Place getFrom() { - return Place.forStop(fromName); + return Place.forStop(from); } @Override public Place getTo() { - return Place.forStop(toName); + return Place.forStop(to); } } diff --git a/src/main/java/org/opentripplanner/model/plan/Place.java b/src/main/java/org/opentripplanner/model/plan/Place.java index 71c6d9bc188..fe3a9dee420 100644 --- a/src/main/java/org/opentripplanner/model/plan/Place.java +++ b/src/main/java/org/opentripplanner/model/plan/Place.java @@ -90,11 +90,7 @@ public static Place normal(Vertex vertex, I18NString name) { } public static Place forStop(StopLocation stop) { - return forStop(stop, stop.getName()); - } - - public static Place forStop(StopLocation stop, I18NString nameOverride) { - return new Place(nameOverride, stop.getCoordinate(), VertexType.TRANSIT, stop, null, null); + return new Place(stop.getName(), stop.getCoordinate(), VertexType.TRANSIT, stop, null, null); } public static Place forFlexStop(StopLocation stop, Vertex vertex) { From 866bc90a729ec28bae8778c92077659f36a727bd Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 31 Jan 2024 21:21:00 +0100 Subject: [PATCH 312/356] Implement logic for fetching primary stop --- .../stopconsolidation/DecorateConsolidatedStopNames.java | 2 +- .../ext/stopconsolidation/StopConsolidationService.java | 2 ++ .../internal/DefaultStopConsolidationService.java | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 887125697f9..c05223d2fb4 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -37,7 +37,7 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { i.transformTransitLegs(leg -> { if (leg instanceof ScheduledTransitLeg stl && needsToRenameStops(stl)) { var agency = leg.getAgency(); - var from = modify(stl.getFrom().stop, agency); + var from = service.primaryStop(stl.getFrom().stop.getId()); var to = modify(stl.getTo().stop, agency); return new ConsolidatedStopLeg(stl, from, to); } else { diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java index 4f03095b0dc..7dcea13f420 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java @@ -34,4 +34,6 @@ public interface StopConsolidationService { */ I18NString agencySpecificName(StopLocation stop, Agency agency); String agencySpecificCode(StopLocation stop, Agency agency); + + StopLocation primaryStop(FeedScopedId id); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java index ee395df9497..ea8dd5b7f99 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java @@ -7,6 +7,7 @@ import javax.annotation.Nonnull; import org.opentripplanner.ext.stopconsolidation.StopConsolidationRepository; import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; +import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -97,4 +98,10 @@ private Optional agencySpecificStop(StopLocation stop, Agency agenc .findAny() .map(id -> transitModel.getStopModel().getRegularStop(id)); } + + @Override + public StopLocation primaryStop(FeedScopedId id) { + var primaryId = repo.groups().stream().filter(g -> g.secondaries().contains(id)).map(ConsolidatedStopGroup::primary).findAny().orElse(id); + return transitModel.getStopModel().getRegularStop(primaryId); + } } From c9ef9628b1a1a9391b5c7dac9c45c6c3f163b718 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 31 Jan 2024 21:40:36 +0100 Subject: [PATCH 313/356] Adapt check for when names should be swapped --- .../ext/stopconsolidation/DecorateConsolidatedStopNames.java | 2 +- .../ext/stopconsolidation/StopConsolidationService.java | 3 +++ .../internal/DefaultStopConsolidationService.java | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index c05223d2fb4..8dcb558b361 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -59,6 +59,6 @@ private StopLocation modify(StopLocation stop, Agency agency) { } private boolean needsToRenameStops(ScheduledTransitLeg stl) { - return (service.isPrimaryStop(stl.getFrom().stop) || service.isPrimaryStop(stl.getTo().stop)); + return (service.isSecondaryStop(stl.getFrom().stop) || service.isPrimaryStop(stl.getTo().stop)); } } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java index 7dcea13f420..969276c9a28 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java @@ -24,6 +24,8 @@ public interface StopConsolidationService { */ boolean isPrimaryStop(StopLocation stop); + boolean isSecondaryStop(StopLocation stop); + /** * Are any stop consolidations defined? */ @@ -36,4 +38,5 @@ public interface StopConsolidationService { String agencySpecificCode(StopLocation stop, Agency agency); StopLocation primaryStop(FeedScopedId id); + } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java index ea8dd5b7f99..7d93433ea01 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java @@ -64,6 +64,11 @@ public boolean isPrimaryStop(StopLocation stop) { return repo.groups().stream().anyMatch(r -> r.primary().equals(stop.getId())); } + @Override + public boolean isSecondaryStop(StopLocation stop) { + return repo.groups().stream().anyMatch(r -> r.secondaries().contains(stop.getId())); + } + @Override public boolean isActive() { return !repo.groups().isEmpty(); From 6e2cfffbe497c16d4be8acb8d4962e6a737b2650 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 1 Feb 2024 13:03:46 +0100 Subject: [PATCH 314/356] Use more general version of agencySpecific methods --- .../DecorateConsolidatedStopNamesTest.java | 4 +-- .../DecorateConsolidatedStopNames.java | 17 +----------- .../StopConsolidationService.java | 4 +-- .../DefaultStopConsolidationService.java | 27 ++++++++----------- 4 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java b/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java index 38af8ea7187..d823a55cc4a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNamesTest.java @@ -37,8 +37,8 @@ void changeNames() { filter.decorate(itinerary); - var updatedLeg = itinerary.getLegs().get(0); - assertEquals(STOP_D.getName(), updatedLeg.getFrom().name); + var updatedLeg = itinerary.getLegs().getFirst(); + assertEquals(STOP_C.getName(), updatedLeg.getFrom().name); assertEquals(STOP_D.getName(), updatedLeg.getTo().name); } } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 8dcb558b361..2a09bb64255 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -5,9 +5,6 @@ import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.ScheduledTransitLeg; import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; -import org.opentripplanner.transit.model.organization.Agency; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.StopLocation; /** * A decorating filter that checks if a transit leg contains any primary stops and if it does, @@ -38,7 +35,7 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { if (leg instanceof ScheduledTransitLeg stl && needsToRenameStops(stl)) { var agency = leg.getAgency(); var from = service.primaryStop(stl.getFrom().stop.getId()); - var to = modify(stl.getTo().stop, agency); + var to = service.agencySpecificStop(stl.getTo().stop, agency); return new ConsolidatedStopLeg(stl, from, to); } else { return leg; @@ -46,18 +43,6 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { }); } - private StopLocation modify(StopLocation stop, Agency agency) { - if (stop instanceof RegularStop rs) { - return rs - .copy() - .withName(service.agencySpecificName(stop, agency)) - .withCode(service.agencySpecificCode(stop, agency)) - .build(); - } else { - return stop; - } - } - private boolean needsToRenameStops(ScheduledTransitLeg stl) { return (service.isSecondaryStop(stl.getFrom().stop) || service.isPrimaryStop(stl.getTo().stop)); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java index 969276c9a28..036e99610f8 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java @@ -34,9 +34,7 @@ public interface StopConsolidationService { /** * For a given primary stop look up the name as it was originally defined in the agency's feed. */ - I18NString agencySpecificName(StopLocation stop, Agency agency); - String agencySpecificCode(StopLocation stop, Agency agency); + StopLocation agencySpecificStop(StopLocation stop, Agency agency); StopLocation primaryStop(FeedScopedId id); - } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java index 7d93433ea01..5011a848210 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java @@ -9,10 +9,8 @@ import org.opentripplanner.ext.stopconsolidation.StopConsolidationService; import org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; -import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; -import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.service.TransitModel; import org.slf4j.Logger; @@ -75,25 +73,16 @@ public boolean isActive() { } @Override - public I18NString agencySpecificName(StopLocation stop, Agency agency) { + public StopLocation agencySpecificStop(StopLocation stop, Agency agency) { if (agency.getId().getFeedId().equals(stop.getId().getFeedId())) { - return stop.getName(); + return stop; } else { - return agencySpecificStop(stop, agency).map(RegularStop::getName).orElseGet(stop::getName); - } - } - - @Override - public String agencySpecificCode(StopLocation stop, Agency agency) { - if (agency.getId().getFeedId().equals(stop.getId().getFeedId())) { - return stop.getCode(); - } else { - return agencySpecificStop(stop, agency).map(RegularStop::getCode).orElseGet(stop::getCode); + return agencySpecificStopOpt(stop, agency).orElse(stop); } } @Nonnull - private Optional agencySpecificStop(StopLocation stop, Agency agency) { + private Optional agencySpecificStopOpt(StopLocation stop, Agency agency) { return repo .groups() .stream() @@ -106,7 +95,13 @@ private Optional agencySpecificStop(StopLocation stop, Agency agenc @Override public StopLocation primaryStop(FeedScopedId id) { - var primaryId = repo.groups().stream().filter(g -> g.secondaries().contains(id)).map(ConsolidatedStopGroup::primary).findAny().orElse(id); + var primaryId = repo + .groups() + .stream() + .filter(g -> g.secondaries().contains(id)) + .map(ConsolidatedStopGroup::primary) + .findAny() + .orElse(id); return transitModel.getStopModel().getRegularStop(primaryId); } } From 85d762a17b0895abd1e040369e28487401d7e991 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 1 Feb 2024 17:25:50 +0100 Subject: [PATCH 315/356] Improve documentation --- .../ext/stopconsolidation/StopConsolidationService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java index 036e99610f8..a829a905e27 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/StopConsolidationService.java @@ -2,7 +2,6 @@ import java.util.List; import org.opentripplanner.ext.stopconsolidation.model.StopReplacement; -import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; @@ -24,6 +23,9 @@ public interface StopConsolidationService { */ boolean isPrimaryStop(StopLocation stop); + /** + * Is the given stop a secondary stop as defined by the stop consolidation configuration? + */ boolean isSecondaryStop(StopLocation stop); /** @@ -32,9 +34,12 @@ public interface StopConsolidationService { boolean isActive(); /** - * For a given primary stop look up the name as it was originally defined in the agency's feed. + * For a given primary stop look up secondary feed as it was originally defined in the agency's feed. */ StopLocation agencySpecificStop(StopLocation stop, Agency agency); + /** + * For a given stop id return the primary stop if it is part of a consolidated stop group. + */ StopLocation primaryStop(FeedScopedId id); } From bd51be9ed1694f195186e5ba0ea576491509aab2 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 1 Feb 2024 18:23:29 +0000 Subject: [PATCH 316/356] Add changelog entry for #5648 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 59d762fb58c..c6bb826884c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -85,6 +85,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Add flexibleArea to GroupStop Quays [#5625](https://github.com/opentripplanner/OpenTripPlanner/pull/5625) - Pass-through should override transit-group-priority [#5638](https://github.com/opentripplanner/OpenTripPlanner/pull/5638) - Introduce `generalizedCostPlusPenalty` to make cost comparsion fairer [#5483](https://github.com/opentripplanner/OpenTripPlanner/pull/5483) +- Separate walk time from non-transit time [#5648](https://github.com/opentripplanner/OpenTripPlanner/pull/5648) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From c48bb220949d1080742cc2723c86a5c1fb81ae0d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 2 Feb 2024 08:08:20 +0100 Subject: [PATCH 317/356] Incorporate review feedback --- .../ext/fares/impl/DefaultFareServiceTest.java | 2 ++ .../ext/fares/impl/FaresIntegrationTest.java | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java index 5f4317a5f4f..cae23f60800 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/DefaultFareServiceTest.java @@ -59,6 +59,8 @@ void simpleZoneBasedFare() { var legProducts = fare.getLegProducts().get(itin.getTransitLeg(0)); assertEquals( List.of( + // reminder: the FareProductUse's id are a (non-random) UUID computed from the start time of the leg + // plus some properties from the product itself like the id, price, rider category and medium new FareProductUse("1d270201-412b-3b86-80f6-92ab144fa2e5", AIRPORT_TO_CITY_CENTER_PRODUCT) ), legProducts diff --git a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java index a7dd4a92311..7b822b03059 100644 --- a/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/fares/impl/FaresIntegrationTest.java @@ -76,11 +76,12 @@ public void testPortland() { .toInstant(); ItineraryFares fare = getFare(from, to, startTime, serverContext); - var fpu = List.copyOf(fare.getLegProducts().values()).getFirst(); - assertEquals(List.of(fpu), List.copyOf(fare.getLegProducts().values())); + var fpu = List.copyOf(fare.getLegProducts().values()); + assertEquals(1, fpu.size()); - assertEquals(Money.usDollars(2f), fpu.product().price()); - assertEquals("prt:19", fpu.product().id().toString()); + var fp = fpu.getFirst(); + assertEquals(Money.usDollars(2f), fp.product().price()); + assertEquals("prt:19", fp.product().id().toString()); // long trip From b2349c34a6c861ba5633a5cd0d8b2c7e1d1d594e Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Fri, 2 Feb 2024 07:55:54 +0000 Subject: [PATCH 318/356] Add changelog entry for #5645 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index c6bb826884c..c58b751e355 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -86,6 +86,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Pass-through should override transit-group-priority [#5638](https://github.com/opentripplanner/OpenTripPlanner/pull/5638) - Introduce `generalizedCostPlusPenalty` to make cost comparsion fairer [#5483](https://github.com/opentripplanner/OpenTripPlanner/pull/5483) - Separate walk time from non-transit time [#5648](https://github.com/opentripplanner/OpenTripPlanner/pull/5648) +- Remove [#5645](https://github.com/opentripplanner/OpenTripPlanner/pull/5645) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 3b667020e270cebf96e9ed3ab70cc0ef6eca4cc3 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Fri, 2 Feb 2024 07:56:09 +0000 Subject: [PATCH 319/356] Bump serialization version id for #5645 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ce77a303d7d..38d646623b2 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 140 + 141 30.1 2.50 From e523ff93797a18b732998ba865d475ea09d6eb73 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 2 Feb 2024 10:04:00 +0100 Subject: [PATCH 320/356] Update changelog [ci skip] --- docs/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index c58b751e355..37c8d26053e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -86,7 +86,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Pass-through should override transit-group-priority [#5638](https://github.com/opentripplanner/OpenTripPlanner/pull/5638) - Introduce `generalizedCostPlusPenalty` to make cost comparsion fairer [#5483](https://github.com/opentripplanner/OpenTripPlanner/pull/5483) - Separate walk time from non-transit time [#5648](https://github.com/opentripplanner/OpenTripPlanner/pull/5648) -- Remove [#5645](https://github.com/opentripplanner/OpenTripPlanner/pull/5645) +- Remove "fare" [#5645](https://github.com/opentripplanner/OpenTripPlanner/pull/5645) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 634b3398a033c247ac625bead890280cc3bebb60 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Mon, 5 Feb 2024 06:52:01 +0000 Subject: [PATCH 321/356] Bump serialization version id for #5640 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bc8ee82b7ec..2bbfec9490a 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 141 + 142 30.2 2.50 From 9f66f5db54ed12a6b426d50b2f7f5acb1c7db1d2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 5 Feb 2024 09:35:30 +0100 Subject: [PATCH 322/356] Move method into sandbox --- .../ext/geocoder/LuceneIndexTest.java | 15 +++++------- .../ext/geocoder/StopClusterMapper.java | 24 +++++++++++++------ .../service/DefaultTransitService.java | 15 ------------ .../transit/service/TransitService.java | 12 ---------- .../service/DefaultTransitServiceTest.java | 7 ------ 5 files changed, 23 insertions(+), 50 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 8dc3ff77a01..b1fb33dfdd3 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -21,6 +21,7 @@ import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; @@ -131,15 +132,6 @@ public List getModesOfStopLocation(StopLocation stop) { } } - @Override - public List getAgenciesForStopLocation(StopLocation stop) { - if (stop.equals(ALEXANDERPLATZ_BUS)) { - return List.of(BVG); - } else { - return List.of(); - } - } - @Override public Agency getAgencyForId(FeedScopedId id) { if (id.equals(BVG.getId())) { @@ -148,6 +140,11 @@ public Agency getAgencyForId(FeedScopedId id) { return null; } + @Override + public Set getRoutesForStop(StopLocation stop) { + return Set.of(TransitModelForTest.route("route1").withAgency(BVG).build()); + } + @Override public FeedInfo getFeedInfo(String feedId) { return new FeedInfo( diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 10243665ac8..6f16d4a0cce 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -2,11 +2,13 @@ import com.google.common.collect.Iterables; import java.util.Collection; +import java.util.List; import java.util.Optional; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; @@ -59,8 +61,7 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = transitService - .getAgenciesForStopLocationsGroup(g) + var agencies = agenciesForStopLocationsGroup(g) .stream() .map(s -> s.getId().toString()) .toList(); @@ -75,11 +76,7 @@ LuceneStopCluster map(StopLocationsGroup g) { } Optional map(StopLocation sl) { - var agencies = transitService - .getAgenciesForStopLocation(sl) - .stream() - .map(a -> a.getId().toString()) - .toList(); + var agencies = agenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); return Optional .ofNullable(sl.getName()) .map(name -> { @@ -95,6 +92,19 @@ Optional map(StopLocation sl) { }); } + private List agenciesForStopLocation(StopLocation stop) { + return transitService.getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); + } + + private List agenciesForStopLocationsGroup(StopLocationsGroup group) { + return group + .getChildStops() + .stream() + .flatMap(sl -> agenciesForStopLocation(sl).stream()) + .distinct() + .toList(); + } + private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { return new StopCluster.Coordinate(c.latitude(), c.longitude()); } diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index f38499bfd68..0d08bcf34b2 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -572,21 +572,6 @@ public List getModesOfStopLocation(StopLocation stop) { return sortByOccurrenceAndReduce(getPatternModesOfStop(stop)).toList(); } - @Override - public List getAgenciesForStopLocation(StopLocation stop) { - return getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); - } - - @Override - public List getAgenciesForStopLocationsGroup(StopLocationsGroup group) { - return group - .getChildStops() - .stream() - .flatMap(sl -> getAgenciesForStopLocation(sl).stream()) - .distinct() - .toList(); - } - /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index 156a3c8dd1a..d0664aa292d 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -215,16 +215,4 @@ List stopTimesForPatternAtStop( * So, if more patterns of mode BUS than RAIL visit the stop, the result will be [BUS,RAIL]. */ List getModesOfStopLocation(StopLocation stop); - - /** - * Iterates over all child stops, the routes that visit this stop and return a de-duplicated list - * of their agencies. - */ - List getAgenciesForStopLocationsGroup(StopLocationsGroup group); - - /** - * Iterates over all routes that visit this stop location and return a de-duplicated list - * of their agencies. - */ - List getAgenciesForStopLocation(StopLocation stop); } diff --git a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java index ab3d5c8ae0a..f04fe782a0a 100644 --- a/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java +++ b/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java @@ -76,11 +76,4 @@ void stationModes() { var modes = service.getModesOfStopLocationsGroup(STATION); assertEquals(List.of(RAIL, FERRY, TRAM), modes); } - - @Test - void stopAgencies() { - var stop = RAIL_PATTERN.getStopPattern().getStop(0); - var agencies = service.getAgenciesForStopLocation(stop); - assertEquals("[Agency{F:A1 Agency Test}]", agencies.toString()); - } } From eaaf758208c26902f79bce952d334036b4441a5b Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Mon, 5 Feb 2024 12:05:52 +0000 Subject: [PATCH 323/356] Add changelog entry for #5651 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 37c8d26053e..05731e6fbeb 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -87,6 +87,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Introduce `generalizedCostPlusPenalty` to make cost comparsion fairer [#5483](https://github.com/opentripplanner/OpenTripPlanner/pull/5483) - Separate walk time from non-transit time [#5648](https://github.com/opentripplanner/OpenTripPlanner/pull/5648) - Remove "fare" [#5645](https://github.com/opentripplanner/OpenTripPlanner/pull/5645) +- Refactor GroupStopBuilder addLocation method [#5651](https://github.com/opentripplanner/OpenTripPlanner/pull/5651) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 190f745d089da47672814a01c10834085a0e49f7 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Mon, 5 Feb 2024 12:06:13 +0000 Subject: [PATCH 324/356] Bump serialization version id for #5651 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c0b2ca4292a..be1e49f2a16 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 142 + 143 30.2 2.50 From 4f5c5900a652c5e1e8851f234bd070940bcaeb46 Mon Sep 17 00:00:00 2001 From: eibakke Date: Mon, 5 Feb 2024 14:21:45 +0100 Subject: [PATCH 325/356] Fixes a few typos and improves documentation in the TransitService interface. --- .../parkAndRideApi/ParkAndRideResource.java | 2 +- .../ext/restapi/resources/IndexAPI.java | 4 ++-- .../layers/stops/StopsLayerBuilder.java | 2 +- .../apis/gtfs/datafetchers/QueryTypeImpl.java | 3 +-- .../transmodel/TransmodelGraphQLSchema.java | 2 +- .../transmodel/model/stop/StopPlaceType.java | 2 +- .../GraphInspectorVectorTileResource.java | 2 +- .../graph_builder/module/NearbyStopFinder.java | 2 +- .../routing/linking/FlexLocationAdder.java | 2 +- .../api/OtpServerRequestContext.java | 2 +- .../transit/service/DefaultTransitService.java | 4 ++-- .../transit/service/StopModel.java | 18 +++++++++++++++--- .../transit/service/TransitService.java | 2 +- .../gtfs/mapping/RouteRequestMapperTest.java | 2 +- 14 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java b/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java index 02dfc1bef5d..4a577433bfe 100644 --- a/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java +++ b/src/ext/java/org/opentripplanner/ext/parkAndRideApi/ParkAndRideResource.java @@ -42,7 +42,7 @@ public ParkAndRideResource( // - serverContext.graphFinder(). This needs at least a comment! // - This can be replaced with a search done with the StopModel // - if we have a radius search there. - this.graphFinder = new DirectGraphFinder(serverContext.transitService()::findRegularStop); + this.graphFinder = new DirectGraphFinder(serverContext.transitService()::findRegularStops); } /** Envelopes are in latitude, longitude format */ diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java index 5bdda8a57a2..cab2be13ad0 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/IndexAPI.java @@ -200,7 +200,7 @@ public List getStopsInRadius( radius = Math.min(radius, MAX_STOP_SEARCH_RADIUS); - return new DirectGraphFinder(serverContext.transitService()::findRegularStop) + return new DirectGraphFinder(serverContext.transitService()::findRegularStops) .findClosestStops(new Coordinate(lon, lat), radius) .stream() .map(it -> StopMapper.mapToApiShort(it.stop, it.distance)) @@ -221,7 +221,7 @@ public List getStopsInRadius( new Coordinate(maxLon, maxLat) ); - var stops = transitService().findRegularStop(envelope); + var stops = transitService().findRegularStops(envelope); return stops .stream() .filter(stop -> envelope.contains(stop.getCoordinate().asJtsCoordinate())) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index 6d15816669e..2ad85587fe5 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -37,7 +37,7 @@ public StopsLayerBuilder( protected List getGeometries(Envelope query) { return transitService - .findRegularStop(query) + .findRegularStops(query) .stream() .map(stop -> { Geometry point = stop.getGeometry(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index d749987384c..a4f5cb00e2f 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.locationtech.jts.geom.Coordinate; @@ -710,7 +709,7 @@ public DataFetcher> stopsByBbox() { ); Stream stopStream = getTransitService(environment) - .findRegularStop(envelope) + .findRegularStops(envelope) .stream() .filter(stop -> envelope.contains(stop.getCoordinate().asJtsCoordinate())); diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java index 00bf98c703f..638d7783e9a 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java @@ -687,7 +687,7 @@ private GraphQLSchema create() { ); return GqlUtil .getTransitService(environment) - .findRegularStop(envelope) + .findRegularStops(envelope) .stream() .filter(stop -> envelope.contains(stop.getCoordinate().asJtsCoordinate())) .filter(stop -> diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java index accaf1e35fb..d178e5125b5 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/stop/StopPlaceType.java @@ -531,7 +531,7 @@ public static Collection fetchStopPlaces( ); Stream stations = transitService - .findRegularStop(envelope) + .findRegularStops(envelope) .stream() .filter(stop -> envelope.contains(stop.getCoordinate().asJtsCoordinate())) .map(StopLocation::getParentStation) diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index 03f4357e540..dc6ba627e0e 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -179,7 +179,7 @@ private static LayerBuilder createLayerBuilder( case RegularStop -> new StopLayerBuilder<>( layerParameters, locale, - e -> context.transitService().findRegularStop(e) + e -> context.transitService().findRegularStops(e) ); case AreaStop -> new StopLayerBuilder<>( layerParameters, diff --git a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java index 360cdaee363..1fbfffcec5f 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/NearbyStopFinder.java @@ -85,7 +85,7 @@ public NearbyStopFinder( // We need to accommodate straight line distance (in meters) but when streets are present we // use an earliest arrival search, which optimizes on time. Ideally we'd specify in meters, // but we don't have much of a choice here. Use the default walking speed to convert. - this.directGraphFinder = new DirectGraphFinder(transitService::findRegularStop); + this.directGraphFinder = new DirectGraphFinder(transitService::findRegularStops); } } diff --git a/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java b/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java index 830a80c39a5..047e44f229a 100644 --- a/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java +++ b/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java @@ -16,7 +16,7 @@ static void addFlexLocations(StreetEdge edge, IntersectionVertex v0, StopModel s if (edge.getPermission().allows(StreetTraversalPermission.PEDESTRIAN_AND_CAR)) { Point p = GeometryUtils.getGeometryFactory().createPoint(v0.getCoordinate()); Envelope env = p.getEnvelopeInternal(); - for (AreaStop areaStop : stopModel.queryLocationIndex(env)) { + for (AreaStop areaStop : stopModel.findAreaStops(env)) { if (!areaStop.getGeometry().disjoint(p)) { v0.addAreaStops(Set.of(areaStop)); } diff --git a/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java b/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java index fa3a7069e2d..bbc6733a40c 100644 --- a/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java +++ b/src/main/java/org/opentripplanner/standalone/api/OtpServerRequestContext.java @@ -114,7 +114,7 @@ public interface OtpServerRequestContext { TraverseVisitor traverseVisitor(); default GraphFinder graphFinder() { - return GraphFinder.getInstance(graph(), transitService()::findRegularStop); + return GraphFinder.getInstance(graph(), transitService()::findRegularStops); } FlexConfig flexConfig(); diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 0d08bcf34b2..3050fca6a3d 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -543,7 +543,7 @@ public ZonedDateTime getTransitServiceStarts() { } @Override - public Collection findRegularStop(Envelope envelope) { + public Collection findRegularStops(Envelope envelope) { OTPRequestTimeoutException.checkForTimeout(); return transitModel.getStopModel().findRegularStops(envelope); } @@ -551,7 +551,7 @@ public Collection findRegularStop(Envelope envelope) { @Override public Collection findAreaStops(Envelope envelope) { OTPRequestTimeoutException.checkForTimeout(); - return transitModel.getStopModel().queryLocationIndex(envelope); + return transitModel.getStopModel().findAreaStops(envelope); } @Override diff --git a/src/main/java/org/opentripplanner/transit/service/StopModel.java b/src/main/java/org/opentripplanner/transit/service/StopModel.java index dd6b65e5b33..763aa504c40 100644 --- a/src/main/java/org/opentripplanner/transit/service/StopModel.java +++ b/src/main/java/org/opentripplanner/transit/service/StopModel.java @@ -108,7 +108,7 @@ public StopModelBuilder withContext() { } /** - * Return a regular transit stop if found(not flex stops). + * Return a regular transit stop if found (not flex stops). */ public RegularStop getRegularStop(FeedScopedId id) { return regularStopById.get(id); @@ -121,6 +121,9 @@ public Collection listRegularStops() { return regularStopById.values(); } + /** + * Find regular stops within a geographical area. + */ public Collection findRegularStops(Envelope envelope) { return index.findRegularStops(envelope); } @@ -131,21 +134,30 @@ public boolean hasAreaStops() { /** * Flex locations are generated by GTFS graph builder, but consumed only after the street graph is - * built + * built. */ @Nullable public AreaStop getAreaStop(FeedScopedId id) { return areaStopById.get(id); } + /** + * Return all flex stops, not regular transit stops and flex group of stops. + */ public Collection listAreaStops() { return areaStopById.values(); } - public Collection queryLocationIndex(Envelope envelope) { + /** + * Find flex stops within a geographical area. + */ + public Collection findAreaStops(Envelope envelope) { return index.findAreaStops(envelope); } + /** + * Return all flex groups of stops. + */ public Collection listGroupStops() { return groupStopById.values(); } diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index d0664aa292d..fdb6dda8749 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -187,7 +187,7 @@ List stopTimesForPatternAtStop( boolean transitFeedCovers(Instant dateTime); - Collection findRegularStop(Envelope envelope); + Collection findRegularStops(Envelope envelope); Collection findAreaStops(Envelope envelope); diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java index b05dd77e2a9..85736291ada 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java @@ -55,7 +55,7 @@ class RouteRequestMapperTest implements PlanTestConstants { graph.getVehicleParkingService(), new DefaultVehicleRentalService(), new DefaultRealtimeVehicleService(transitService), - GraphFinder.getInstance(graph, transitService::findRegularStop), + GraphFinder.getInstance(graph, transitService::findRegularStops), new RouteRequest() ); } From 8a7bbc08f603a961511ec5c8a255a80927fb45c3 Mon Sep 17 00:00:00 2001 From: eibakke Date: Mon, 5 Feb 2024 14:36:26 +0100 Subject: [PATCH 326/356] Changes the GroupStop's getEncompassingAreaGeometry method to return an empty optional if the group stop is not defined as an area. This was an oversight earlier. --- .../org/opentripplanner/transit/model/site/GroupStop.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java index edee00e27e1..c674d588238 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupStop.java @@ -94,13 +94,12 @@ public Geometry getGeometry() { /** * Returns the geometry of the area that encompasses the bounds of this StopLocation group. If the - * group is defined only as a list of stops, this will return the same as getGeometry. If on the - * other hand the group is defined as an area and the stops are inferred from that area, then this - * will return the geometry of the area. + * group is defined as all the stops within an area, then this will return the geometry of the + * area. If the group is defined simply as a list of stops, this will return an empty optional. */ @Override public Optional getEncompassingAreaGeometry() { - return Optional.ofNullable(encompassingAreaGeometry).or(() -> Optional.of(geometry)); + return Optional.ofNullable(encompassingAreaGeometry); } @Override From 645d3244f51416b217aa6d13ddeb558c0c20a7d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:10:26 +0000 Subject: [PATCH 327/356] Update junit5 monorepo to v5.10.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be1e49f2a16..32b977f0efd 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ 2.50 2.16.1 3.1.5 - 5.10.1 + 5.10.2 1.12.1 5.5.3 1.4.14 From 7705301832a0edd3a62930096eaf43a22a5907f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:10:20 +0000 Subject: [PATCH 328/356] Update dependency org.slf4j:jul-to-slf4j to v2.0.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32b977f0efd..5476adbe49c 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ 5.5.3 1.4.14 9.9.1 - 2.0.11 + 2.0.12 2.0.15 1.26 4.0.4 From 31cb93ca668022bbb65b3dcf7f9f2983c6ab9ba6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 03:28:59 +0000 Subject: [PATCH 329/356] Update dependency org.mockito:mockito-core to v5.10.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5476adbe49c..67595a4ec1e 100644 --- a/pom.xml +++ b/pom.xml @@ -713,7 +713,7 @@ org.mockito mockito-core - 5.9.0 + 5.10.0 test From 22dad32bea0ad075fbdf17d02a083d19bf5b4090 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Tue, 6 Feb 2024 09:25:34 +0000 Subject: [PATCH 330/356] Bump serialization version id for #5650 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 67595a4ec1e..844fc4e7f97 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 143 + 144 30.2 2.50 From 3ddaf01525fc2ad22439dceb2732433248265247 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 6 Feb 2024 16:55:38 +0200 Subject: [PATCH 331/356] Refactor SteetMode --- .../routing/api/request/RequestModes.java | 10 +- .../routing/api/request/StreetMode.java | 124 ++++++++++-------- 2 files changed, 71 insertions(+), 63 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java b/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java index 5253bb2018d..72b06f62979 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java +++ b/src/main/java/org/opentripplanner/routing/api/request/RequestModes.java @@ -2,12 +2,9 @@ import static org.opentripplanner.routing.api.request.StreetMode.NOT_SET; -import java.util.Collection; -import java.util.List; import java.util.Objects; import javax.annotation.Nonnull; import org.opentripplanner.framework.tostring.ToStringBuilder; -import org.opentripplanner.transit.model.basic.MainAndSubMode; public class RequestModes { @@ -39,10 +36,11 @@ private RequestModes( StreetMode directMode, StreetMode transferMode ) { - this.accessMode = (accessMode != null && accessMode.access) ? accessMode : NOT_SET; - this.egressMode = (egressMode != null && egressMode.egress) ? egressMode : NOT_SET; + this.accessMode = (accessMode != null && accessMode.accessAllowed()) ? accessMode : NOT_SET; + this.egressMode = (egressMode != null && egressMode.egressAllowed()) ? egressMode : NOT_SET; this.directMode = directMode != null ? directMode : NOT_SET; - this.transferMode = (transferMode != null && transferMode.transfer) ? transferMode : NOT_SET; + this.transferMode = + (transferMode != null && transferMode.transferAllowed()) ? transferMode : NOT_SET; } public RequestModes(RequestModesBuilder builder) { diff --git a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java b/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java index bb5dc4b7f04..041a6fbb247 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java +++ b/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java @@ -1,5 +1,7 @@ package org.opentripplanner.routing.api.request; +import java.util.EnumSet; +import java.util.Set; import org.opentripplanner.framework.doc.DocumentedEnum; public enum StreetMode implements DocumentedEnum { @@ -7,134 +9,142 @@ public enum StreetMode implements DocumentedEnum { * No street mode is set. This option is used if we do not want street routing at all in this part * of the search. */ - NOT_SET(true, true, true, false, false, false, false, false, false, false), + NOT_SET(Feature.ACCESS, Feature.TRANSFER, Feature.EGRESS), /** * Walk only */ - WALK(true, true, true, true, false, false, false, false, false, false), + WALK(Feature.ACCESS, Feature.TRANSFER, Feature.EGRESS, Feature.WALKING), /** * Bike only */ - BIKE(true, true, true, false, true, false, false, false, false, false), + BIKE(Feature.ACCESS, Feature.TRANSFER, Feature.EGRESS, Feature.CYCLING), /** * Bike to a bike parking area, then walk the rest of the way. *

      * Direct mode and access mode only. */ - BIKE_TO_PARK(true, false, false, true, true, false, false, false, true, false), + BIKE_TO_PARK(Feature.ACCESS, Feature.WALKING, Feature.CYCLING, Feature.PARKING), /** * Walk to a bike rental point, bike to a bike rental drop-off point, and walk the rest of the * way. This can include bike rental at fixed locations or free-floating services. */ - BIKE_RENTAL(true, true, true, true, true, false, false, true, false, false), + BIKE_RENTAL( + Feature.ACCESS, + Feature.TRANSFER, + Feature.EGRESS, + Feature.WALKING, + Feature.CYCLING, + Feature.RENTING + ), /** * Walk to a scooter rental point, ride a scooter to a scooter rental drop-off point, and walk the * rest of the way. This can include scooter rental at fixed locations or free-floating services. */ - SCOOTER_RENTAL(true, true, true, true, false, false, true, true, false, false), + SCOOTER_RENTAL( + Feature.ACCESS, + Feature.TRANSFER, + Feature.EGRESS, + Feature.WALKING, + Feature.SCOOTER, + Feature.RENTING + ), /** * Car only *

      * Direct mode only. */ - CAR(true, false, false, false, false, true, false, false, false, false), + CAR(Feature.ACCESS, Feature.DRIVING), /** * Start in the car, drive to a parking area, and walk the rest of the way. *

      * Direct mode and access mode only. */ - CAR_TO_PARK(true, false, false, true, false, true, false, false, true, false), + CAR_TO_PARK(Feature.ACCESS, Feature.WALKING, Feature.DRIVING, Feature.PARKING), /** * Walk to a pickup point along the road, drive to a drop-off point along the road, and walk the * rest of the way. This can include various taxi-services or kiss & ride. */ - CAR_PICKUP(true, false, true, true, false, true, false, false, false, true), + CAR_PICKUP(Feature.ACCESS, Feature.EGRESS, Feature.WALKING, Feature.DRIVING, Feature.PICKUP), /** * Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. * This can include car rental at fixed locations or free-floating services. */ - CAR_RENTAL(true, true, true, true, false, true, false, true, false, false), + CAR_RENTAL( + Feature.ACCESS, + Feature.TRANSFER, + Feature.EGRESS, + Feature.WALKING, + Feature.DRIVING, + Feature.RENTING + ), /** * Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination. */ - CAR_HAILING(true, false, true, false, false, true, false, false, false, true), + CAR_HAILING(Feature.ACCESS, Feature.EGRESS, Feature.DRIVING, Feature.PICKUP), /** * Encompasses all types of on-demand and flexible transportation. */ - FLEXIBLE(true, false, true, true, false, false, false, false, false, false); - - final boolean access; - - final boolean transfer; - - final boolean egress; - - final boolean includesWalking; - - final boolean includesBiking; - - final boolean includesDriving; + FLEXIBLE(Feature.ACCESS, Feature.EGRESS, Feature.WALKING); + + private enum Feature { + ACCESS, + EGRESS, + TRANSFER, + WALKING, + CYCLING, + DRIVING, + SCOOTER, + RENTING, + PARKING, + PICKUP, + } - final boolean includesScooter; + private final Set features; - final boolean includesRenting; + StreetMode(Feature first, Feature... rest) { + this.features = EnumSet.of(first, rest); + } - final boolean includesParking; + public boolean accessAllowed() { + return features.contains(Feature.ACCESS); + } - final boolean includesPickup; + public boolean transferAllowed() { + return features.contains(Feature.TRANSFER); + } - StreetMode( - boolean access, - boolean transfer, - boolean egress, - boolean includesWalking, - boolean includesBiking, - boolean includesDriving, - boolean includesScooter, - boolean includesRenting, - boolean includesParking, - boolean includesPickup - ) { - this.access = access; - this.transfer = transfer; - this.egress = egress; - this.includesWalking = includesWalking; - this.includesBiking = includesBiking; - this.includesDriving = includesDriving; - this.includesScooter = includesScooter; - this.includesRenting = includesRenting; - this.includesParking = includesParking; - this.includesPickup = includesPickup; + public boolean egressAllowed() { + return features.contains(Feature.EGRESS); } public boolean includesWalking() { - return includesWalking; + return features.contains(Feature.WALKING); } public boolean includesBiking() { - return includesBiking; + return features.contains(Feature.CYCLING); } public boolean includesDriving() { - return includesDriving; + return features.contains(Feature.DRIVING); } public boolean includesScooter() { - return includesScooter; + return features.contains(Feature.SCOOTER); } public boolean includesRenting() { - return includesRenting; + return features.contains(Feature.RENTING); } public boolean includesParking() { - return includesParking; + return features.contains(Feature.PARKING); } public boolean includesPickup() { - return includesPickup; + return features.contains(Feature.PICKUP); } @Override From aa32eb753952153d4b0fc0f073487f20fc7965f1 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 6 Feb 2024 17:32:47 +0200 Subject: [PATCH 332/356] Remove transfer from rental modes as it's not possible --- .../routing/api/request/StreetMode.java | 27 +++---------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java b/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java index 041a6fbb247..47073aa7eeb 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java +++ b/src/main/java/org/opentripplanner/routing/api/request/StreetMode.java @@ -28,26 +28,12 @@ public enum StreetMode implements DocumentedEnum { * Walk to a bike rental point, bike to a bike rental drop-off point, and walk the rest of the * way. This can include bike rental at fixed locations or free-floating services. */ - BIKE_RENTAL( - Feature.ACCESS, - Feature.TRANSFER, - Feature.EGRESS, - Feature.WALKING, - Feature.CYCLING, - Feature.RENTING - ), + BIKE_RENTAL(Feature.ACCESS, Feature.EGRESS, Feature.WALKING, Feature.CYCLING, Feature.RENTING), /** * Walk to a scooter rental point, ride a scooter to a scooter rental drop-off point, and walk the * rest of the way. This can include scooter rental at fixed locations or free-floating services. */ - SCOOTER_RENTAL( - Feature.ACCESS, - Feature.TRANSFER, - Feature.EGRESS, - Feature.WALKING, - Feature.SCOOTER, - Feature.RENTING - ), + SCOOTER_RENTAL(Feature.ACCESS, Feature.EGRESS, Feature.WALKING, Feature.SCOOTER, Feature.RENTING), /** * Car only *

      @@ -69,14 +55,7 @@ public enum StreetMode implements DocumentedEnum { * Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. * This can include car rental at fixed locations or free-floating services. */ - CAR_RENTAL( - Feature.ACCESS, - Feature.TRANSFER, - Feature.EGRESS, - Feature.WALKING, - Feature.DRIVING, - Feature.RENTING - ), + CAR_RENTAL(Feature.ACCESS, Feature.EGRESS, Feature.WALKING, Feature.DRIVING, Feature.RENTING), /** * Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination. From 5184fa0ddedb36c8796f000158c64eed0e66e314 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 00:55:02 +0000 Subject: [PATCH 333/356] Update graphqlcodegenerator monorepo to v5.0.2 --- .../apis/gtfs/generated/package.json | 4 +- .../apis/gtfs/generated/yarn.lock | 172 ++++++++++++++---- 2 files changed, 141 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json b/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json index 6a2eb3343b9..db865eaa003 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/package.json @@ -10,8 +10,8 @@ }, "license": "LGPL-3.0", "dependencies": { - "@graphql-codegen/add": "5.0.0", - "@graphql-codegen/cli": "5.0.0", + "@graphql-codegen/add": "5.0.2", + "@graphql-codegen/cli": "5.0.2", "@graphql-codegen/java": "4.0.0", "@graphql-codegen/java-resolvers": "3.0.0", "graphql": "16.8.1" diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock b/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock index 7e3c815cfb1..fffe602db18 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/yarn.lock @@ -264,7 +264,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-plugin-utils@^7.22.5": +"@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== @@ -699,24 +699,25 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@graphql-codegen/add@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.0.tgz#578ebaf4fa87c1e934c381cd679bcedcf79feaba" - integrity sha512-ynWDOsK2yxtFHwcJTB9shoSkUd7YXd6ZE57f0nk7W5cu/nAgxZZpEsnTPEpZB/Mjf14YRGe2uJHQ7AfElHjqUQ== +"@graphql-codegen/add@5.0.2", "@graphql-codegen/add@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.2.tgz#71b3ae0465a4537172dddb84531b6967ca5545f2" + integrity sha512-ouBkSvMFUhda5VoKumo/ZvsZM9P5ZTyDsI8LW18VxSNWOjrTeLXBWHG8Gfaai0HwhflPtCYVABbriEcOmrRShQ== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.0" - tslib "~2.5.0" + "@graphql-codegen/plugin-helpers" "^5.0.3" + tslib "~2.6.0" -"@graphql-codegen/cli@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-5.0.0.tgz#761dcf08cfee88bbdd9cdf8097b2343445ec6f0a" - integrity sha512-A7J7+be/a6e+/ul2KI5sfJlpoqeqwX8EzktaKCeduyVKgOLA6W5t+NUGf6QumBDXU8PEOqXk3o3F+RAwCWOiqA== +"@graphql-codegen/cli@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-5.0.2.tgz#07ff691c16da4c3dcc0e1995d3231530379ab317" + integrity sha512-MBIaFqDiLKuO4ojN6xxG9/xL9wmfD3ZjZ7RsPjwQnSHBCUXnEkdKvX+JVpx87Pq29Ycn8wTJUguXnTZ7Di0Mlw== dependencies: "@babel/generator" "^7.18.13" "@babel/template" "^7.18.10" "@babel/types" "^7.18.13" - "@graphql-codegen/core" "^4.0.0" - "@graphql-codegen/plugin-helpers" "^5.0.1" + "@graphql-codegen/client-preset" "^4.2.2" + "@graphql-codegen/core" "^4.0.2" + "@graphql-codegen/plugin-helpers" "^5.0.3" "@graphql-tools/apollo-engine-loader" "^8.0.0" "@graphql-tools/code-file-loader" "^8.0.0" "@graphql-tools/git-loader" "^8.0.0" @@ -747,15 +748,45 @@ yaml "^2.3.1" yargs "^17.0.0" -"@graphql-codegen/core@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-4.0.0.tgz#b29c911746a532a675e33720acb4eb2119823e01" - integrity sha512-JAGRn49lEtSsZVxeIlFVIRxts2lWObR+OQo7V2LHDJ7ohYYw3ilv7nJ8pf8P4GTg/w6ptcYdSdVVdkI8kUHB/Q== +"@graphql-codegen/client-preset@^4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/client-preset/-/client-preset-4.2.2.tgz#545c62789a5687bee5df8b4738b4911e72ea8051" + integrity sha512-DF9pNWj3TEdA90E9FH5SsUIqiZfr872vqaQOspLVuVXGsaDx8F/JLLzaN+7ucmoo0ff/bLW8munVXYXTmgwwEA== dependencies: - "@graphql-codegen/plugin-helpers" "^5.0.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/template" "^7.20.7" + "@graphql-codegen/add" "^5.0.2" + "@graphql-codegen/gql-tag-operations" "4.0.4" + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/typed-document-node" "^5.0.4" + "@graphql-codegen/typescript" "^4.0.4" + "@graphql-codegen/typescript-operations" "^4.1.2" + "@graphql-codegen/visitor-plugin-common" "^4.1.2" + "@graphql-tools/documents" "^1.0.0" + "@graphql-tools/utils" "^10.0.0" + "@graphql-typed-document-node/core" "3.2.0" + tslib "~2.6.0" + +"@graphql-codegen/core@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-4.0.2.tgz#7e6ec266276f54bbf02f60599d9e518f4a59d85e" + integrity sha512-IZbpkhwVqgizcjNiaVzNAzm/xbWT6YnGgeOLwVjm4KbJn3V2jchVtuzHH09G5/WkkLSk2wgbXNdwjM41JxO6Eg== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" "@graphql-tools/schema" "^10.0.0" "@graphql-tools/utils" "^10.0.0" - tslib "~2.5.0" + tslib "~2.6.0" + +"@graphql-codegen/gql-tag-operations@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.4.tgz#572be5db804af5efdc3ca24e4bcac815448730c5" + integrity sha512-dypul0iDLjb07yv+/cRb6qPbn42cFPcwlsJertVl9G6qkS4+3V4806WwSfUht4QVMWnvGfgDkJJqG0yUVKOHwA== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/visitor-plugin-common" "4.1.2" + "@graphql-tools/utils" "^10.0.0" + auto-bind "~4.0.0" + tslib "~2.6.0" "@graphql-codegen/java-common@^3.0.0": version "3.0.0" @@ -813,29 +844,59 @@ lodash "~4.17.0" tslib "~2.4.0" -"@graphql-codegen/plugin-helpers@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.0.tgz#40c18217454af5cf8317e5f46cf4d38e8cc78ae4" - integrity sha512-suL2ZMkBAU2a4YbBHaZvUPsV1z0q3cW6S96Z/eYYfkRIsJoe2vN+wNZ9Xdzmqx0JLmeeFCBSoBGC0imFyXlkDQ== +"@graphql-codegen/plugin-helpers@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.3.tgz#7027b9d911d7cb594663590fcf5d63e9cf7ec2ff" + integrity sha512-yZ1rpULIWKBZqCDlvGIJRSyj1B2utkEdGmXZTBT/GVayP4hyRYlkd36AJV/LfEsVD8dnsKL5rLz2VTYmRNlJ5Q== dependencies: "@graphql-tools/utils" "^10.0.0" change-case-all "1.0.15" common-tags "1.8.2" import-from "4.0.0" lodash "~4.17.0" - tslib "~2.5.0" + tslib "~2.6.0" -"@graphql-codegen/plugin-helpers@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.1.tgz#e2429fcfba3f078d5aa18aa062d46c922bbb0d55" - integrity sha512-6L5sb9D8wptZhnhLLBcheSPU7Tg//DGWgc5tQBWX46KYTOTQHGqDpv50FxAJJOyFVJrveN9otWk9UT9/yfY4ww== +"@graphql-codegen/schema-ast@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-4.0.2.tgz#aeaa104e4555cca73a058f0a9350b4b0e290b377" + integrity sha512-5mVAOQQK3Oz7EtMl/l3vOQdc2aYClUzVDHHkMvZlunc+KlGgl81j8TLa+X7ANIllqU4fUEsQU3lJmk4hXP6K7Q== dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" "@graphql-tools/utils" "^10.0.0" + tslib "~2.6.0" + +"@graphql-codegen/typed-document-node@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.4.tgz#06e286caacdd66c3566f98433dcb8f1a9c9a9f1d" + integrity sha512-t66Z6erQ4Dh1j6f9pRZmc8uYtHoUI3A49tLmJAlg9/3IV0kCmwrWKJut/G8SeOefDLG8cXBTVtI/YuZOe1Te+w== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/visitor-plugin-common" "4.1.2" + auto-bind "~4.0.0" change-case-all "1.0.15" - common-tags "1.8.2" - import-from "4.0.0" - lodash "~4.17.0" - tslib "~2.5.0" + tslib "~2.6.0" + +"@graphql-codegen/typescript-operations@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-4.1.2.tgz#a0f455ae19e16961e5870420ca7515bbe51b5568" + integrity sha512-CtCWK+gW7hS+Ely3lohr8CL1HVLswQzMcaUk3k1sxdWCWKTNq7abMsWa31rTVwRCJ+WNEkM/7S8sIBTpEG683A== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/typescript" "^4.0.4" + "@graphql-codegen/visitor-plugin-common" "4.1.2" + auto-bind "~4.0.0" + tslib "~2.6.0" + +"@graphql-codegen/typescript@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-4.0.4.tgz#e791c61f675ae454951ea077b0ae519ae352cc3e" + integrity sha512-x79CKLfP9UQCX+/I78qxQlMs2Mmq3pF1lKafZo7lAno0f/fvJ+qWUduzdgjRNz+YL+5blGeWcC0pWEDxniO7hw== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/schema-ast" "^4.0.2" + "@graphql-codegen/visitor-plugin-common" "4.1.2" + auto-bind "~4.0.0" + tslib "~2.6.0" "@graphql-codegen/visitor-plugin-common@2.13.1": version "2.13.1" @@ -853,6 +914,22 @@ parse-filepath "^1.0.2" tslib "~2.4.0" +"@graphql-codegen/visitor-plugin-common@4.1.2", "@graphql-codegen/visitor-plugin-common@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-4.1.2.tgz#674c5d5813f6c00dd65e1ee148a62536879e65e2" + integrity sha512-yk7iEAL1kYZ2Gi/pvVjdsZhul5WsYEM4Zcgh2Ev15VicMdJmPHsMhNUsZWyVJV0CaQCYpNOFlGD/11Ea3pn4GA== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-tools/optimize" "^2.0.0" + "@graphql-tools/relay-operation-optimizer" "^7.0.0" + "@graphql-tools/utils" "^10.0.0" + auto-bind "~4.0.0" + change-case-all "1.0.15" + dependency-graph "^0.11.0" + graphql-tag "^2.11.0" + parse-filepath "^1.0.2" + tslib "~2.6.0" + "@graphql-tools/apollo-engine-loader@^8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-8.0.0.tgz#ac1f351cbe41508411784f25757f5557b0f27489" @@ -897,6 +974,14 @@ tslib "^2.5.0" value-or-promise "^1.0.12" +"@graphql-tools/documents@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/documents/-/documents-1.0.0.tgz#e3ed97197cc22ec830ca227fd7d17e86d8424bdf" + integrity sha512-rHGjX1vg/nZ2DKqRGfDPNC55CWZBMldEVcH+91BThRa6JeT80NqXknffLLEZLRUxyikCfkwMsk6xR3UNMqG0Rg== + dependencies: + lodash.sortby "^4.7.0" + tslib "^2.4.0" + "@graphql-tools/executor-graphql-ws@^1.0.0": version "1.0.2" resolved "https://registry.yarnpkg.com/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-1.0.2.tgz#29890f9370c5bebd4a2380e29904f8eaf9f013ca" @@ -1036,6 +1121,13 @@ dependencies: tslib "^2.4.0" +"@graphql-tools/optimize@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/optimize/-/optimize-2.0.0.tgz#7a9779d180824511248a50c5a241eff6e7a2d906" + integrity sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg== + dependencies: + tslib "^2.4.0" + "@graphql-tools/prisma-loader@^8.0.0": version "8.0.1" resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-8.0.1.tgz#0a013c69b04e0779b5be15757173d458cdf94e35" @@ -1069,6 +1161,15 @@ "@graphql-tools/utils" "9.1.1" tslib "^2.4.0" +"@graphql-tools/relay-operation-optimizer@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.0.tgz#24367666af87bc5a81748de5e8e9b3c523fd4207" + integrity sha512-UNlJi5y3JylhVWU4MBpL0Hun4Q7IoJwv9xYtmAz+CgRa066szzY7dcuPfxrA7cIGgG/Q6TVsKsYaiF4OHPs1Fw== + dependencies: + "@ardatan/relay-compiler" "12.0.0" + "@graphql-tools/utils" "^10.0.0" + tslib "^2.4.0" + "@graphql-tools/schema@^10.0.0": version "10.0.0" resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-10.0.0.tgz#7b5f6b6a59f51c927de8c9069bde4ebbfefc64b3" @@ -2374,6 +2475,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -3049,7 +3155,7 @@ ts-log@^2.2.3: resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.3.tgz#4da5640fe25a9fb52642cd32391c886721318efb" integrity sha512-XvB+OdKSJ708Dmf9ore4Uf/q62AYDTzFcAdxc8KNML1mmAWywRFVt/dn1KYJH8Agt5UJNujfM3znU5PxgAzA2w== -tslib@^2.0.0, tslib@^2.3.1, tslib@^2.4.1, tslib@~2.5.0: +tslib@^2.0.0, tslib@^2.3.1, tslib@^2.4.1: version "2.5.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== From 5904d2ee51aca36dca243de88b13de6237e9042b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 04:01:36 +0000 Subject: [PATCH 334/356] Update micrometer.version to v1.12.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 844fc4e7f97..aae99297d39 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 2.16.1 3.1.5 5.10.2 - 1.12.1 + 1.12.2 5.5.3 1.4.14 9.9.1 From 1d4f70f663ee4043cb2ebc1235c25bce3f5f6255 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 06:42:15 +0000 Subject: [PATCH 335/356] Update dependency com.google.cloud:libraries-bom to v26.31.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 844fc4e7f97..db06b8eb6dc 100644 --- a/pom.xml +++ b/pom.xml @@ -545,7 +545,7 @@ com.google.cloud libraries-bom - 26.27.0 + 26.31.0 pom import From 46b00abf9028152c9c82914aaeeec0a7998c8240 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Wed, 7 Feb 2024 09:06:02 +0000 Subject: [PATCH 336/356] Add changelog entry for #5381 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 05731e6fbeb..df2ecd4b8fc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -88,6 +88,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Separate walk time from non-transit time [#5648](https://github.com/opentripplanner/OpenTripPlanner/pull/5648) - Remove "fare" [#5645](https://github.com/opentripplanner/OpenTripPlanner/pull/5645) - Refactor GroupStopBuilder addLocation method [#5651](https://github.com/opentripplanner/OpenTripPlanner/pull/5651) +- Remove `VehicleToStopHeuristics` [#5381](https://github.com/opentripplanner/OpenTripPlanner/pull/5381) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 7692ef10fa9d8a5d51b371c7585ecbb9df4a4f2d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 7 Feb 2024 12:25:44 +0100 Subject: [PATCH 337/356] Apply review feedback --- .../DecorateConsolidatedStopNames.java | 34 ++++++++++++++----- .../DefaultStopConsolidationService.java | 4 +-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java index 2a09bb64255..a287e6a7d66 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/DecorateConsolidatedStopNames.java @@ -7,9 +7,9 @@ import org.opentripplanner.routing.algorithm.filterchain.framework.spi.ItineraryDecorator; /** - * A decorating filter that checks if a transit leg contains any primary stops and if it does, - * then replaces it with the secondary, agency-specific stop name. This is so that the in-vehicle - * display matches what OTP returns as a board/alight stop name. + * A decorating filter that checks if a transit leg contains any consolidated stops and if it does, + * then replaces it with the appropriate, agency-specific stop name. This is so that the physical + * signage and in-vehicle display matches what OTP returns as a board/alight stop name. */ public class DecorateConsolidatedStopNames implements ItineraryDecorator { @@ -21,20 +21,28 @@ public DecorateConsolidatedStopNames(StopConsolidationService service) { @Override public void decorate(Itinerary itinerary) { - replacePrimaryNamesWithSecondary(itinerary); + replaceConsolidatedStops(itinerary); } /** - * If the itinerary has a from/to that is the primary stop of a {@link org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup} - * then we replace its name with the secondary name of the agency that is - * operating the route, so that the name in the result matches the name in the in-vehicle - * display. + * If the itinerary has a "from" stop that is the secondary stop of a + * {@link org.opentripplanner.ext.stopconsolidation.model.ConsolidatedStopGroup} + * then we replace its name with the primary name of the agency that is + * operating the route, so that the name in the result matches the physical signage on the stop. + *

      + * If the leg has a "to" stop that is a primary stop, then we don't want to show the stop that's on + * the signage but what is shown _inside_ the vehicle. That's why we use the agency-specific (aka + * secondary) stop. + *

      + * This follows the somewhat idiosyncratic logic of the consolidated stops feature. */ - private void replacePrimaryNamesWithSecondary(Itinerary i) { + private void replaceConsolidatedStops(Itinerary i) { i.transformTransitLegs(leg -> { if (leg instanceof ScheduledTransitLeg stl && needsToRenameStops(stl)) { var agency = leg.getAgency(); + // to show the name on the stop signage we use the primary stop's name var from = service.primaryStop(stl.getFrom().stop.getId()); + // to show the name that's on the display inside the vehicle we use the agency-specific name var to = service.agencySpecificStop(stl.getTo().stop, agency); return new ConsolidatedStopLeg(stl, from, to); } else { @@ -43,6 +51,14 @@ private void replacePrimaryNamesWithSecondary(Itinerary i) { }); } + /** + * Figures out if the from/to stops are part of a consolidated stop group and therefore + * some stops need to be replaced. + *

      + * Please consult the Javadoc of {@link DecorateConsolidatedStopNames#replaceConsolidatedStops(Itinerary)} + * for details of this idiosyncratic business logic and in particular why the logic is not the same + * for the from/to stops. + */ private boolean needsToRenameStops(ScheduledTransitLeg stl) { return (service.isSecondaryStop(stl.getFrom().stop) || service.isPrimaryStop(stl.getTo().stop)); } diff --git a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java index 5011a848210..51a57028121 100644 --- a/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java +++ b/src/ext/java/org/opentripplanner/ext/stopconsolidation/internal/DefaultStopConsolidationService.java @@ -77,12 +77,12 @@ public StopLocation agencySpecificStop(StopLocation stop, Agency agency) { if (agency.getId().getFeedId().equals(stop.getId().getFeedId())) { return stop; } else { - return agencySpecificStopOpt(stop, agency).orElse(stop); + return findAgencySpecificStop(stop, agency).orElse(stop); } } @Nonnull - private Optional agencySpecificStopOpt(StopLocation stop, Agency agency) { + private Optional findAgencySpecificStop(StopLocation stop, Agency agency) { return repo .groups() .stream() From 056d7585fb86eebb6a6456e259fc9cf63885a646 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 7 Feb 2024 14:11:32 +0100 Subject: [PATCH 338/356] Allow configuring a custom attribution for vector tiles --- docs/sandbox/MapboxVectorTilesApi.md | 1 + .../ext/vectortiles/VectorTilesResource.java | 6 +++- .../apis/support/TileJson.java | 27 +++++++++++------ .../config/routerconfig/VectorTileConfig.java | 20 +++++++++++-- .../apis/support/TileJsonTest.java | 30 +++++++++++++++++++ 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index da9fd1120e1..8e4af296155 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -148,6 +148,7 @@ For each layer, the configuration includes: | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |----------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| +| attribution | `string` | Set a custom attribution to be returned in `tilejson.json` | *Optional* | | 2.5 | | [basePath](#vectorTiles_basePath) | `string` | The path of the vector tile source URLs in `tilejson.json`. | *Optional* | | 2.5 | | [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | |       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index 772db7394f3..b4e59dc49e5 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -101,7 +101,11 @@ public TileJson getTileJson( TileJson.urlWithDefaultPath(uri, headers, rLayers, ignoreRouterId, "vectorTiles") ); - return new TileJson(url, envelope, feedInfos); + return serverContext + .vectorTileConfig() + .attribution() + .map(attr -> new TileJson(url, envelope, attr)) + .orElseGet(() -> new TileJson(url, envelope, feedInfos)); } private static LayerBuilder crateLayerBuilder( diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index 75aabb2b6c6..72fe1ac3140 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -6,6 +6,7 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; +import javax.annotation.Nonnull; import org.apache.commons.lang3.StringUtils; import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.model.FeedInfo; @@ -36,15 +37,8 @@ public class TileJson implements Serializable { public final double[] bounds; public final double[] center; - public TileJson(String tileUrl, WorldEnvelope envelope, Collection feedInfos) { - attribution = - feedInfos - .stream() - .map(feedInfo -> - "" + feedInfo.getPublisherName() + "" - ) - .collect(Collectors.joining(", ")); - + public TileJson(String tileUrl, WorldEnvelope envelope, String attribution) { + this.attribution = attribution; tiles = new String[] { tileUrl }; bounds = @@ -59,6 +53,21 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee center = new double[] { c.longitude(), c.latitude(), 9 }; } + public TileJson(String tileUrl, WorldEnvelope envelope, Collection feedInfos) { + this(tileUrl, envelope, attributionFromFeedInfo(feedInfos)); + } + + @Nonnull + private static String attributionFromFeedInfo(Collection feedInfos) { + var attribution = feedInfos + .stream() + .map(feedInfo -> + "" + feedInfo.getPublisherName() + "" + ) + .collect(Collectors.joining(", ")); + return attribution; + } + /** * Creates a vector source layer URL from a hard-coded path plus information from the incoming * HTTP request. diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 6f7d6967ce8..4afc14a4ea7 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -18,18 +18,23 @@ public class VectorTileConfig implements VectorTilesResource.LayersParameters { - public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null); + public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null, null); private final List> layers; @Nullable private final String basePath; + @Nullable + private final String attribution; + VectorTileConfig( Collection> layers, - @Nullable String basePath + @Nullable String basePath, + @Nullable String attribution ) { this.layers = List.copyOf(layers); this.basePath = basePath; + this.attribution = attribution; } @Override @@ -41,6 +46,10 @@ public Optional basePath() { return Optional.ofNullable(basePath); } + public Optional attribution() { + return Optional.ofNullable(attribution); + } + public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String paramName) { var root = node.of(paramName).summary("Vector tile configuration").asObject(); return new VectorTileConfig( @@ -71,7 +80,12 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String is expected to be handled by a proxy. """ ) - .asString(DEFAULT.basePath) + .asString(DEFAULT.basePath), + root + .of("attribution") + .since(V2_5) + .summary("Set a custom attribution to be returned in `tilejson.json`") + .asString(DEFAULT.attribution) ); } diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index ac3b7bca522..f5f0401cf86 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -2,16 +2,24 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.time.LocalDate; import java.util.List; import org.glassfish.jersey.server.internal.routing.UriRoutingContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.service.worldenvelope.model.WorldEnvelope; import org.opentripplanner.test.support.HttpForTest; class TileJsonTest { private static final List LAYERS = List.of("stops", "rentalVehicles"); + private static final WorldEnvelope ENVELOPE = WorldEnvelope + .of() + .expandToIncludeStreetEntities(1, 1) + .expandToIncludeStreetEntities(2, 2) + .build(); @ParameterizedTest @ValueSource( @@ -40,4 +48,26 @@ void defaultPath() { TileJson.urlWithDefaultPath(uriInfo, req, LAYERS, "default", "vectorTiles") ); } + + @Test + void attributionFromFeedInfo() { + var feedInfo = new FeedInfo( + "1", + "Trimet", + "https://trimet.org", + "en", + LocalDate.MIN, + LocalDate.MIN, + "1" + ); + var tileJson = new TileJson("http://example.com", ENVELOPE, List.of(feedInfo)); + assertEquals("Trimet", tileJson.attribution); + } + + @Test + void attributionFromOverride() { + final String override = "OVERRIDE"; + var tileJson = new TileJson("http://example.com", ENVELOPE, override); + assertEquals(override, tileJson.attribution); + } } From c7e8e0d60e39b3cd44723f4809cfa2dae5c86fbe Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 7 Feb 2024 16:38:05 +0100 Subject: [PATCH 339/356] Refactor attribution handling --- .../ext/vectortiles/VectorTilesResource.java | 23 +++++++++------ .../apis/support/TileJson.java | 22 +++++++-------- .../apis/support/TileJsonTest.java | 28 +++++++++++-------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index b4e59dc49e5..a1e9a83c85a 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -28,6 +28,7 @@ import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.inspector.vector.VectorTileResponseFactory; +import org.opentripplanner.model.FeedInfo; import org.opentripplanner.standalone.api.OtpServerRequestContext; @Path("/routers/{ignoreRouterId}/vectorTiles") @@ -81,13 +82,6 @@ public TileJson getTileJson( @PathParam("layers") String requestedLayers ) { var envelope = serverContext.worldEnvelopeService().envelope().orElseThrow(); - var feedInfos = serverContext - .transitService() - .getFeedIds() - .stream() - .map(serverContext.transitService()::getFeedInfo) - .filter(Predicate.not(Objects::isNull)) - .toList(); List rLayers = Arrays.asList(requestedLayers.split(",")); @@ -105,7 +99,20 @@ public TileJson getTileJson( .vectorTileConfig() .attribution() .map(attr -> new TileJson(url, envelope, attr)) - .orElseGet(() -> new TileJson(url, envelope, feedInfos)); + .orElseGet(() -> { + var feedInfos = getFeedInfos(); + return new TileJson(url, envelope, feedInfos); + }); + } + + private List getFeedInfos() { + return serverContext + .transitService() + .getFeedIds() + .stream() + .map(serverContext.transitService()::getFeedInfo) + .filter(Predicate.not(Objects::isNull)) + .toList(); } private static LayerBuilder crateLayerBuilder( diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index 72fe1ac3140..fcd6e84cc06 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -6,7 +6,6 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.apache.commons.lang3.StringUtils; import org.opentripplanner.framework.io.HttpUtils; import org.opentripplanner.model.FeedInfo; @@ -57,17 +56,6 @@ public TileJson(String tileUrl, WorldEnvelope envelope, Collection fee this(tileUrl, envelope, attributionFromFeedInfo(feedInfos)); } - @Nonnull - private static String attributionFromFeedInfo(Collection feedInfos) { - var attribution = feedInfos - .stream() - .map(feedInfo -> - "" + feedInfo.getPublisherName() + "" - ) - .collect(Collectors.joining(", ")); - return attribution; - } - /** * Creates a vector source layer URL from a hard-coded path plus information from the incoming * HTTP request. @@ -105,4 +93,14 @@ public static String urlFromOverriddenBasePath( String.join(",", layers) ); } + + private static String attributionFromFeedInfo(Collection feedInfos) { + return feedInfos + .stream() + .map(feedInfo -> + "" + feedInfo.getPublisherName() + "" + ) + .distinct() + .collect(Collectors.joining(", ")); + } } diff --git a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java index f5f0401cf86..73c8cd1369e 100644 --- a/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java +++ b/src/test/java/org/opentripplanner/apis/support/TileJsonTest.java @@ -20,6 +20,15 @@ class TileJsonTest { .expandToIncludeStreetEntities(1, 1) .expandToIncludeStreetEntities(2, 2) .build(); + private static final FeedInfo FEED_INFO = new FeedInfo( + "1", + "Trimet", + "https://trimet.org", + "en", + LocalDate.MIN, + LocalDate.MIN, + "1" + ); @ParameterizedTest @ValueSource( @@ -51,22 +60,19 @@ void defaultPath() { @Test void attributionFromFeedInfo() { - var feedInfo = new FeedInfo( - "1", - "Trimet", - "https://trimet.org", - "en", - LocalDate.MIN, - LocalDate.MIN, - "1" - ); - var tileJson = new TileJson("http://example.com", ENVELOPE, List.of(feedInfo)); + var tileJson = new TileJson("http://example.com", ENVELOPE, List.of(FEED_INFO)); + assertEquals("Trimet", tileJson.attribution); + } + + @Test + void duplicateAttribution() { + var tileJson = new TileJson("http://example.com", ENVELOPE, List.of(FEED_INFO, FEED_INFO)); assertEquals("Trimet", tileJson.attribution); } @Test void attributionFromOverride() { - final String override = "OVERRIDE"; + var override = "OVERRIDE"; var tileJson = new TileJson("http://example.com", ENVELOPE, override); assertEquals(override, tileJson.attribution); } From db5eb9e915a0e463fd4593df7e111cea977a1e39 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 7 Feb 2024 16:48:43 +0100 Subject: [PATCH 340/356] Flesh out documentation --- docs/sandbox/MapboxVectorTilesApi.md | 17 ++++++++++++++++- .../config/routerconfig/VectorTileConfig.java | 12 +++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 8e4af296155..11bd195a9d8 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -148,7 +148,7 @@ For each layer, the configuration includes: | Config Parameter | Type | Summary | Req./Opt. | Default Value | Since | |----------------------------------------------------------------|:----------:|--------------------------------------------------------------------------------------------|:----------:|---------------|:-----:| -| attribution | `string` | Set a custom attribution to be returned in `tilejson.json` | *Optional* | | 2.5 | +| [attribution](#vectorTiles_attribution) | `string` | Custom attribution to be returned in `tilejson.json` | *Optional* | | 2.5 | | [basePath](#vectorTiles_basePath) | `string` | The path of the vector tile source URLs in `tilejson.json`. | *Optional* | | 2.5 | | [layers](#vectorTiles_layers) | `object[]` | Configuration of the individual layers for the Mapbox vector tiles. | *Optional* | | 2.0 | |       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | @@ -162,6 +162,21 @@ For each layer, the configuration includes: #### Details +

      attribution

      + +**Since version:** `2.5` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` +**Path:** /vectorTiles + +Custom attribution to be returned in `tilejson.json` + +By default the `attribution` property in `tilejson.json` is computed from the names and +URLs of the feed publishers. +If the OTP deployment contains many fields, this can become very unwieldy. + +This configuration parameter allows you to set the `attribution` to any string you wish, +for example `TriMet, C-Tran, SMART and Friends`. + +

      basePath

      **Since version:** `2.5` ∙ **Type:** `string` ∙ **Cardinality:** `Optional` diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 4afc14a4ea7..f0c6cb7d9b0 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -84,7 +84,17 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String root .of("attribution") .since(V2_5) - .summary("Set a custom attribution to be returned in `tilejson.json`") + .summary("Custom attribution to be returned in `tilejson.json`") + .description( + """ + By default the `attribution` property in `tilejson.json` is computed from the names and + URLs of the feed publishers. + If the OTP deployment contains many fields, this can become very unwieldy. + + This configuration parameter allows you to set the `attribution` to any string you wish, + for example `TriMet, C-Tran, SMART and Friends`. + """ + ) .asString(DEFAULT.attribution) ); } From 18b94fc34272724ec9619cd82952ee2f47b28487 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Feb 2024 13:33:02 +0100 Subject: [PATCH 341/356] Reduce flex default penalty --- docs/RouteRequest.md | 2 +- .../api/request/preference/AccessEgressPreferences.java | 6 +++++- .../org/opentripplanner/apis/transmodel/schema.graphql | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 4ef1e17a7d8..81f4dd396f6 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -411,7 +411,7 @@ The default values are - `car-to-park` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) - `car-rental` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) - `car-hailing` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) -- `flexible` = (timePenalty: 20m + 2.0 t, costFactor: 1.50) +- `flexible` = (timePenalty: 10m + 1.30 t, costFactor: 1.30) Example: `"car-to-park" : { "timePenalty": "10m + 1.5t", "costFactor": 2.5 }` diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java index ada495b19ba..9998f0a3b1c 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java @@ -25,12 +25,16 @@ public final class AccessEgressPreferences implements Serializable { TimePenalty.of(ofMinutes(20), 2f), 1.5 ); + private static final TimeAndCostPenalty FLEX_DEFAULT_PENALTY = TimeAndCostPenalty.of( + TimePenalty.of(ofMinutes(10), 1.3f), + 1.3 + ); private static final TimeAndCostPenaltyForEnum DEFAULT_TIME_AND_COST = TimeAndCostPenaltyForEnum .of(StreetMode.class) .with(StreetMode.CAR_TO_PARK, DEFAULT_PENALTY) .with(StreetMode.CAR_HAILING, DEFAULT_PENALTY) .with(StreetMode.CAR_RENTAL, DEFAULT_PENALTY) - .with(StreetMode.FLEXIBLE, DEFAULT_PENALTY) + .with(StreetMode.FLEXIBLE, FLEX_DEFAULT_PENALTY) .build(); public static final AccessEgressPreferences DEFAULT = new AccessEgressPreferences(); diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index dad106418fe..9c0eae88fa1 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -774,7 +774,7 @@ type QueryType { "Input type for executing a travel search for a trip between two locations. Returns trip patterns describing suggested alternatives for the trip." trip( "Time and cost penalty on access/egress modes." - accessEgressPenalty: [PenaltyForStreetMode!] = [{streetMode : car_park, timePenalty : "20m + 2.0 t", costFactor : 1.5}, {streetMode : flexible, timePenalty : "20m + 2.0 t", costFactor : 1.5}], + accessEgressPenalty: [PenaltyForStreetMode!] = [{streetMode : car_park, timePenalty : "20m + 2.0 t", costFactor : 1.5}, {streetMode : flexible, timePenalty : "10m + 1.30 t", costFactor : 1.3}], "The alightSlack is the minimum extra time after exiting a public transport vehicle. This is the default value used, if not overridden by the 'alightSlackList'." alightSlackDefault: Int = 0, "List of alightSlack for a given set of modes. Defaults: []" From 6ca07cfb17e6a0a99dae5e127333932d4182ca23 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Feb 2024 13:43:10 +0100 Subject: [PATCH 342/356] Fix test --- .../routing/api/request/preference/StreetPreferencesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java index 0289c24e837..a318474eab7 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/StreetPreferencesTest.java @@ -112,7 +112,7 @@ void testToString() { "accessEgress: AccessEgressPreferences{penalty: TimeAndCostPenaltyForEnum{CAR_TO_PARK: " + CAR_PENALTY + ", CAR_RENTAL: (timePenalty: 20m + 2.0 t, costFactor: 1.50), CAR_HAILING: (timePenalty: 20m + 2.0 t, costFactor: 1.50), " + - "FLEXIBLE: (timePenalty: 20m + 2.0 t, costFactor: 1.50)}, " + + "FLEXIBLE: (timePenalty: 10m + 1.30 t, costFactor: 1.30)}, " + "maxDuration: DurationForStreetMode{default:5m}" + "}, " + "maxDirectDuration: DurationForStreetMode{default:10m}" + From b7d037ee5c6caf33ab61b2c9cd6d4d928b0382ff Mon Sep 17 00:00:00 2001 From: Eivind Morris Bakke Date: Fri, 9 Feb 2024 15:28:38 +0100 Subject: [PATCH 343/356] Set defaults of the modes WALK, even if one and not the others are set (#5675) * Sets modes only if they are set in the request. Setting them to null overrides the default of WALK, which leads to no results. * Adds comment to the RequestModesMapper explaining defaults. * Adds unittest for RequestModesMapper and removes an unneeded unchecked warning suppression. * Makes keys constants in RequestModesMapper and changes map initialization in RequestModesMapperTest. * Makes use of Map.of everywhere in RequestModesMapperTest. --- .../mapping/RequestModesMapper.java | 33 ++++++----- .../mapping/RequestModesMapperTest.java | 57 +++++++++++++++++++ 2 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java index d02e251f4e2..59259905944 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapper.java @@ -7,23 +7,30 @@ class RequestModesMapper { + private static final String accessModeKey = "accessMode"; + private static final String egressModeKey = "egressMode"; + private static final String directModeKey = "directMode"; + /** - * Maps a GraphQL Modes input type to a RequestModes. - * - * This only maps access, egress, direct & transfer. - * Transport modes are now part of filters. - * Only in case filters are not present we will use this mapping + * Maps GraphQL Modes input type to RequestModes. + *

      + * This only maps access, egress, direct & transfer modes. Transport modes are set using filters. + * Default modes are WALK for access, egress, direct & transfer. */ - @SuppressWarnings("unchecked") static RequestModes mapRequestModes(Map modesInput) { - StreetMode accessMode = (StreetMode) modesInput.get("accessMode"); - RequestModesBuilder mBuilder = RequestModes - .of() - .withAccessMode(accessMode) - .withEgressMode((StreetMode) modesInput.get("egressMode")) - .withDirectMode((StreetMode) modesInput.get("directMode")); + RequestModesBuilder mBuilder = RequestModes.of(); - mBuilder.withTransferMode(accessMode == StreetMode.BIKE ? StreetMode.BIKE : StreetMode.WALK); + if (modesInput.containsKey(accessModeKey)) { + StreetMode accessMode = (StreetMode) modesInput.get(accessModeKey); + mBuilder.withAccessMode(accessMode); + mBuilder.withTransferMode(accessMode == StreetMode.BIKE ? StreetMode.BIKE : StreetMode.WALK); + } + if (modesInput.containsKey(egressModeKey)) { + mBuilder.withEgressMode((StreetMode) modesInput.get(egressModeKey)); + } + if (modesInput.containsKey(directModeKey)) { + mBuilder.withDirectMode((StreetMode) modesInput.get(directModeKey)); + } return mBuilder.build(); } diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java new file mode 100644 index 00000000000..160014213d3 --- /dev/null +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/RequestModesMapperTest.java @@ -0,0 +1,57 @@ +package org.opentripplanner.apis.transmodel.mapping; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.opentripplanner.routing.api.request.RequestModes; +import org.opentripplanner.routing.api.request.StreetMode; + +class RequestModesMapperTest { + + @Test + void testMapRequestModesEmptyMapReturnsDefaults() { + Map inputModes = Map.of(); + + RequestModes mappedModes = RequestModesMapper.mapRequestModes(inputModes); + + assertEquals(RequestModes.of().build(), mappedModes); + } + + @Test + void testMapRequestModesAccessSetReturnsDefaultsForOthers() { + Map inputModes = Map.of("accessMode", StreetMode.BIKE); + + RequestModes wantModes = RequestModes + .of() + .withAccessMode(StreetMode.BIKE) + .withTransferMode(StreetMode.BIKE) + .build(); + + RequestModes mappedModes = RequestModesMapper.mapRequestModes(inputModes); + + assertEquals(wantModes, mappedModes); + } + + @Test + void testMapRequestModesEgressSetReturnsDefaultsForOthers() { + Map inputModes = Map.of("egressMode", StreetMode.CAR); + + RequestModes wantModes = RequestModes.of().withEgressMode(StreetMode.CAR).build(); + + RequestModes mappedModes = RequestModesMapper.mapRequestModes(inputModes); + + assertEquals(wantModes, mappedModes); + } + + @Test + void testMapRequestModesDirectSetReturnsDefaultsForOthers() { + Map inputModes = Map.of("directMode", StreetMode.CAR); + + RequestModes wantModes = RequestModes.of().withDirectMode(StreetMode.CAR).build(); + + RequestModes mappedModes = RequestModesMapper.mapRequestModes(inputModes); + + assertEquals(wantModes, mappedModes); + } +} From 16108a9867159bb2fb6b70370f3ea791d34ad697 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Fri, 9 Feb 2024 14:28:53 +0000 Subject: [PATCH 344/356] Add changelog entry for #5675 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index df2ecd4b8fc..5fa9a3ee0b3 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -89,6 +89,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Remove "fare" [#5645](https://github.com/opentripplanner/OpenTripPlanner/pull/5645) - Refactor GroupStopBuilder addLocation method [#5651](https://github.com/opentripplanner/OpenTripPlanner/pull/5651) - Remove `VehicleToStopHeuristics` [#5381](https://github.com/opentripplanner/OpenTripPlanner/pull/5381) +- Set defaults of the modes WALK, even if one and not the others are set [#5675](https://github.com/opentripplanner/OpenTripPlanner/pull/5675) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 9cb7445f47330e7eb9ea511e6b325fe95f3b2b58 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Wed, 14 Feb 2024 08:43:30 +0000 Subject: [PATCH 345/356] Add changelog entry for #5674 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 5fa9a3ee0b3..86f6355f37f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -90,6 +90,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Refactor GroupStopBuilder addLocation method [#5651](https://github.com/opentripplanner/OpenTripPlanner/pull/5651) - Remove `VehicleToStopHeuristics` [#5381](https://github.com/opentripplanner/OpenTripPlanner/pull/5381) - Set defaults of the modes WALK, even if one and not the others are set [#5675](https://github.com/opentripplanner/OpenTripPlanner/pull/5675) +- Reduce flex default access/egress penalty [#5674](https://github.com/opentripplanner/OpenTripPlanner/pull/5674) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 0f63b2fbc8e7443ea2246ecbe5121d167dc8e651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Thu, 11 Jan 2024 13:57:02 +0100 Subject: [PATCH 346/356] Smoke tests wip Due to huge issues with mocking mapbox-gl, smoke tests on search bar and itinerary list. --- .github/workflows/debug-client.yml | 1 + client-next/package-lock.json | 6637 ++++++++--------- client-next/package.json | 8 +- .../ItineraryList/ItineraryList.test.tsx | 2394 ++++++ .../components/SearchBar/SearchBar.test.tsx | 14 + client-next/vite.config.ts | 4 + 6 files changed, 5737 insertions(+), 3321 deletions(-) create mode 100644 client-next/src/components/ItineraryList/ItineraryList.test.tsx create mode 100644 client-next/src/components/SearchBar/SearchBar.test.tsx diff --git a/.github/workflows/debug-client.yml b/.github/workflows/debug-client.yml index de92c121db7..56304db88f2 100644 --- a/.github/workflows/debug-client.yml +++ b/.github/workflows/debug-client.yml @@ -42,6 +42,7 @@ jobs: run: | npm install npm run build -- --base https://cdn.jsdelivr.net/gh/opentripplanner/debug-client-assets@main/${VERSION}/ + npm run coverage - name: Deploy compiled assets to repo if: github.event_name == 'push' && github.ref == 'refs/heads/dev-2.x' diff --git a/client-next/package-lock.json b/client-next/package-lock.json index 11894b5b246..b1dcfecb817 100644 --- a/client-next/package-lock.json +++ b/client-next/package-lock.json @@ -23,11 +23,13 @@ "@graphql-codegen/client-preset": "4.1.0", "@graphql-codegen/introspection": "4.0.0", "@parcel/watcher": "2.3.0", + "@testing-library/react": "14.1.2", "@types/react": "18.2.21", "@types/react-dom": "18.2.7", "@typescript-eslint/eslint-plugin": "6.5.0", "@typescript-eslint/parser": "6.5.0", "@vitejs/plugin-react": "4.0.4", + "@vitest/coverage-v8": "1.1.3", "eslint": "8.48.0", "eslint-config-prettier": "9.0.0", "eslint-plugin-import": "2.28.1", @@ -35,25 +37,25 @@ "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.3", + "jsdom": "23.2.0", "prettier": "3.0.3", "typescript": "5.2.2", - "vite": "4.4.9" + "vite": "4.4.9", + "vitest": "1.1.3" } }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -64,9 +66,8 @@ }, "node_modules/@ardatan/relay-compiler": { "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", - "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", @@ -93,71 +94,20 @@ "graphql": "*" } }, - "node_modules/@ardatan/relay-compiler/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@ardatan/relay-compiler/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@ardatan/relay-compiler/node_modules/cliui": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, - "node_modules/@ardatan/relay-compiler/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@ardatan/relay-compiler/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/@ardatan/relay-compiler/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -166,20 +116,10 @@ "node": ">=8" } }, - "node_modules/@ardatan/relay-compiler/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@ardatan/relay-compiler/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -189,9 +129,8 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -204,9 +143,8 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -214,29 +152,15 @@ "node": ">=8" } }, - "node_modules/@ardatan/relay-compiler/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@ardatan/relay-compiler/node_modules/y18n": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@ardatan/relay-compiler/node_modules/yargs": { "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -256,9 +180,8 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/yargs-parser": { "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -269,9 +192,8 @@ }, "node_modules/@ardatan/sync-fetch": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz", - "integrity": "sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==", "dev": true, + "license": "MIT", "dependencies": { "node-fetch": "^2.6.1" }, @@ -279,45 +201,116 @@ "node": ">=14" } }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.3", + "css-tree": "^2.3.1", + "is-potential-custom-element-name": "^1.0.1" + } + }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.5", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", - "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", + "version": "7.23.7", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.11", - "@babel/parser": "^7.22.11", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", @@ -331,22 +324,12 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -357,9 +340,8 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -368,14 +350,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "version": "7.23.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -383,27 +364,17 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", - "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", + "version": "7.23.7", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -415,32 +386,21 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -448,9 +408,8 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -459,40 +418,37 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "version": "7.23.0", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -503,9 +459,8 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -515,21 +470,19 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", + "version": "7.22.20", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -541,9 +494,8 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -553,9 +505,8 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -565,9 +516,8 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -576,53 +526,48 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.23.5", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", - "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", + "version": "7.23.8", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "version": "7.23.4", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -630,11 +575,74 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/parser": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.13.tgz", - "integrity": "sha512-3l6+4YOvc9wx7VlCSw4yQfcBo01ECA8TicQfbnCPuCEpRQrf+gTUyGdxNw+pyTUyywp6JRD1w0YQs9TpBXYlkw==", + "version": "7.23.6", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -644,9 +652,8 @@ }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -660,9 +667,8 @@ }, "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.7", @@ -679,9 +685,8 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -690,10 +695,9 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz", - "integrity": "sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -705,10 +709,9 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", - "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -720,10 +723,9 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -736,9 +738,8 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -747,10 +748,9 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", - "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -762,10 +762,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", - "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -777,10 +776,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz", - "integrity": "sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg==", + "version": "7.23.4", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -792,18 +790,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", - "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "version": "7.23.8", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, @@ -815,13 +811,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", - "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" + "@babel/template": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -831,10 +826,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz", - "integrity": "sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -846,13 +840,12 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz", - "integrity": "sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-flow": "^7.22.5" + "@babel/plugin-syntax-flow": "^7.23.3" }, "engines": { "node": ">=6.9.0" @@ -862,12 +855,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "version": "7.23.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -877,13 +870,12 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", - "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -894,10 +886,9 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", - "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -909,10 +900,9 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", - "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -924,12 +914,11 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.11.tgz", - "integrity": "sha512-o2+bg7GDS60cJMgz9jWqRUsWkMzLCxp+jFDeDUT5sjRlAxcJWZ2ylNdI7QQ2+CH5hWu7OnN+Cv3htt7AkSf96g==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.22.9", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -941,13 +930,12 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", - "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5" + "@babel/helper-replace-supers": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -957,10 +945,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -972,10 +959,9 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", - "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -987,10 +973,9 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", - "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1002,16 +987,15 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", + "version": "7.23.4", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" }, "engines": { "node": ">=6.9.0" @@ -1021,10 +1005,9 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz", - "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1036,10 +1019,9 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz", - "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1051,10 +1033,9 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", - "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1066,10 +1047,9 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", - "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1082,10 +1062,9 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", - "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "version": "7.23.3", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1097,9 +1076,8 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", - "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", + "version": "7.23.8", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1108,34 +1086,32 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", + "version": "7.23.7", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.11", - "@babel/types": "^7.22.11", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1143,400 +1119,64 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.23.6", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/@esbuild/android-arm64": { + "node_modules/@esbuild/darwin-x64": { "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "android" + "darwin" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", "dev": true, - "optional": true, - "os": [ - "android" - ], + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -1556,10 +1196,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.24.0", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -1570,25 +1209,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@googlemaps/polyline-codec": { "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@googlemaps/polyline-codec/-/polyline-codec-1.0.28.tgz", - "integrity": "sha512-m7rh8sbxlrHvebXEweBHX8r1uPtToPRYxWDD6p6k2YG8hyhBe0Wi6xRUVFpxpEseMNgF+OBotFQC5senj8K7TQ==" + "license": "Apache-2.0" }, "node_modules/@graphql-codegen/add": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-5.0.0.tgz", - "integrity": "sha512-ynWDOsK2yxtFHwcJTB9shoSkUd7YXd6ZE57f0nk7W5cu/nAgxZZpEsnTPEpZB/Mjf14YRGe2uJHQ7AfElHjqUQ==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "tslib": "~2.5.0" @@ -1599,15 +1246,13 @@ }, "node_modules/@graphql-codegen/add/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/cli": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-5.0.0.tgz", - "integrity": "sha512-A7J7+be/a6e+/ul2KI5sfJlpoqeqwX8EzktaKCeduyVKgOLA6W5t+NUGf6QumBDXU8PEOqXk3o3F+RAwCWOiqA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/generator": "^7.18.13", "@babel/template": "^7.18.10", @@ -1660,81 +1305,10 @@ } } }, - "node_modules/@graphql-codegen/cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@graphql-codegen/cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@graphql-codegen/cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@graphql-codegen/cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@graphql-codegen/cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@graphql-codegen/cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@graphql-codegen/client-preset": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@graphql-codegen/client-preset/-/client-preset-4.1.0.tgz", - "integrity": "sha512-/3Ymb/fjxIF1+HGmaI1YwSZbWsrZAWMSQjh3dU425eBjctjsVQ6gzGRr+l/gE5F1mtmCf+vlbTAT03heAc/QIw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/template": "^7.20.7", @@ -1756,15 +1330,13 @@ }, "node_modules/@graphql-codegen/client-preset/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/core": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-4.0.0.tgz", - "integrity": "sha512-JAGRn49lEtSsZVxeIlFVIRxts2lWObR+OQo7V2LHDJ7ohYYw3ilv7nJ8pf8P4GTg/w6ptcYdSdVVdkI8kUHB/Q==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-tools/schema": "^10.0.0", @@ -1777,15 +1349,13 @@ }, "node_modules/@graphql-codegen/core/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/gql-tag-operations": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.1.tgz", - "integrity": "sha512-qF6wIbBzW8BNT+wiVsBxrYOs2oYcsxQ7mRvCpfEI3HnNZMAST/uX76W8MqFEJvj4mw7NIDv7xYJAcAZIWM5LWw==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/visitor-plugin-common": "4.0.1", @@ -1799,15 +1369,13 @@ }, "node_modules/@graphql-codegen/gql-tag-operations/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/introspection": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@graphql-codegen/introspection/-/introspection-4.0.0.tgz", - "integrity": "sha512-t9g3AkK99dfHblMWtG4ynUM9+A7JrWq5110zSpNV2wlSnv0+bRKagDW8gozwgXfR5i1IIG8QDjJZ6VgXQVqCZw==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/visitor-plugin-common": "^4.0.0", @@ -1819,15 +1387,13 @@ }, "node_modules/@graphql-codegen/introspection/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/plugin-helpers": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.1.tgz", - "integrity": "sha512-6L5sb9D8wptZhnhLLBcheSPU7Tg//DGWgc5tQBWX46KYTOTQHGqDpv50FxAJJOyFVJrveN9otWk9UT9/yfY4ww==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "change-case-all": "1.0.15", @@ -1842,15 +1408,13 @@ }, "node_modules/@graphql-codegen/plugin-helpers/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/schema-ast": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-4.0.0.tgz", - "integrity": "sha512-WIzkJFa9Gz28FITAPILbt+7A8+yzOyd1NxgwFh7ie+EmO9a5zQK6UQ3U/BviirguXCYnn+AR4dXsoDrSrtRA1g==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-tools/utils": "^10.0.0", @@ -1862,15 +1426,13 @@ }, "node_modules/@graphql-codegen/schema-ast/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/typed-document-node": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.1.tgz", - "integrity": "sha512-VFkhCuJnkgtbbgzoCAwTdJe2G1H6sd3LfCrDqWUrQe53y2ukfSb5Ov1PhAIkCBStKCMQBUY9YgGz9GKR40qQ8g==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/visitor-plugin-common": "4.0.1", @@ -1884,15 +1446,13 @@ }, "node_modules/@graphql-codegen/typed-document-node/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/typescript": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-4.0.1.tgz", - "integrity": "sha512-3YziQ21dCVdnHb+Us1uDb3pA6eG5Chjv0uTK+bt9dXeMlwYBU8MbtzvQTo4qvzWVC1AxSOKj0rgfNu1xCXqJyA==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/schema-ast": "^4.0.0", @@ -1906,9 +1466,8 @@ }, "node_modules/@graphql-codegen/typescript-operations": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-4.0.1.tgz", - "integrity": "sha512-GpUWWdBVUec/Zqo23aFLBMrXYxN2irypHqDcKjN78JclDPdreasAEPcIpMfqf4MClvpmvDLy4ql+djVAwmkjbw==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/typescript": "^4.0.1", @@ -1922,21 +1481,18 @@ }, "node_modules/@graphql-codegen/typescript-operations/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/typescript/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-codegen/visitor-plugin-common": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-4.0.1.tgz", - "integrity": "sha512-Bi/1z0nHg4QMsAqAJhds+ForyLtk7A3HQOlkrZNm3xEkY7lcBzPtiOTLBtvziwopBsXUxqeSwVjOOFPLS5Yw1Q==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-tools/optimize": "^2.0.0", @@ -1955,15 +1511,13 @@ }, "node_modules/@graphql-codegen/visitor-plugin-common/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@graphql-tools/apollo-engine-loader": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-8.0.0.tgz", - "integrity": "sha512-axQTbN5+Yxs1rJ6cWQBOfw3AEeC+fvIuZSfJLPLLvFJLj4pUm9fhxey/g6oQZAAQJqKPfw+tLDUQvnfvRK8Kmg==", "dev": true, + "license": "MIT", "dependencies": { "@ardatan/sync-fetch": "^0.0.1", "@graphql-tools/utils": "^10.0.0", @@ -1979,20 +1533,18 @@ }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, + "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.9.tgz", - "integrity": "sha512-OTVoDm039CNyAWSRc2WBimMl/N9J4Fk2le21Xzcf+3OiWPNNSIbMnpWKBUyraPh2d9SAEgoBdQxTfVNihXgiUw==", + "version": "0.9.15", "dev": true, + "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.4.8", + "@whatwg-node/node-fetch": "^0.5.0", "urlpattern-polyfill": "^9.0.0" }, "engines": { @@ -2000,15 +1552,14 @@ } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.14.tgz", - "integrity": "sha512-ii/eZz2PcjLGj9D6WfsmfzlTzZV1Kz6MxYpq2Vc5P21J8vkKfENWC9B2ISsFCKovxElLukIwPg8HTrHFsLNflg==", + "version": "0.5.4", "dev": true, + "license": "MIT", "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", - "fast-url-parser": "^1.1.3", "tslib": "^2.3.1" }, "engines": { @@ -2017,15 +1568,13 @@ }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/urlpattern-polyfill": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@graphql-tools/batch-execute": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-9.0.2.tgz", - "integrity": "sha512-Y2uwdZI6ZnatopD/SYfZ1eGuQFI7OU2KGZ2/B/7G9ISmgMl5K+ZZWz/PfIEXeiHirIDhyk54s4uka5rj2xwKqQ==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.5", "dataloader": "^2.2.2", @@ -2040,12 +1589,11 @@ } }, "node_modules/@graphql-tools/code-file-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-8.0.2.tgz", - "integrity": "sha512-AKNpkElUL2cWocYpC4DzNEpo6qJw8Lp+L3bKQ/mIfmbsQxgLz5uve6zHBMhDaFPdlwfIox41N3iUSvi77t9e8A==", + "version": "8.0.3", "dev": true, + "license": "MIT", "dependencies": { - "@graphql-tools/graphql-tag-pluck": "8.0.2", + "@graphql-tools/graphql-tag-pluck": "8.1.0", "@graphql-tools/utils": "^10.0.0", "globby": "^11.0.3", "tslib": "^2.4.0", @@ -2059,10 +1607,9 @@ } }, "node_modules/@graphql-tools/delegate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-10.0.2.tgz", - "integrity": "sha512-ZU7VnR2xFgHrGnsuw6+nRJkcvSucn7w5ooxb/lTKlVfrNJfTwJevNcNKMnbtPUSajG3+CaFym/nU6v44GXCmNw==", + "version": "10.0.3", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/batch-execute": "^9.0.1", "@graphql-tools/executor": "^1.0.0", @@ -2080,9 +1627,8 @@ }, "node_modules/@graphql-tools/documents": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/documents/-/documents-1.0.0.tgz", - "integrity": "sha512-rHGjX1vg/nZ2DKqRGfDPNC55CWZBMldEVcH+91BThRa6JeT80NqXknffLLEZLRUxyikCfkwMsk6xR3UNMqG0Rg==", "dev": true, + "license": "MIT", "dependencies": { "lodash.sortby": "^4.7.0", "tslib": "^2.4.0" @@ -2096,9 +1642,8 @@ }, "node_modules/@graphql-tools/executor": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.2.0.tgz", - "integrity": "sha512-SKlIcMA71Dha5JnEWlw4XxcaJ+YupuXg0QCZgl2TOLFz4SkGCwU/geAsJvUJFwK2RbVLpQv/UMq67lOaBuwDtg==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "@graphql-typed-document-node/core": "3.2.0", @@ -2115,9 +1660,8 @@ }, "node_modules/@graphql-tools/executor-graphql-ws": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-1.1.0.tgz", - "integrity": "sha512-yM67SzwE8rYRpm4z4AuGtABlOp9mXXVy6sxXnTJRoYIdZrmDbKVfIY+CpZUJCqS0FX3xf2+GoHlsj7Qswaxgcg==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.2", "@types/ws": "^8.0.0", @@ -2134,10 +1678,9 @@ } }, "node_modules/@graphql-tools/executor-http": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/executor-http/-/executor-http-1.0.2.tgz", - "integrity": "sha512-JKTB4E3kdQM2/1NEcyrVPyQ8057ZVthCV5dFJiKktqY9IdmF00M8gupFcW3jlbM/Udn78ickeUBsUzA3EouqpA==", + "version": "1.0.7", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.2", "@repeaterjs/repeater": "^3.0.4", @@ -2156,20 +1699,18 @@ }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/events": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, + "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/fetch": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.9.tgz", - "integrity": "sha512-OTVoDm039CNyAWSRc2WBimMl/N9J4Fk2le21Xzcf+3OiWPNNSIbMnpWKBUyraPh2d9SAEgoBdQxTfVNihXgiUw==", + "version": "0.9.15", "dev": true, + "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.4.8", + "@whatwg-node/node-fetch": "^0.5.0", "urlpattern-polyfill": "^9.0.0" }, "engines": { @@ -2177,15 +1718,14 @@ } }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.14.tgz", - "integrity": "sha512-ii/eZz2PcjLGj9D6WfsmfzlTzZV1Kz6MxYpq2Vc5P21J8vkKfENWC9B2ISsFCKovxElLukIwPg8HTrHFsLNflg==", + "version": "0.5.4", "dev": true, + "license": "MIT", "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", - "fast-url-parser": "^1.1.3", "tslib": "^2.3.1" }, "engines": { @@ -2194,21 +1734,19 @@ }, "node_modules/@graphql-tools/executor-http/node_modules/urlpattern-polyfill": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@graphql-tools/executor-legacy-ws": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-1.0.1.tgz", - "integrity": "sha512-PQrTJ+ncHMEQspBARc2lhwiQFfRAX/z/CsOdZTFjIljOHgRWGAA1DAx7pEN0j6PflbLCfZ3NensNq2jCBwF46w==", + "version": "1.0.5", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "@types/ws": "^8.0.0", - "isomorphic-ws": "5.0.0", + "isomorphic-ws": "^5.0.0", "tslib": "^2.4.0", - "ws": "8.13.0" + "ws": "^8.15.0" }, "engines": { "node": ">=16.0.0" @@ -2218,12 +1756,11 @@ } }, "node_modules/@graphql-tools/git-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-8.0.2.tgz", - "integrity": "sha512-AuCB0nlPvsHh8u42zRZdlD/ZMaWP9A44yAkQUVCZir1E/LG63fsZ9svTWJ+CbusW3Hd0ZP9qpxEhlHxnd4Tlsg==", + "version": "8.0.3", "dev": true, + "license": "MIT", "dependencies": { - "@graphql-tools/graphql-tag-pluck": "8.0.2", + "@graphql-tools/graphql-tag-pluck": "8.1.0", "@graphql-tools/utils": "^10.0.0", "is-glob": "4.0.3", "micromatch": "^4.0.4", @@ -2239,9 +1776,8 @@ }, "node_modules/@graphql-tools/github-loader": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-8.0.0.tgz", - "integrity": "sha512-VuroArWKcG4yaOWzV0r19ElVIV6iH6UKDQn1MXemND0xu5TzrFme0kf3U9o0YwNo0kUYEk9CyFM0BYg4he17FA==", "dev": true, + "license": "MIT", "dependencies": { "@ardatan/sync-fetch": "^0.0.1", "@graphql-tools/executor-http": "^1.0.0", @@ -2260,20 +1796,18 @@ }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, + "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.9.tgz", - "integrity": "sha512-OTVoDm039CNyAWSRc2WBimMl/N9J4Fk2le21Xzcf+3OiWPNNSIbMnpWKBUyraPh2d9SAEgoBdQxTfVNihXgiUw==", + "version": "0.9.15", "dev": true, + "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.4.8", + "@whatwg-node/node-fetch": "^0.5.0", "urlpattern-polyfill": "^9.0.0" }, "engines": { @@ -2281,15 +1815,14 @@ } }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.14.tgz", - "integrity": "sha512-ii/eZz2PcjLGj9D6WfsmfzlTzZV1Kz6MxYpq2Vc5P21J8vkKfENWC9B2ISsFCKovxElLukIwPg8HTrHFsLNflg==", + "version": "0.5.4", "dev": true, + "license": "MIT", "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", - "fast-url-parser": "^1.1.3", "tslib": "^2.3.1" }, "engines": { @@ -2298,15 +1831,13 @@ }, "node_modules/@graphql-tools/github-loader/node_modules/urlpattern-polyfill": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@graphql-tools/graphql-file-loader": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-8.0.0.tgz", - "integrity": "sha512-wRXj9Z1IFL3+zJG1HWEY0S4TXal7+s1vVhbZva96MSp0kbb/3JBF7j0cnJ44Eq0ClccMgGCDFqPFXty4JlpaPg==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/import": "7.0.0", "@graphql-tools/utils": "^10.0.0", @@ -2322,10 +1853,9 @@ } }, "node_modules/@graphql-tools/graphql-tag-pluck": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-8.0.2.tgz", - "integrity": "sha512-U6fE4yEHxuk/nqmPixHpw1WhqdS6aYuaV60m1bEmUmGJNbpAhaMBy01JncpvpF15yZR5LZ0UjkHg+A3Lhoc8YQ==", + "version": "8.1.0", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.22.9", "@babel/parser": "^7.16.8", @@ -2344,9 +1874,8 @@ }, "node_modules/@graphql-tools/import": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-7.0.0.tgz", - "integrity": "sha512-NVZiTO8o1GZs6OXzNfjB+5CtQtqsZZpQOq+Uu0w57kdUkT4RlQKlwhT8T81arEsbV55KpzkpFsOZP7J1wdmhBw==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "resolve-from": "5.0.0", @@ -2359,20 +1888,10 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/import/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@graphql-tools/json-file-loader": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-8.0.0.tgz", - "integrity": "sha512-ki6EF/mobBWJjAAC84xNrFMhNfnUFD6Y0rQMGXekrUgY0NdeYXHU0ZUgHzC9O5+55FslqUmAUHABePDHTyZsLg==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "globby": "^11.0.3", @@ -2387,13 +1906,12 @@ } }, "node_modules/@graphql-tools/load": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-8.0.0.tgz", - "integrity": "sha512-Cy874bQJH0FP2Az7ELPM49iDzOljQmK1PPH6IuxsWzLSTxwTqd8dXA09dcVZrI7/LsN26heTY2R8q2aiiv0GxQ==", + "version": "8.0.1", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/schema": "^10.0.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/utils": "^10.0.11", "p-limit": "3.1.0", "tslib": "^2.4.0" }, @@ -2405,12 +1923,11 @@ } }, "node_modules/@graphql-tools/merge": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.0.tgz", - "integrity": "sha512-J7/xqjkGTTwOJmaJQJ2C+VDBDOWJL3lKrHJN4yMaRLAJH3PosB7GiPRaSDZdErs0+F77sH2MKs2haMMkywzx7Q==", + "version": "9.0.1", "dev": true, + "license": "MIT", "dependencies": { - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/utils": "^10.0.10", "tslib": "^2.4.0" }, "engines": { @@ -2422,9 +1939,8 @@ }, "node_modules/@graphql-tools/optimize": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-2.0.0.tgz", - "integrity": "sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.4.0" }, @@ -2436,13 +1952,12 @@ } }, "node_modules/@graphql-tools/prisma-loader": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-8.0.1.tgz", - "integrity": "sha512-bl6e5sAYe35Z6fEbgKXNrqRhXlCJYeWKBkarohgYA338/SD9eEhXtg3Cedj7fut3WyRLoQFpHzfiwxKs7XrgXg==", + "version": "8.0.2", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/url-loader": "^8.0.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/utils": "^10.0.8", "@types/js-yaml": "^4.0.0", "@types/json-stable-stringify": "^1.0.32", "@whatwg-node/fetch": "^0.9.0", @@ -2452,7 +1967,7 @@ "graphql-request": "^6.0.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", - "jose": "^4.11.4", + "jose": "^5.0.0", "js-yaml": "^4.0.0", "json-stable-stringify": "^1.0.1", "lodash": "^4.17.20", @@ -2462,130 +1977,55 @@ }, "engines": { "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.9.tgz", - "integrity": "sha512-OTVoDm039CNyAWSRc2WBimMl/N9J4Fk2le21Xzcf+3OiWPNNSIbMnpWKBUyraPh2d9SAEgoBdQxTfVNihXgiUw==", - "dev": true, - "dependencies": { - "@whatwg-node/node-fetch": "^0.4.8", - "urlpattern-polyfill": "^9.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.14.tgz", - "integrity": "sha512-ii/eZz2PcjLGj9D6WfsmfzlTzZV1Kz6MxYpq2Vc5P21J8vkKfENWC9B2ISsFCKovxElLukIwPg8HTrHFsLNflg==", - "dev": true, - "dependencies": { - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "fast-url-parser": "^1.1.3", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/prisma-loader/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/events": { + "version": "0.1.1", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, + "license": "MIT", "engines": { - "node": ">=7.0.0" + "node": ">=16.0.0" } }, - "node_modules/@graphql-tools/prisma-loader/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@graphql-tools/prisma-loader/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": { + "version": "0.9.15", "dev": true, + "license": "MIT", + "dependencies": { + "@whatwg-node/node-fetch": "^0.5.0", + "urlpattern-polyfill": "^9.0.0" + }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/@graphql-tools/prisma-loader/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": { + "version": "0.5.4", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@kamilkisiela/fast-url-parser": "^1.1.4", + "@whatwg-node/events": "^0.1.0", + "busboy": "^1.6.0", + "fast-querystring": "^1.1.1", + "tslib": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, "node_modules/@graphql-tools/prisma-loader/node_modules/urlpattern-polyfill": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@graphql-tools/relay-operation-optimizer": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.0.tgz", - "integrity": "sha512-UNlJi5y3JylhVWU4MBpL0Hun4Q7IoJwv9xYtmAz+CgRa066szzY7dcuPfxrA7cIGgG/Q6TVsKsYaiF4OHPs1Fw==", "dev": true, + "license": "MIT", "dependencies": { "@ardatan/relay-compiler": "12.0.0", "@graphql-tools/utils": "^10.0.0", @@ -2599,13 +2039,12 @@ } }, "node_modules/@graphql-tools/schema": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.0.tgz", - "integrity": "sha512-kf3qOXMFcMs2f/S8Y3A8fm/2w+GaHAkfr3Gnhh2LOug/JgpY/ywgFVxO3jOeSpSEdoYcDKLcXVjMigNbY4AdQg==", + "version": "10.0.2", "dev": true, + "license": "MIT", "dependencies": { - "@graphql-tools/merge": "^9.0.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/merge": "^9.0.1", + "@graphql-tools/utils": "^10.0.10", "tslib": "^2.4.0", "value-or-promise": "^1.0.12" }, @@ -2617,15 +2056,14 @@ } }, "node_modules/@graphql-tools/url-loader": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-8.0.0.tgz", - "integrity": "sha512-rPc9oDzMnycvz+X+wrN3PLrhMBQkG4+sd8EzaFN6dypcssiefgWKToXtRKI8HHK68n2xEq1PyrOpkjHFJB+GwA==", + "version": "8.0.1", "dev": true, + "license": "MIT", "dependencies": { "@ardatan/sync-fetch": "^0.0.1", "@graphql-tools/delegate": "^10.0.0", "@graphql-tools/executor-graphql-ws": "^1.0.0", - "@graphql-tools/executor-http": "^1.0.0", + "@graphql-tools/executor-http": "^1.0.5", "@graphql-tools/executor-legacy-ws": "^1.0.0", "@graphql-tools/utils": "^10.0.0", "@graphql-tools/wrap": "^10.0.0", @@ -2645,20 +2083,18 @@ }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, + "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.9.tgz", - "integrity": "sha512-OTVoDm039CNyAWSRc2WBimMl/N9J4Fk2le21Xzcf+3OiWPNNSIbMnpWKBUyraPh2d9SAEgoBdQxTfVNihXgiUw==", + "version": "0.9.15", "dev": true, + "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.4.8", + "@whatwg-node/node-fetch": "^0.5.0", "urlpattern-polyfill": "^9.0.0" }, "engines": { @@ -2666,15 +2102,14 @@ } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.14.tgz", - "integrity": "sha512-ii/eZz2PcjLGj9D6WfsmfzlTzZV1Kz6MxYpq2Vc5P21J8vkKfENWC9B2ISsFCKovxElLukIwPg8HTrHFsLNflg==", + "version": "0.5.4", "dev": true, + "license": "MIT", "dependencies": { + "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", - "fast-url-parser": "^1.1.3", "tslib": "^2.3.1" }, "engines": { @@ -2683,17 +2118,16 @@ }, "node_modules/@graphql-tools/url-loader/node_modules/urlpattern-polyfill": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@graphql-tools/utils": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.5.tgz", - "integrity": "sha512-ZTioQqg9z9eCG3j+KDy54k1gp6wRIsLqkx5yi163KVvXVkfjsrdErCyZjrEug21QnKE9piP4tyxMpMMOT1RuRw==", + "version": "10.0.12", "dev": true, + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", + "cross-inspect": "1.0.0", "dset": "^3.1.2", "tslib": "^2.4.0" }, @@ -2705,12 +2139,11 @@ } }, "node_modules/@graphql-tools/wrap": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-10.0.0.tgz", - "integrity": "sha512-HDOeUUh6UhpiH0WPJUQl44ODt1x5pnMUbOJZ7GjTdGQ7LK0AgVt3ftaAQ9duxLkiAtYJmu5YkULirfZGj4HzDg==", + "version": "10.0.1", "dev": true, + "license": "MIT", "dependencies": { - "@graphql-tools/delegate": "^10.0.0", + "@graphql-tools/delegate": "^10.0.3", "@graphql-tools/schema": "^10.0.0", "@graphql-tools/utils": "^10.0.0", "tslib": "^2.4.0", @@ -2725,20 +2158,18 @@ }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.14", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -2747,9 +2178,8 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -2759,16 +2189,33 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "version": "2.0.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2780,42 +2227,42 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.21", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kamilkisiela/fast-url-parser": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, "node_modules/@mapbox/geojson-rewind": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", - "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "license": "ISC", "dependencies": { "get-stream": "^6.0.1", "minimist": "^1.2.6" @@ -2826,47 +2273,39 @@ }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", - "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", "engines": { "node": ">= 0.6" } }, "node_modules/@mapbox/point-geometry": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", - "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" + "license": "ISC" }, "node_modules/@mapbox/tiny-sdf": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", - "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==" + "license": "BSD-2-Clause" }, "node_modules/@mapbox/unitbezier": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", - "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==" + "license": "BSD-2-Clause" }, "node_modules/@mapbox/vector-tile": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", - "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "license": "BSD-3-Clause", "dependencies": { "@mapbox/point-geometry": "~0.1.0" } }, "node_modules/@mapbox/whoots-js": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", - "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "license": "ISC", "engines": { "node": ">=6.0.0" } }, "node_modules/@maplibre/maplibre-gl-style-spec": { "version": "19.3.3", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", - "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", + "license": "ISC", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", @@ -2883,9 +2322,8 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2896,18 +2334,16 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2918,10 +2354,8 @@ }, "node_modules/@parcel/watcher": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.3.0.tgz", - "integrity": "sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -2950,54 +2384,13 @@ "@parcel/watcher-win32-x64": "2.3.0" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz", - "integrity": "sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz", - "integrity": "sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/watcher-darwin-x64": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz", - "integrity": "sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3010,202 +2403,20 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz", - "integrity": "sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz", - "integrity": "sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz", - "integrity": "sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz", - "integrity": "sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz", - "integrity": "sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz", - "integrity": "sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz", - "integrity": "sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz", - "integrity": "sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz", - "integrity": "sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@peculiar/asn1-schema": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz", - "integrity": "sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==", + "version": "2.3.8", "dev": true, + "license": "MIT", "dependencies": { "asn1js": "^3.0.5", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.0" + "pvtsutils": "^1.3.5", + "tslib": "^2.6.2" } }, "node_modules/@peculiar/json-schema": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", - "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -3215,9 +2426,8 @@ }, "node_modules/@peculiar/webcrypto": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", - "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", "dev": true, + "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.3.6", "@peculiar/json-schema": "^1.1.12", @@ -3231,17 +2441,15 @@ }, "node_modules/@popperjs/core": { "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@react-aria/ssr": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.1.tgz", - "integrity": "sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==", + "version": "3.9.1", + "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" }, @@ -3253,15 +2461,13 @@ } }, "node_modules/@repeaterjs/repeater": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", - "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==", - "dev": true + "version": "3.0.5", + "dev": true, + "license": "MIT" }, "node_modules/@restart/hooks": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", - "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", + "version": "0.4.15", + "license": "MIT", "dependencies": { "dequal": "^2.0.3" }, @@ -3271,8 +2477,7 @@ }, "node_modules/@restart/ui": { "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", - "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.21.0", "@popperjs/core": "^2.11.6", @@ -3289,60 +2494,118 @@ "react-dom": ">=16.14.0" } }, - "node_modules/@restart/ui/node_modules/uncontrollable": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", - "peerDependencies": { - "react": ">=16.14.0" + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "license": "MIT", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.9.5", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.3", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@testing-library/dom": { + "version": "9.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@swc/helpers": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", - "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==", + "node_modules/@testing-library/react": { + "version": "14.1.2", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.4.0" + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, "node_modules/@types/geojson": { "version": "7946.0.13", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz", - "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==" + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" }, "node_modules/@types/js-yaml": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", - "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", - "dev": true + "version": "4.0.9", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true + "version": "7.0.15", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-stable-stringify": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz", - "integrity": "sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==", - "dev": true + "version": "1.0.36", + "dev": true, + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mapbox__point-geometry": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", - "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==" + "license": "MIT" }, "node_modules/@types/mapbox__vector-tile": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", - "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "license": "MIT", "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", @@ -3350,33 +2613,31 @@ } }, "node_modules/@types/mapbox-gl": { - "version": "2.7.13", - "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.7.13.tgz", - "integrity": "sha512-qNffhTdYkeFl8QG9Q1zPPJmcs8PvHgmLa1PcwP1rxvcfMsIgcFr/FnrCttG0ZnH7Kzdd7xfECSRNTWSr4jC3PQ==", + "version": "2.7.19", + "license": "MIT", "dependencies": { "@types/geojson": "*" } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "dev": true + "version": "20.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/pbf": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", - "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" + "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "license": "MIT" }, "node_modules/@types/react": { "version": "18.2.21", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", - "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3385,59 +2646,51 @@ }, "node_modules/@types/react-dom": { "version": "18.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", - "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "version": "4.4.10", + "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + "version": "0.16.8", + "license": "MIT" }, "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", - "dev": true + "version": "7.5.6", + "dev": true, + "license": "MIT" }, "node_modules/@types/supercluster": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", - "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", "dependencies": { "@types/geojson": "*" } }, "node_modules/@types/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" + "version": "3.0.3", + "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.10", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.5.0", @@ -3468,11 +2721,40 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, "node_modules/@typescript-eslint/parser": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "6.5.0", "@typescript-eslint/types": "6.5.0", @@ -3490,167 +2772,391 @@ "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/utils": "6.5.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "6.5.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.22.9", + "@babel/plugin-transform-react-jsx-self": "^7.22.5", + "@babel/plugin-transform-react-jsx-source": "^7.22.5", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.2", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "^1.0.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", + "node_modules/@vitest/expect": { + "version": "1.1.3", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" + "@vitest/spy": "1.1.3", + "@vitest/utils": "1.1.3", + "chai": "^4.3.10" }, - "engines": { - "node": "^16.0.0 || >=18.0.0" + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.1.3", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "yocto-queue": "^1.0.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=18" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=12.20" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", + "node_modules/@vitest/snapshot": { + "version": "1.1.3", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", + "node_modules/@vitest/snapshot/node_modules/pretty-format": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "semver": "^7.5.4" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/snapshot/node_modules/react-is": { + "version": "18.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/spy": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", + "node_modules/@vitest/utils": { + "version": "1.1.3", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@vitejs/plugin-react": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.4.tgz", - "integrity": "sha512-7wU921ABnNYkETiMaZy7XqpueMnpu5VxvVps13MjmCo+utBdD79sZzrApHawHtVX66cCJQQTXFcjH0y9dSUK8g==", + "node_modules/@vitest/utils/node_modules/pretty-format": { + "version": "29.7.0", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.22.9", - "@babel/plugin-transform-react-jsx-self": "^7.22.5", - "@babel/plugin-transform-react-jsx-source": "^7.22.5", - "react-refresh": "^0.14.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@vitest/utils/node_modules/react-is": { + "version": "18.2.0", + "dev": true, + "license": "MIT" + }, "node_modules/@whatwg-node/events": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", - "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@whatwg-node/fetch": { "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.8.8.tgz", - "integrity": "sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg==", "dev": true, + "license": "MIT", "dependencies": { "@peculiar/webcrypto": "^1.4.0", "@whatwg-node/node-fetch": "^0.3.6", @@ -3661,9 +3167,8 @@ }, "node_modules/@whatwg-node/node-fetch": { "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", - "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", "dev": true, + "license": "MIT", "dependencies": { "@whatwg-node/events": "^0.0.3", "busboy": "^1.6.0", @@ -3673,10 +3178,9 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3686,18 +3190,24 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -3707,9 +3217,8 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3720,9 +3229,8 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3736,9 +3244,8 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -3749,67 +3256,52 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "5.1.3", "dev": true, + "license": "Apache-2.0", "dependencies": { - "dequal": "^2.0.3" + "deep-equal": "^2.0.5" } }, "node_modules/arr-union": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "is-array-buffer": "^3.0.1" @@ -3819,15 +3311,14 @@ } }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { @@ -3839,18 +3330,16 @@ }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/array.prototype.findlastindex": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3866,14 +3355,13 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "version": "1.3.2", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -3884,14 +3372,13 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -3902,27 +3389,26 @@ } }, "node_modules/array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "version": "1.1.2", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" + "get-intrinsic": "^1.2.1" } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "version": "1.0.2", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", "is-array-buffer": "^3.0.2", "is-shared-array-buffer": "^1.0.2" @@ -3936,15 +3422,13 @@ }, "node_modules/asap": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/asn1js": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", - "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "pvtsutils": "^1.3.2", "pvutils": "^1.1.3", @@ -3954,43 +3438,51 @@ "node": ">=12.0.0" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/assign-symbols": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/ast-types-flow": { "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asynciterator.prototype": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, "node_modules/auto-bind": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", - "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4000,9 +3492,8 @@ }, "node_modules/available-typed-arrays": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4011,34 +3502,30 @@ } }, "node_modules/axe-core": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", - "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", + "version": "4.8.3", "dev": true, + "license": "MPL-2.0", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } }, "node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", - "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-preset-fbjs": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", - "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", @@ -4074,14 +3561,11 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { @@ -4096,13 +3580,21 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -4111,8 +3603,6 @@ }, "node_modules/bootstrap": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz", - "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==", "funding": [ { "type": "github", @@ -4123,15 +3613,15 @@ "url": "https://opencollective.com/bootstrap" } ], + "license": "MIT", "peerDependencies": { "@popperjs/core": "^2.11.8" } }, "node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4139,9 +3629,8 @@ }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -4150,9 +3639,7 @@ } }, "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.22.2", "dev": true, "funding": [ { @@ -4168,11 +3655,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -4183,17 +3671,14 @@ }, "node_modules/bser": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { @@ -4209,6 +3694,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -4216,8 +3702,6 @@ }, "node_modules/busboy": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dev": true, "dependencies": { "streamsearch": "^1.1.0" @@ -4228,8 +3712,7 @@ }, "node_modules/bytewise": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", - "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", + "license": "MIT", "dependencies": { "bytewise-core": "^1.2.2", "typewise": "^1.0.3" @@ -4237,20 +3720,27 @@ }, "node_modules/bytewise-core": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", - "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", + "license": "MIT", "dependencies": { "typewise-core": "^1.2" } }, + "node_modules/cac": { + "version": "6.7.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4258,18 +3748,16 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camel-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, + "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" @@ -4277,17 +3765,14 @@ }, "node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001524", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz", - "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==", + "version": "1.0.30001576", "dev": true, "funding": [ { @@ -4302,38 +3787,55 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/capital-case": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", - "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", "dev": true, + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/chai": { + "version": "4.4.0", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" } }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/change-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", - "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", "dev": true, + "license": "MIT", "dependencies": { "camel-case": "^4.1.2", "capital-case": "^1.0.4", @@ -4351,9 +3853,8 @@ }, "node_modules/change-case-all": { "version": "1.0.15", - "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", - "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dev": true, + "license": "MIT", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", @@ -4369,29 +3870,36 @@ }, "node_modules/chardet": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/check-error": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } }, "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "license": "MIT" }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -4400,10 +3908,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "version": "2.9.2", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -4413,9 +3920,8 @@ }, "node_modules/cli-truncate": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -4429,65 +3935,29 @@ }, "node_modules/cli-width": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, + "license": "ISC", "engines": { "node": ">= 10" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/cliui": { + "version": "8.0.1", "dev": true, + "license": "ISC", "dependencies": { - "color-name": "~1.1.4" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" } }, - "node_modules/cliui/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4502,54 +3972,61 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "version": "1.1.4", + "dev": true, + "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/common-tags": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0.0" } }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/constant-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", - "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", "dev": true, + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -4557,20 +4034,18 @@ } }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "version": "2.0.0", + "dev": true, + "license": "MIT" }, "node_modules/cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "version": "8.3.6", "dev": true, + "license": "MIT", "dependencies": { - "import-fresh": "^3.2.1", + "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", + "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "engines": { @@ -4578,21 +4053,38 @@ }, "funding": { "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/cross-fetch": { "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } }, + "node_modules/cross-inspect": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4602,34 +4094,64 @@ "node": ">= 8" } }, + "node_modules/css-tree": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssstyle": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } }, "node_modules/dataloader": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", - "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/debounce": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -4644,24 +4166,68 @@ }, "node_modules/decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -4669,12 +4235,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", "dev": true, + "license": "MIT", "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -4685,37 +4264,41 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dependency-graph": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/detect-indent": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, + "license": "Apache-2.0", "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -4723,11 +4306,18 @@ "node": ">=0.10" } }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -4737,9 +4327,8 @@ }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4747,10 +4336,14 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "dev": true, + "license": "MIT" + }, "node_modules/dom-helpers": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -4758,9 +4351,8 @@ }, "node_modules/dot-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -4768,9 +4360,8 @@ }, "node_modules/dotenv": { "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -4779,61 +4370,66 @@ } }, "node_modules/dset": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", - "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==", + "version": "3.1.3", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/earcut": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" + "license": "ISC" }, "node_modules/electron-to-chromium": { - "version": "1.4.504", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.504.tgz", - "integrity": "sha512-cSMwIAd8yUh54VwitVRVvHK66QqHWE39C3DRj8SWiXitEpVSY3wNPD9y1pxQtLIi4w3UdzF9klLsmuPshz09DQ==", - "dev": true + "version": "1.4.629", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "version": "1.22.3", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.5", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", + "hasown": "^2.0.0", "internal-slot": "^1.0.5", "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", @@ -4841,23 +4437,23 @@ "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", "typed-array-buffer": "^1.0.0", "typed-array-byte-length": "^1.0.0", "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" + "which-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -4866,15 +4462,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-iterator-helpers": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz", - "integrity": "sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw==", + "version": "1.0.15", "dev": true, + "license": "MIT", "dependencies": { "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.2", - "define-properties": "^1.2.0", + "define-properties": "^1.2.1", "es-abstract": "^1.22.1", "es-set-tostringtag": "^2.0.1", "function-bind": "^1.1.1", @@ -4884,38 +4498,35 @@ "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", - "iterator.prototype": "^1.1.0", - "safe-array-concat": "^1.0.0" + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" } }, "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.2", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", "dev": true, + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -4930,10 +4541,9 @@ }, "node_modules/esbuild": { "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -4967,27 +4577,27 @@ }, "node_modules/escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5039,9 +4649,8 @@ }, "node_modules/eslint-config-prettier": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", - "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -5051,9 +4660,8 @@ }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -5062,18 +4670,16 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -5088,18 +4694,16 @@ }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import": { "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.findlastindex": "^1.2.2", @@ -5128,18 +4732,16 @@ }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5147,20 +4749,10 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", - "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.7", "aria-query": "^5.1.3", @@ -5186,26 +4778,10 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-react": { "version": "7.33.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", - "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flatmap": "^1.3.1", @@ -5233,9 +4809,8 @@ }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5245,18 +4820,16 @@ }, "node_modules/eslint-plugin-react-refresh": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz", - "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==", "dev": true, + "license": "MIT", "peerDependencies": { "eslint": ">=7" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5265,12 +4838,11 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "version": "2.0.0-next.5", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5281,20 +4853,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-scope": { "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -5308,9 +4870,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5318,72 +4879,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.24.0", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -5394,32 +4893,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/espree": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -5434,9 +4922,8 @@ }, "node_modules/esquery": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -5446,9 +4933,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -5458,26 +4944,100 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" }, @@ -5487,9 +5047,8 @@ }, "node_modules/external-editor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, + "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -5501,9 +5060,8 @@ }, "node_modules/extract-files": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", - "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20 || >= 14.13" }, @@ -5513,21 +5071,18 @@ }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5541,9 +5096,8 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -5553,63 +5107,50 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-querystring": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", - "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "dev": true, + "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "node_modules/fast-url-parser": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", "dev": true, + "license": "MIT", "dependencies": { "punycode": "^1.3.2" } }, - "node_modules/fast-url-parser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, "node_modules/fbjs": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", - "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", "dev": true, + "license": "MIT", "dependencies": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", @@ -5622,15 +5163,13 @@ }, "node_modules/fbjs-css-vars": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", - "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/figures": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -5641,11 +5180,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -5655,9 +5201,8 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5667,9 +5212,8 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -5682,46 +5226,53 @@ } }, "node_modules/flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "version": "3.2.0", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.2.7", + "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true + "version": "3.2.9", + "dev": true, + "license": "ISC" }, "node_modules/for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -5731,16 +5282,17 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -5756,46 +5308,49 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/geojson-vt": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", - "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" + "license": "ISC" }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5803,8 +5358,7 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -5814,9 +5368,8 @@ }, "node_modules/get-symbol-description": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -5830,22 +5383,19 @@ }, "node_modules/get-value": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/gl-matrix": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", - "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" + "license": "MIT" }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5863,9 +5413,8 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -5875,8 +5424,7 @@ }, "node_modules/global-prefix": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "license": "MIT", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -5888,8 +5436,7 @@ }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5899,18 +5446,16 @@ }, "node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globalthis": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.1.3" }, @@ -5923,9 +5468,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -5943,9 +5487,8 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -5955,23 +5498,20 @@ }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/graphql": { "version": "16.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.0.tgz", - "integrity": "sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg==", + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, "node_modules/graphql-config": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-5.0.2.tgz", - "integrity": "sha512-7TPxOrlbiG0JplSZYCyxn2XQtqVhXomEjXUmWJVSS5ET1nPhOJSsIb/WTwqWhcYX6G0RlHXSj9PLtGTKmxLNGg==", + "version": "5.0.3", "dev": true, + "license": "MIT", "dependencies": { "@graphql-tools/graphql-file-loader": "^8.0.0", "@graphql-tools/json-file-loader": "^8.0.0", @@ -6000,9 +5540,8 @@ }, "node_modules/graphql-config/node_modules/minimatch": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", - "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6012,8 +5551,7 @@ }, "node_modules/graphql-request": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-6.1.0.tgz", - "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.2.0", "cross-fetch": "^3.1.5" @@ -6024,9 +5562,8 @@ }, "node_modules/graphql-tag": { "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.1.0" }, @@ -6038,10 +5575,9 @@ } }, "node_modules/graphql-ws": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.14.0.tgz", - "integrity": "sha512-itrUTQZP/TgswR4GSSYuwWUzrE/w5GhbwM2GX3ic2U7aw33jgEsayfIlvaj7/GcIvZgNMzsPTrE5hqPuFUiE5g==", + "version": "5.14.3", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6050,42 +5586,35 @@ } }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "version": "1.0.4", "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/has-bigints": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6093,9 +5622,8 @@ }, "node_modules/has-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6105,9 +5633,8 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6117,9 +5644,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6130,21 +5656,46 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/header-case": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", - "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", "dev": true, + "license": "MIT", "dependencies": { "capital-case": "^1.0.4", "tslib": "^2.0.3" } }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, "node_modules/http-proxy-agent": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -6154,10 +5705,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", - "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", + "version": "7.0.2", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -6166,11 +5716,18 @@ "node": ">= 14" } }, + "node_modules/human-signals": { + "version": "5.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -6180,8 +5737,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -6195,31 +5750,29 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immutable": { "version": "3.7.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", - "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.8.0" } }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6231,11 +5784,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/import-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", - "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.2" }, @@ -6245,27 +5805,24 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6273,20 +5830,17 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "license": "ISC" }, "node_modules/inquirer": { "version": "8.2.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", - "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -6308,84 +5862,13 @@ "node": ">=12.0.0" } }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.6", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -6394,17 +5877,15 @@ }, "node_modules/invariant": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/is-absolute": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, + "license": "MIT", "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" @@ -6413,11 +5894,25 @@ "node": ">=0.10.0" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -6429,15 +5924,13 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-async-function": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6450,9 +5943,8 @@ }, "node_modules/is-bigint": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -6462,9 +5954,8 @@ }, "node_modules/is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6478,9 +5969,8 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6489,12 +5979,11 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.13.1", "dev": true, + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6502,9 +5991,8 @@ }, "node_modules/is-date-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6517,26 +6005,23 @@ }, "node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-finalizationregistry": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6546,18 +6031,16 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-generator-function": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6570,9 +6053,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -6582,36 +6064,32 @@ }, "node_modules/is-interactive": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-lower-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", - "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/is-map": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-negative-zero": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6621,18 +6099,16 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-number-object": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6645,17 +6121,15 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -6663,11 +6137,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6681,9 +6159,8 @@ }, "node_modules/is-relative": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, + "license": "MIT", "dependencies": { "is-unc-path": "^1.0.0" }, @@ -6693,18 +6170,16 @@ }, "node_modules/is-set": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6712,11 +6187,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6729,9 +6214,8 @@ }, "node_modules/is-symbol": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6744,9 +6228,8 @@ }, "node_modules/is-typed-array": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.11" }, @@ -6759,9 +6242,8 @@ }, "node_modules/is-unc-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, + "license": "MIT", "dependencies": { "unc-path-regex": "^0.1.2" }, @@ -6771,9 +6253,8 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6783,27 +6264,24 @@ }, "node_modules/is-upper-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", - "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/is-weakmap": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakref": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6813,9 +6291,8 @@ }, "node_modules/is-weakset": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -6826,82 +6303,118 @@ }, "node_modules/is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isomorphic-ws": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", "dev": true, - "peerDependencies": { - "ws": "*" + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/iterator.prototype": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.0.tgz", - "integrity": "sha512-rjuhAk1AJ1fssphHD0IFV6TWL40CwRZ53FrztKx43yk2v6rguBYsY4Bj1VU4HmoMmKwZUlx7mfnhDf9cOp4YTw==", + "version": "1.1.2", "dev": true, + "license": "MIT", "dependencies": { - "define-properties": "^1.1.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", - "has-tostringtag": "^1.0.0", - "reflect.getprototypeof": "^1.0.3" + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" } }, "node_modules/jiti": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz", - "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==", + "version": "1.21.0", "dev": true, + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } }, "node_modules/jose": { - "version": "4.14.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", - "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==", + "version": "5.2.0", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6909,11 +6422,49 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "23.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/dom-selector": "^2.0.1", + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.16.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -6923,29 +6474,31 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", - "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", + "version": "1.1.0", "dev": true, + "license": "MIT", "dependencies": { - "jsonify": "^0.0.1" + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6953,20 +6506,17 @@ }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stringify-pretty-compact": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", - "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==" + "license": "MIT" }, "node_modules/json-to-pretty-yaml": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz", - "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "remedial": "^1.0.7", "remove-trailing-spaces": "^1.0.6" @@ -6977,9 +6527,8 @@ }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -6987,20 +6536,23 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "dev": true, + "license": "MIT" + }, "node_modules/jsonify": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", "dev": true, + "license": "Public Domain", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/jsx-ast-utils": { "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -7013,46 +6565,40 @@ }, "node_modules/kdbush": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", - "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" + "license": "ISC" }, "node_modules/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "version": "4.5.4", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/language-subtag-registry": { "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/language-tags": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "dev": true, + "license": "MIT", "dependencies": { "language-subtag-registry": "~0.3.2" } }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7063,15 +6609,13 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/listr2": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -7094,61 +6638,41 @@ } } }, - "node_modules/listr2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "7.0.0", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/listr2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/listr2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/local-pkg": { + "version": "0.5.0", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/antfu" } }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -7161,27 +6685,23 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.sortby": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -7193,187 +6713,158 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/log-update": { + "version": "4.0.0", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "js-tokens": "^3.0.0 || ^4.0.0" }, - "engines": { - "node": ">=7.0.0" + "bin": { + "loose-envify": "cli.js" } }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/loupe": { + "version": "2.3.7", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" } }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/lower-case": { + "version": "2.0.2", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "tslib": "^2.0.3" } }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "node_modules/lower-case-first": { + "version": "2.0.2", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "tslib": "^2.0.3" } }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/lru-cache": { + "version": "5.1.1", "dev": true, + "license": "ISC", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "yallist": "^3.0.2" } }, - "node_modules/log-update/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/lz-string": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.5", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" } }, - "node_modules/log-update/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/magicast": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "source-map-js": "^1.0.2" + } }, - "node_modules/log-update/node_modules/slice-ansi": { + "node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "semver": "^7.5.3" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "node_modules/make-dir/node_modules/lru-cache": { + "version": "6.0.0", "dev": true, + "license": "ISC", "dependencies": { - "tslib": "^2.0.3" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/lower-case-first": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", - "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", + "node_modules/make-dir/node_modules/semver": { + "version": "7.5.4", "dev": true, + "license": "ISC", "dependencies": { - "tslib": "^2.0.3" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/make-dir/node_modules/yallist": { + "version": "4.0.0", "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } + "license": "ISC" }, "node_modules/map-cache": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7417,20 +6908,28 @@ "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" } }, + "node_modules/mdn-data": { + "version": "2.0.30", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/meros": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz", - "integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=13" }, @@ -7445,9 +6944,8 @@ }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -7456,20 +6954,37 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7479,33 +6994,38 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mlly": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/murmurhash-js": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", - "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" + "license": "MIT" }, "node_modules/mute-stream": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", "dev": true, "funding": [ { @@ -7513,6 +7033,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7522,15 +7043,13 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/no-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, + "license": "MIT", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" @@ -7538,14 +7057,12 @@ }, "node_modules/node-addon-api": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", - "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7561,70 +7078,118 @@ } } }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "version": "2.0.14", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, + "license": "MIT", "dependencies": { "remove-trailing-separator": "^1.0.1" }, - "engines": { - "node": ">=0.10.0" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/nullthrows": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -7637,9 +7202,8 @@ }, "node_modules/object.entries": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7651,9 +7215,8 @@ }, "node_modules/object.fromentries": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7668,9 +7231,8 @@ }, "node_modules/object.groupby": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7680,9 +7242,8 @@ }, "node_modules/object.hasown": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.0", "es-abstract": "^1.22.1" @@ -7693,9 +7254,8 @@ }, "node_modules/object.values": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7710,18 +7270,16 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -7734,9 +7292,8 @@ }, "node_modules/optionator": { "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, + "license": "MIT", "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -7751,9 +7308,8 @@ }, "node_modules/ora": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -7772,90 +7328,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ora/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7868,9 +7352,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -7883,9 +7366,8 @@ }, "node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -7898,18 +7380,16 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/param-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -7917,9 +7397,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -7929,9 +7408,8 @@ }, "node_modules/parse-filepath": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dev": true, + "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", @@ -7943,9 +7421,8 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -7959,11 +7436,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/pascal-case": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dev": true, + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -7971,9 +7458,8 @@ }, "node_modules/path-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", - "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "dev": true, + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -7981,42 +7467,37 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-root": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dev": true, + "license": "MIT", "dependencies": { "path-root-regex": "^0.1.0" }, @@ -8026,26 +7507,36 @@ }, "node_modules/path-root-regex": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/pbf": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "license": "BSD-3-Clause", "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" @@ -8056,15 +7547,13 @@ }, "node_modules/picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -8072,10 +7561,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-types": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, "node_modules/postcss": { - "version": "8.4.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", - "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", + "version": "8.4.33", "dev": true, "funding": [ { @@ -8091,8 +7588,9 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -8102,23 +7600,20 @@ }, "node_modules/potpack": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", - "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==" + "license": "ISC" }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -8129,19 +7624,41 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/promise": { "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, + "license": "MIT", "dependencies": { "asap": "~2.0.3" } }, "node_modules/prop-types": { "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8150,8 +7667,7 @@ }, "node_modules/prop-types-extra": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "license": "MIT", "dependencies": { "react-is": "^16.3.2", "warning": "^4.0.0" @@ -8160,42 +7676,51 @@ "react": ">=0.14.0" } }, + "node_modules/prop-types-extra/node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", - "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.9.0", + "dev": true, + "license": "MIT" }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "1.4.1", "dev": true, - "engines": { - "node": ">=6" - } + "license": "MIT" }, "node_modules/pvtsutils": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", - "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.6.1" } }, "node_modules/pvutils": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", - "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -8210,17 +7735,16 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/quickselect": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + "license": "ISC" }, "node_modules/react": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -8230,8 +7754,7 @@ }, "node_modules/react-bootstrap": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", - "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.21.0", "@restart/hooks": "^0.4.9", @@ -8259,8 +7782,7 @@ }, "node_modules/react-dom": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -8270,19 +7792,17 @@ } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "version": "17.0.2", + "dev": true, + "license": "MIT" }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + "license": "MIT" }, "node_modules/react-map-gl": { "version": "7.1.5", - "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-7.1.5.tgz", - "integrity": "sha512-YS2u2cSLlZVGjfa394f0snO6f6ZwZVTKqQwjbq/jj0w7fHU01Mn+Xqvm/Qr7nZChoT3OG7kh8JluDcXeBrDG/g==", + "license": "MIT", "dependencies": { "@maplibre/maplibre-gl-style-spec": "^19.2.1", "@types/mapbox-gl": ">=1.0.0" @@ -8304,17 +7824,15 @@ }, "node_modules/react-refresh": { "version": "0.14.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", - "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-transition-group": { "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -8328,9 +7846,8 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -8341,15 +7858,14 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.3.tgz", - "integrity": "sha512-TTAOZpkJ2YLxl7mVHWrNo3iDMEkYlva/kgFcXndqMgbo/AZUmmavEkdXV+hXtE4P8xdyEKRzalaFqZVuwIk/Nw==", + "version": "1.0.4", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" }, @@ -8361,19 +7877,17 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + "version": "0.14.1", + "license": "MIT" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -8384,9 +7898,8 @@ }, "node_modules/relay-runtime": { "version": "12.0.0", - "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", - "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.0.0", "fbjs": "^3.0.0", @@ -8395,45 +7908,52 @@ }, "node_modules/remedial": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", - "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", "dev": true, + "license": "(MIT OR Apache-2.0)", "engines": { "node": "*" } }, "node_modules/remove-trailing-separator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/remove-trailing-spaces": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz", - "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.8", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -8447,27 +7967,24 @@ } }, "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "version": "5.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/resolve-protobuf-schema": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", - "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "license": "MIT", "dependencies": { "protocol-buffers-schema": "^3.3.1" } }, "node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -8478,9 +7995,8 @@ }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -8488,15 +8004,13 @@ }, "node_modules/rfdc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -8508,10 +8022,9 @@ } }, "node_modules/rollup": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", - "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "version": "3.29.4", "dev": true, + "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -8523,19 +8036,21 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "dev": true, + "license": "MIT" + }, "node_modules/run-async": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -8551,32 +8066,30 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rw": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "license": "BSD-3-Clause" }, "node_modules/rxjs": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "version": "1.0.1", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", + "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -8589,8 +8102,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -8605,80 +8116,65 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.2", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } }, "node_modules/scheduler": { "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/scuid": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", - "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "6.3.1", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" } }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/sentence-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", - "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", "dev": true, + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -8687,14 +8183,39 @@ }, "node_modules/set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/set-value": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -8707,15 +8228,13 @@ }, "node_modules/setimmediate": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -8725,27 +8244,24 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -8755,32 +8271,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/signedsource": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", - "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -8790,44 +8307,10 @@ "node": ">=8" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/snake-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "dev": true, + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -8835,24 +8318,21 @@ }, "node_modules/sort-asc": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", - "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/sort-desc": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", - "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/sort-object": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", - "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", + "license": "MIT", "dependencies": { "bytewise": "^1.1.0", "get-value": "^2.0.2", @@ -8865,19 +8345,25 @@ "node": ">=0.10.0" } }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/split-string": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "license": "MIT", "dependencies": { "extend-shallow": "^3.0.0" }, @@ -8887,8 +8373,7 @@ }, "node_modules/split-string/node_modules/extend-shallow": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -8899,8 +8384,7 @@ }, "node_modules/split-string/node_modules/is-extendable": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -8910,17 +8394,35 @@ }, "node_modules/sponge-case": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", - "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, + "node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -8928,24 +8430,21 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string-env-interpolation": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz", - "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8955,11 +8454,15 @@ "node": ">=8" } }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, "node_modules/string.prototype.matchall": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.9.tgz", - "integrity": "sha512-6i5hL3MqG/K2G43mWXWgP+qizFW/QH/7kCNN13JrJS5q48FN5IKksLDscexKP3dnmB6cdm9jlNgAsWNLpSykmA==", + "version": "4.0.10", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -8968,6 +8471,7 @@ "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", "side-channel": "^1.0.4" }, "funding": { @@ -8975,14 +8479,13 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "version": "1.2.8", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -8992,28 +8495,26 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.7", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.7", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9021,9 +8522,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9033,18 +8533,27 @@ }, "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -9052,31 +8561,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/supercluster": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", - "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", "dependencies": { "kdbush": "^4.0.2" } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9086,44 +8603,77 @@ }, "node_modules/swap-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", - "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.5.1", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "0.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/tinyqueue": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", - "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" + "license": "ISC" + }, + "node_modules/tinyspy": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/title-case": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", - "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/tmp": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, + "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -9133,18 +8683,16 @@ }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -9152,16 +8700,51 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tr46/node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, "node_modules/ts-api-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", - "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", + "version": "1.0.3", "dev": true, + "license": "MIT", "engines": { "node": ">=16.13.0" }, @@ -9171,15 +8754,13 @@ }, "node_modules/ts-log": { "version": "2.2.5", - "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", - "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "version": "3.15.0", "dev": true, + "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -9189,9 +8770,8 @@ }, "node_modules/tsconfig-paths/node_modules/json5": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -9201,14 +8781,12 @@ }, "node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -9216,11 +8794,18 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.21.3", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -9230,9 +8815,8 @@ }, "node_modules/typed-array-buffer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -9244,9 +8828,8 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -9262,9 +8845,8 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -9281,9 +8863,8 @@ }, "node_modules/typed-array-length": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -9295,9 +8876,8 @@ }, "node_modules/typescript": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9308,21 +8888,17 @@ }, "node_modules/typewise": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", - "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", + "license": "MIT", "dependencies": { "typewise-core": "^1.2.0" } }, "node_modules/typewise-core": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==" + "license": "MIT" }, "node_modules/ua-parser-js": { - "version": "1.0.35", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", - "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", + "version": "1.0.37", "dev": true, "funding": [ { @@ -9332,17 +8908,26 @@ { "type": "paypal", "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } ], + "license": "MIT", "engines": { "node": "*" } }, + "node_modules/ufo": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, "node_modules/unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -9355,17 +8940,15 @@ }, "node_modules/unc-path-regex": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/uncontrollable": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.6.3", "@types/react": ">=16.9.11", @@ -9376,10 +8959,14 @@ "react": ">=15.0.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, "node_modules/union-value": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "license": "MIT", "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -9390,120 +8977,509 @@ "node": ">=0.10.0" } }, - "node_modules/unixify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", - "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", + "node_modules/universalify": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unixify": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "normalize-path": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/value-or-promise": { + "version": "1.0.12", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/vite": { + "version": "4.4.9", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.1.3", "dev": true, + "license": "MIT", "dependencies": { - "normalize-path": "^2.1.1" + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=0.10.0" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.19.11", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, + "node_modules/vite-node/node_modules/rollup": { + "version": "4.9.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" }, "bin": { - "update-browserslist-db": "cli.js" + "rollup": "dist/bin/rollup" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.9.5", + "@rollup/rollup-android-arm64": "4.9.5", + "@rollup/rollup-darwin-arm64": "4.9.5", + "@rollup/rollup-darwin-x64": "4.9.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.5", + "@rollup/rollup-linux-arm64-gnu": "4.9.5", + "@rollup/rollup-linux-arm64-musl": "4.9.5", + "@rollup/rollup-linux-riscv64-gnu": "4.9.5", + "@rollup/rollup-linux-x64-gnu": "4.9.5", + "@rollup/rollup-linux-x64-musl": "4.9.5", + "@rollup/rollup-win32-arm64-msvc": "4.9.5", + "@rollup/rollup-win32-ia32-msvc": "4.9.5", + "@rollup/rollup-win32-x64-msvc": "4.9.5", + "fsevents": "~2.3.2" } }, - "node_modules/upper-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", - "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "node_modules/vite-node/node_modules/vite": { + "version": "5.0.11", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.0.3" + "esbuild": "^0.19.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, - "node_modules/upper-case-first": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", - "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "node_modules/vitest": { + "version": "1.1.3", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.0.3" + "@vitest/expect": "1.1.3", + "@vitest/runner": "1.1.3", + "@vitest/snapshot": "1.1.3", + "@vitest/spy": "1.1.3", + "@vitest/utils": "1.1.3", + "acorn-walk": "^8.3.1", + "cac": "^6.7.14", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^1.3.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.1", + "vite": "^5.0.0", + "vite-node": "1.1.3", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "^1.0.0", + "@vitest/ui": "^1.0.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/urlpattern-polyfill": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", - "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", - "dev": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/value-or-promise": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", - "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "node_modules/vitest/node_modules/esbuild": { + "version": "0.19.11", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" + } + }, + "node_modules/vitest/node_modules/rollup": { + "version": "4.9.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.9.5", + "@rollup/rollup-android-arm64": "4.9.5", + "@rollup/rollup-darwin-arm64": "4.9.5", + "@rollup/rollup-darwin-x64": "4.9.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.5", + "@rollup/rollup-linux-arm64-gnu": "4.9.5", + "@rollup/rollup-linux-arm64-musl": "4.9.5", + "@rollup/rollup-linux-riscv64-gnu": "4.9.5", + "@rollup/rollup-linux-x64-gnu": "4.9.5", + "@rollup/rollup-linux-x64-musl": "4.9.5", + "@rollup/rollup-win32-arm64-msvc": "4.9.5", + "@rollup/rollup-win32-ia32-msvc": "4.9.5", + "@rollup/rollup-win32-x64-msvc": "4.9.5", + "fsevents": "~2.3.2" } }, - "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "node_modules/vitest/node_modules/vite": { + "version": "5.0.11", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.19.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", @@ -9537,45 +9513,51 @@ }, "node_modules/vt-pbf": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", - "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "license": "MIT", "dependencies": { "@mapbox/point-geometry": "0.1.0", "@mapbox/vector-tile": "^1.3.1", "pbf": "^3.2.1" } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/warning": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "version": "3.3.2", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/webcrypto-core": { "version": "1.7.7", - "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", - "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", "dev": true, + "license": "MIT", "dependencies": { "@peculiar/asn1-schema": "^2.3.6", "@peculiar/json-schema": "^1.1.12", @@ -9585,24 +9567,59 @@ } }, "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "version": "14.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -9615,9 +9632,8 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -9631,9 +9647,8 @@ }, "node_modules/which-builtin-type": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", "dev": true, + "license": "MIT", "dependencies": { "function.prototype.name": "^1.1.5", "has-tostringtag": "^1.0.0", @@ -9657,9 +9672,8 @@ }, "node_modules/which-collection": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "dev": true, + "license": "MIT", "dependencies": { "is-map": "^2.0.1", "is-set": "^2.0.1", @@ -9672,18 +9686,16 @@ }, "node_modules/which-module": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "version": "1.1.13", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" @@ -9695,64 +9707,43 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/why-is-node-running": { + "version": "2.2.2", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "siginfo": "^2.0.0", + "stackback": "0.0.2" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" + "bin": { + "why-is-node-running": "cli.js" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/wrap-ansi": { + "version": "6.2.0", "dev": true, + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" } }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.16.0", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -9769,41 +9760,49 @@ } } }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "version": "2.3.4", "dev": true, + "license": "ISC", "engines": { "node": ">= 14" } }, "node_modules/yaml-ast-parser": { "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9819,18 +9818,16 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/client-next/package.json b/client-next/package.json index 6388122befc..3f8f303cc79 100644 --- a/client-next/package.json +++ b/client-next/package.json @@ -6,6 +6,8 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", + "test": "vitest --root src/", + "coverage": "vitest run --root src/ --coverage", "lint": "eslint . --report-unused-disable-directives --max-warnings 0", "check-format": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\"", @@ -30,11 +32,13 @@ "@graphql-codegen/client-preset": "4.1.0", "@graphql-codegen/introspection": "4.0.0", "@parcel/watcher": "2.3.0", + "@testing-library/react": "14.1.2", "@types/react": "18.2.21", "@types/react-dom": "18.2.7", "@typescript-eslint/eslint-plugin": "6.5.0", "@typescript-eslint/parser": "6.5.0", "@vitejs/plugin-react": "4.0.4", + "@vitest/coverage-v8": "1.1.3", "eslint": "8.48.0", "eslint-config-prettier": "9.0.0", "eslint-plugin-import": "2.28.1", @@ -42,8 +46,10 @@ "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.3", + "jsdom": "23.2.0", "prettier": "3.0.3", "typescript": "5.2.2", - "vite": "4.4.9" + "vite": "4.4.9", + "vitest": "1.1.3" } } diff --git a/client-next/src/components/ItineraryList/ItineraryList.test.tsx b/client-next/src/components/ItineraryList/ItineraryList.test.tsx new file mode 100644 index 00000000000..d1d13b36bf3 --- /dev/null +++ b/client-next/src/components/ItineraryList/ItineraryList.test.tsx @@ -0,0 +1,2394 @@ +import { it } from 'vitest'; +import { ItineraryListContainer } from './ItineraryListContainer'; +import { render } from '@testing-library/react'; +import { QueryType } from '../../gql/graphql.ts'; + +const tripQueryResult = { + trip: { + previousPageCursor: + 'MXxQUkVWSU9VU19QQUdFfDIwMjQtMDEtMTJUMTA6MzI6MThafHwxaHxTVFJFRVRfQU5EX0FSUklWQUxfVElNRXxmYWxzZXwyMDI0LTAxLTEyVDExOjQxOjAwWnwyMDI0LTAxLTEyVDEzOjE4OjUwWnwzfDExMTM0fA==', + nextPageCursor: + 'MXxORVhUX1BBR0V8MjAyNC0wMS0xMlQxMTozOTowN1p8fDFofFNUUkVFVF9BTkRfQVJSSVZBTF9USU1FfGZhbHNlfDIwMjQtMDEtMTJUMTE6NDE6MDBafDIwMjQtMDEtMTJUMTM6MTg6NTBafDN8MTExMzR8', + tripPatterns: [ + { + aimedStartTime: '2024-01-12T12:39:07+01:00', + aimedEndTime: '2024-01-12T13:54:09+01:00', + expectedEndTime: '2024-01-12T13:54:09+01:00', + expectedStartTime: '2024-01-12T12:39:07+01:00', + duration: 4502, + distance: 26616.219999999998, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:39:07+01:00', + aimedEndTime: '2024-01-12T12:50:00+01:00', + expectedEndTime: '2024-01-12T12:50:00+01:00', + expectedStartTime: '2024-01-12T12:39:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAB0AAAAmABBSQjpOU1I6UXVheTo3OTQ0ABFSQjpOU1I6UXVheToxMTk2OQA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6ODIyMzhhN2VmZmNhMzY2YzAwZmNkYmJjMWU2MWQ2N2E=', + mode: 'bus', + aimedStartTime: '2024-01-12T12:50:00+01:00', + aimedEndTime: '2024-01-12T13:13:00+01:00', + expectedEndTime: '2024-01-12T13:13:00+01:00', + expectedStartTime: '2024-01-12T12:50:00+01:00', + realtime: true, + distance: 17846.09, + duration: 1380, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA??EMIU]{@MYKOMOEIIKIGAK?GCGCGGIECM?GIEIGOWy@EKEKCGIKCCCCOQCCAA[a@QSQU_@c@QU[_@i@o@KMCEOQIKkAyAMQY]KMAAAAACKKCEcAmAUU?M?IAOGyGAg@AQHQDK`AuBx@gB@Eh@cAh@gA??`@y@JSHSHWFOHWJ_@Lg@Pw@Lu@H_@De@Dg@Ba@@s@?s@Eq@GuAEs@MsBGqAEm@E}@C}@AcBAgA?e@?]?Q?U@_@@k@HoANiAT}B@SHu@F]D[J_@H[j@uBBK@EDOFe@@EDYH[VaAJ]@CFODIFG`AwAZa@??@AHKLOFC?A@?DA@?FA@?B?H@??D@F@NBF?D?FADCFCHGl@m@\\[LOFGFEBEDCDE@APMFChC_ALCNEDDB@F?BADEBIBK@OAOJy@VwCBWL_BD[DEBI@I?IAKB]Fi@JsAD{@HiALoAJ_AFg@@G??LeBLyANkBBSBQHk@BEBG@I?I?G?IAGCIACCAECA?C?C@C@ADCDAHAH?H?H@HBF?F?NAL?RMRILEHABINATKhAIbAIbAO`BALE`@ABGt@KlAKvAAL', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:13:00+01:00', + aimedEndTime: '2024-01-12T13:16:42+01:00', + expectedEndTime: '2024-01-12T13:16:42+01:00', + expectedStartTime: '2024-01-12T13:13:00+01:00', + realtime: false, + distance: 213.19, + duration: 222, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'sptlJm|s`A??LoAB[@EPqB@MBa@JD@@FQ??D@HDJsA@@B@DBB@DBDB@@Fu@LwAHwA??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAANABFSQjpOU1I6UXVheToxMTk2MAARUkI6TlNSOlF1YXk6MTE0NDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmY0M2E3ZDUxNmY5ZDljMzUyMDFlYzU2ZDk4NjM5M2Jh', + mode: 'bus', + aimedStartTime: '2024-01-12T13:20:00+01:00', + aimedEndTime: '2024-01-12T13:39:00+01:00', + expectedEndTime: '2024-01-12T13:39:00+01:00', + expectedStartTime: '2024-01-12T13:20:00+01:00', + realtime: false, + distance: 6755.19, + duration: 1140, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Alfaset', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Kjeller', + }, + }, + line: { + publicCode: '100', + name: 'Kjeller - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '}ktlJynt`ADi@BQBSBQHk@BEBG@I?I?G?IAG@QBQBKH_@Ji@BNBN?DDUBGJm@BM?ARy@d@{Bt@mDZ{ANo@H[@E`@oBt@mDFUBM?CJe@DSFU@KHc@?GDe@Nq@TgAj@mC@A@KBMFa@x@wE@E??F_@l@iDXcB`@eCV_BDYV_@BE??LUBM?OOaBBa@VuC`@}D@KZwCb@iEZgDFk@BUKa@CKGWWqAe@{BOu@EMIc@C_@G[YwAAGM[EQI]EQMm@ScAG[Mq@??OaAKo@Ik@Is@Io@MqAQ_BC]YeCs@}GEi@Gi@KeAEY??E[Iu@Gc@Ga@G]Ic@Kc@i@aCa@aBMk@Kc@[sAIa@Kc@S_A?C??I[C_@AKAa@?W@G@E?GHSBMFYN_@Rm@FUDUBOBQ@O@Q@O?MD]@g@?_@BG@I@KAIAICIEEEAE?EDADADO?I?E?C?E@C@CBEFCBCDSd@EHEFCDEDCBE@E@A@C?I?EAIEECs@q@Uw@WcAe@qBeD_OS{ASgAOiAEy@Ca@?U?O@I@G?IAKCICECCCAA?C?CBEIKUKc@COG[Ge@OkAEU??AIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGBUGk@Ce@Ao@Ao@AWA[AQC]CWIe@COOgAMo@OaAGWcA}FCMUgA??AESaASu@WaA[gAUu@]cAWy@W{@K]wAsEIYKWMa@Qo@K_@I[CIAMCKAQ@M?Q@Y@QA]KKEGEEEIEOM_@AOK_AKaAIw@Ek@??CSGgAEy@Cs@AaAAs@Ay@As@?q@@yA@gDBsD@wD@_C?oDByD?_@@iB@gB@i@@m@@[@Y?EHg@@U@A@E@E?EAEAEACAAA?A?IIECGCOBG?C?[@[BYB_@FSDy@J??C@OBSEE?KAI?AEACCEEACAC@A@KIGKEGUa@KYQ_@o@oAeAuBiAyBS[MW]o@Wc@[c@[c@i@q@EG??c@i@[_@[]s@w@GIIIYc@EIGKIMGMAAAKAGCEEEEAC@A@KIGEEGQOYk@]s@[w@Um@Sk@IYIUESIYEWGYEYEWE_@Ge@Gk@Ec@C]C_@C_@A]GcBC_@A[Ca@EWCWE]G[G]Qy@Qy@e@yBS_AMq@GSCOEQCMKe@S_AAC', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:39:00+01:00', + aimedEndTime: '2024-01-12T13:54:09+01:00', + expectedEndTime: '2024-01-12T13:54:09+01:00', + expectedStartTime: '2024-01-12T13:39:00+01:00', + realtime: false, + distance: 1074.54, + duration: 909, + fromPlace: { + name: 'Alfaset', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'egxlJeigaA@A?BRz@DZA@ILEDA@}@aEAECIACCGAE?IUiA?CAEMaA_Br@KBI?GBGHKNW^w@jA]f@ORSRQLMHMBAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:39:07+01:00', + aimedEndTime: '2024-01-12T14:03:50+01:00', + expectedEndTime: '2024-01-12T14:03:50+01:00', + expectedStartTime: '2024-01-12T12:39:07+01:00', + duration: 5083, + distance: 30479.82, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:39:07+01:00', + aimedEndTime: '2024-01-12T12:50:00+01:00', + expectedEndTime: '2024-01-12T12:50:00+01:00', + expectedStartTime: '2024-01-12T12:39:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAB0AAAAmABBSQjpOU1I6UXVheTo3OTQ0ABFSQjpOU1I6UXVheToxMTk2OQA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6ODIyMzhhN2VmZmNhMzY2YzAwZmNkYmJjMWU2MWQ2N2E=', + mode: 'bus', + aimedStartTime: '2024-01-12T12:50:00+01:00', + aimedEndTime: '2024-01-12T13:13:00+01:00', + expectedEndTime: '2024-01-12T13:13:00+01:00', + expectedStartTime: '2024-01-12T12:50:00+01:00', + realtime: true, + distance: 17846.09, + duration: 1380, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA??EMIU]{@MYKOMOEIIKIGAK?GCGCGGIECM?GIEIGOWy@EKEKCGIKCCCCOQCCAA[a@QSQU_@c@QU[_@i@o@KMCEOQIKkAyAMQY]KMAAAAACKKCEcAmAUU?M?IAOGyGAg@AQHQDK`AuBx@gB@Eh@cAh@gA??`@y@JSHSHWFOHWJ_@Lg@Pw@Lu@H_@De@Dg@Ba@@s@?s@Eq@GuAEs@MsBGqAEm@E}@C}@AcBAgA?e@?]?Q?U@_@@k@HoANiAT}B@SHu@F]D[J_@H[j@uBBK@EDOFe@@EDYH[VaAJ]@CFODIFG`AwAZa@??@AHKLOFC?A@?DA@?FA@?B?H@??D@F@NBF?D?FADCFCHGl@m@\\[LOFGFEBEDCDE@APMFChC_ALCNEDDB@F?BADEBIBK@OAOJy@VwCBWL_BD[DEBI@I?IAKB]Fi@JsAD{@HiALoAJ_AFg@@G??LeBLyANkBBSBQHk@BEBG@I?I?G?IAGCIACCAECA?C?C@C@ADCDAHAH?H?H@HBF?F?NAL?RMRILEHABINATKhAIbAIbAO`BALE`@ABGt@KlAKvAAL', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:13:00+01:00', + aimedEndTime: '2024-01-12T13:13:39+01:00', + expectedEndTime: '2024-01-12T13:13:39+01:00', + expectedStartTime: '2024-01-12T13:13:00+01:00', + realtime: false, + distance: 30.41, + duration: 39, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'sptlJm|s`A@@@SAAGCGC?ACACACA@W@K', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAANABFSQjpOU1I6UXVheToxMTk3OQARUkI6TlNSOlF1YXk6MTA2NDMAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjY3YzVkMTllZmMyOWI1MDdmMzkxYmYzY2Q3NDRiZDY1', + mode: 'bus', + aimedStartTime: '2024-01-12T13:25:00+01:00', + aimedEndTime: '2024-01-12T13:44:00+01:00', + expectedEndTime: '2024-01-12T13:44:00+01:00', + expectedStartTime: '2024-01-12T13:25:00+01:00', + realtime: false, + distance: 8619.48, + duration: 1140, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Rødtvet T', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Hellerudhaugen', + }, + }, + line: { + publicCode: '390', + name: 'Kongskog/Hellerudhaugen - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'qqtlJu~s`A??Be@AKIMCWJwA@UBUBW@SBWBW@WBU@UBUBW@WBU@I@M@UBUBW@UBUDE^W@AZUNDH@D?@?D?FAB?BABBB@B?@?BABCBEBG@I?I?G?IAGCIACCAECA?C?C@C@ADGAE?MEc@UEAGAIBIFGBC@EDEDEHCLENCLCTYpDSfCId@ENELELGJEBCFKAI?KCGCIEKIYUWSmBaB_BuA]YYYSSY[QSGGOQEE??EEKMACEIEIKSAKCIEGECEAGKCGGKGQI]K[W_AyAiFGUQo@_@wAc@cBKUIUEOEOE_@I]Su@Wo@GSCMCOEW]sAQ_@CICMIY_AjAI@G?EACAECIGW_@cAiBqCeF}C}FOe@EIGIIOGIEGKOSO{BoCKWGKSYMKGEKISK{@gAGIGO??KSIOGKIOOUGK]]IOyAwC_@s@mAcCMc@GQEI_AgBGKCGIQEIAIAOAOAK?IAC?I?Wc@G{AKyBQIAWAOCYIIAiAIMCCAEC@]AKAGACACG?YCC?C@ABADAB?BIKIGKKc@[MK??m@c@[UIIQKYUeAq@eAm@YOYQYOIEKCEAICKAMAyEe@[EgAKm@G??[C_@EoAKg@Cm@CoAK_@Ce@E]CWCWEMAIAGCAEAIAIAIEIEIEEEEGAE@G@EBCBCFQEg@UiAo@gAk@}@q@SQa@a@UUm@y@_@q@g@aAEGo@yBs@{BIS??IS_@iAyAkEw@}BG[Ie@?OAQCOEUIQIOKGGCI?A?S[OYK[m@iBWu@??Ma@_@oAY}@q@sBm@cDSoAUsAWaBQiAYqBYsBK{BQ{AUcCCu@C}@Gs@MqAUeBYqCQgBSkBGk@??AIGm@QkAGa@a@qB{@{IyBeTUaCMyAY_DIiDCaBI}CIyCCyA?k@?_@@c@Fo@@C@E?E?I?ICGAEECAAC?C?EEGKK[I_@OiAKw@OiA??SeBs@{DqAgKgAiIk@qEKq@??Ge@MiAI{@GcAE}@CaAA{@AcA@cAB}@BmAHgAJkANsAJu@N_AVgA~@mDXgAR{@Lo@PmALkAHiAFeABoA@oA?yAAoAAo@C_@??A]KoBK}AMaBWyBi@aFIy@Iw@IcAG{AGuACcBByB?}B?cA??AcAEyCGoBI_BCi@AQIw@SeBQkAO{@SeA[sAu@{FeB}Mm@mEUmBGc@??c@gD_@sCQcAMs@WkAQu@Sy@y@sCcAwDcCaJi@kBUu@Sq@Wm@Wi@We@U]_@e@[]a@g@Y]W]SWUa@S_@Q]Qe@Wq@So@Qo@Og@Ou@Os@O_AMs@K{@KaAIu@IaAGkAEy@C}@GqA', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:44:00+01:00', + aimedEndTime: '2024-01-12T13:49:09+01:00', + expectedEndTime: '2024-01-12T13:49:09+01:00', + expectedStartTime: '2024-01-12T13:44:00+01:00', + realtime: false, + distance: 367.92, + duration: 309, + fromPlace: { + name: 'Rødtvet T', + }, + toPlace: { + name: 'Kalbakkstubben', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'cd|lJ}ghaA??DWGw@Cm@Co@MsDAs@?m@AcA?e@Ci@Cs@E}@GaAGo@Ei@K{@SgBAQ@IBIDKFEFAJ?D?N@J@d@F??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAMAAAAIABFSQjpOU1I6UXVheToxMDY2OAARUkI6TlNSOlF1YXk6MTAyNTkAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmQ5OTFhMTk1NGQzYjkyNjRhMTk5ZGY1OTA5YTBlMmE5', + mode: 'bus', + aimedStartTime: '2024-01-12T13:55:00+01:00', + aimedEndTime: '2024-01-12T13:59:00+01:00', + expectedEndTime: '2024-01-12T13:59:00+01:00', + expectedStartTime: '2024-01-12T13:55:00+01:00', + realtime: false, + distance: 2578.69, + duration: 240, + fromPlace: { + name: 'Kalbakkstubben', + }, + toPlace: { + name: 'Postnord', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Helsfyr', + }, + }, + line: { + publicCode: '68', + name: 'Helsfyr T - Grorud T via Alfaset', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'sc|lJijiaA@?HBPNHBHBDBFBJBDBFBXDHFf@b@JLHHNPTXRZXd@`@r@^l@`@r@T`@PXPVTXNRVTZTVPTLZLXJVFVDVDz@JNBx@H^DRHH@l@B??J@X@RBH?LBHBT@`@TVN\\VVRXVTTLNNPX`@\\f@T`@Zn@Rd@lCnGR`@P^PZR\\PVJLNPNN??B@LLFDNF\\JXRFBFBFDDHDFLR?FBD@DBDD@DABC@C`@[TIH@ZErAL|@Jp@FlAHh@BH@RJHFHHJLDJBFFFD@FADCDEDKBKHIHGHCNMF?PARANANAPCd@Ib@Gh@K^Il@@PCjA[TG??`A[JALCH?RBBDBBBVBT@HBPDb@?TBbABlBFvBBf@Fr@Dh@Ht@Jr@Np@Lj@Nd@N`@Rb@Td@PZh@x@NP~@nAzAjBHLVZRVNVI\\Sd@Q^GN??KTcApBmA`CIPKREREX@XBXDPdAxCJ\\l@bB', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:59:00+01:00', + aimedEndTime: '2024-01-12T14:03:50+01:00', + expectedEndTime: '2024-01-12T14:03:50+01:00', + expectedStartTime: '2024-01-12T13:59:00+01:00', + realtime: false, + distance: 310.02, + duration: 290, + fromPlace: { + name: 'Postnord', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'q|xlJmweaACFA?m@aBBEDKK]eAyCEQSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T14:03:50+01:00', + expectedEndTime: '2024-01-12T14:03:50+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + duration: 4183, + distance: 27503.719999999998, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T13:05:00+01:00', + expectedEndTime: '2024-01-12T13:05:00+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeRABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADUAAAA7ABBSQjpOU1I6UXVheTo3OTQ0ABBSQjpOU1I6UXVheTo3MzczADtSQjpSVVQ6RGF0ZWRTZXJ2aWNlSm91cm5leTplNjBjM2M1ODE2ZjUxNGExZjk2NTdiZjEwYmQ3ZmJhNw==', + mode: 'bus', + aimedStartTime: '2024-01-12T13:05:00+01:00', + aimedEndTime: '2024-01-12T13:21:00+01:00', + expectedEndTime: '2024-01-12T13:21:00+01:00', + expectedStartTime: '2024-01-12T13:05:00+01:00', + realtime: true, + distance: 15329.9, + duration: 960, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:21:00+01:00', + aimedEndTime: '2024-01-12T13:24:57+01:00', + expectedEndTime: '2024-01-12T13:24:57+01:00', + expectedStartTime: '2024-01-12T13:21:00+01:00', + realtime: false, + distance: 234.7, + duration: 237, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'u~tlJ{}n`A??GYEKIS[w@GKMSOUGKAEAE?G?G@EAECGCGACAAACCGAC?AAECECGAEFOTo@ISEKAFKl@IJO^GRCAIRGRc@p@??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAABAAAAAWABBSQjpOU1I6UXVheTo3MzMzABFSQjpOU1I6UXVheToxMTEzNAA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6YzRjM2QwMjI1YWI5OGFhYjQ4NWNmZjAwZDExM2E0NzA=', + mode: 'metro', + aimedStartTime: '2024-01-12T13:27:00+01:00', + aimedEndTime: '2024-01-12T13:37:00+01:00', + expectedEndTime: '2024-01-12T13:37:00+01:00', + expectedStartTime: '2024-01-12T13:27:00+01:00', + realtime: true, + distance: 4410.74, + duration: 600, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Helsfyr', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Mortensrud', + }, + }, + line: { + publicCode: '3', + name: 'Kolsås - Mortensrud', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'seulJ{co`AHMTm@FKBa@@KJu@NuAL{@Jw@Lu@Ls@Hk@Lo@?AVyAf@oCLs@Lw@Ho@Js@Fs@Hu@HwADaADkAD}@?WP{EDo@Fm@LiELeD??By@NmEBy@Du@Bk@JgAJcAL_APeAX{A\\aBd@iCL_AJ{@H{@Bi@@g@@e@FgCBcA?OHuD??@[JyE@uA@oAAiAGaAGy@Iy@M{@{@sEOeAIo@IiAEkAAeA?qAH}H??@i@D}DDqC@y@@e@B{@Be@H_ArAeMR}BFuA@yAEwAIsAO{ASqAWgAa@mAe@_Ag@m@mByB]k@[q@Yy@YkASkAQsAYkCKy@Ko@Ms@Ka@Me@Ma@O_@O_@Sa@Yi@uAeCa@u@??w@yAQc@Oa@K[K_@Ma@Mg@g@uBOk@Oi@Mc@Oa@O[Q[QYEc@Cs@Am@Am@@o@@g@@g@Bi@Di@De@Fc@Fc@Hg@Nm@Ja@La@N_@N]R_@RYPYVUTSRMPIPIl@WRITKNKNMLKNQPSRYLULUHSJUHUJYHUNc@Lg@Pk@Lg@Lg@P{@Ha@n@{CH]R}@??`@mBH_@Lq@DYDYD]Da@B]Dg@@_@Bi@@g@?c@?c@Ae@A_@Ck@Eo@?AWwCEq@Eq@Cu@Cw@Cc@Ao@?m@?k@?q@?y@@k@B{@j@oOD}@FgAHw@LuANgAn@uFHw@', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:37:00+01:00', + aimedEndTime: '2024-01-12T13:37:32+01:00', + expectedEndTime: '2024-01-12T13:37:32+01:00', + expectedStartTime: '2024-01-12T13:37:00+01:00', + realtime: false, + distance: 33.93, + duration: 32, + fromPlace: { + name: 'Helsfyr', + }, + toPlace: { + name: 'Helsfyr T', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '_utlJws|`ABBAb@i@G??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAIAAAAFABFSQjpOU1I6UXVheToxMTE0MgARUkI6TlNSOlF1YXk6MTA0MDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmIzNDRjZDFmM2FjZWU2MTE5ZGE2N2M3MDNjMTViYmQ1', + mode: 'bus', + aimedStartTime: '2024-01-12T13:40:00+01:00', + aimedEndTime: '2024-01-12T13:44:00+01:00', + expectedEndTime: '2024-01-12T13:44:00+01:00', + expectedStartTime: '2024-01-12T13:40:00+01:00', + realtime: false, + distance: 4040.73, + duration: 240, + fromPlace: { + name: 'Helsfyr T', + }, + toPlace: { + name: 'Trosterud', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Blystadlia', + }, + }, + line: { + publicCode: '300', + name: 'Blystadlia - Ahus - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'wvtlJsr|`AAIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGo@{CWiAYiAcAmDqBeHgBiGqBcHc@cBc@eBUgASiAQoAIi@Gi@ScCKaBKmBMuBCw@CiB?{BAiBAuA?yA?sA@yB@gC@{D?{A?{A?qA?sAAuAAqACuACqAEwAEkACiAGmAGqAI{AKkBKsAKoAKqAMmAMqAGm@K{@MgAM{@UeBWaBSsAc@oCa@kCSwAYsBQqAQ}AQ{AMqAMkAQuBm@yGOcB]cDMoAYwBWmBc@mC_@qB_@mBi@sDSiAe@}BOu@Oq@YeAOk@Qg@Wu@Oe@Q[M[Wk@We@EI', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:44:00+01:00', + aimedEndTime: '2024-01-12T13:47:21+01:00', + expectedEndTime: '2024-01-12T13:47:21+01:00', + expectedStartTime: '2024-01-12T13:44:00+01:00', + realtime: false, + distance: 178.32, + duration: 201, + fromPlace: { + name: 'Trosterud', + }, + toPlace: { + name: 'Trosterudkrysset', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'sywlJw}haA?A?ECOAM@K?G@E@I@EBCBEFCPEBABCBC@E@G@K@YBSBSDKJQ`@y@HMVv@DPBJ@LBXU[??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAIAAAAFABFSQjpOU1I6UXVheToxMDM3NQARUkI6TlNSOlF1YXk6MTAzOTYAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjliZTdhODEwN2RjMGEyODQ5NGVkNTRhNzQ3ZThjYzZi', + mode: 'bus', + aimedStartTime: '2024-01-12T13:51:00+01:00', + aimedEndTime: '2024-01-12T13:53:00+01:00', + expectedEndTime: '2024-01-12T13:53:00+01:00', + expectedStartTime: '2024-01-12T13:51:00+01:00', + realtime: false, + distance: 1203.14, + duration: 120, + fromPlace: { + name: 'Trosterudkrysset', + }, + toPlace: { + name: 'Alfasetveien', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Majorstuen', + }, + }, + line: { + publicCode: '25', + name: 'Majorstuen-Haugerud', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'iuwlJ_diaAEIOg@Us@EKIWOi@IQKIKIIEMCCGCECACAE?C@C@ABCDADADAFORQTKNKNMVMZ??MXO\\qAbDGLMXGNKLKPE@CBCDCDAHAFAF?HGRGVGTMZqBbFm@vASh@A???Sf@OZMVKTMVQVKJKJMHQHE?E@GBCFEHAJAD?DGPGHGHKH]TIFSH[LQDWDc@HwCh@uB^qDz@i@JM@MAQ?GKGCGAGBGFEJCNKNIHIFMDODo@RcAZE@', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:53:00+01:00', + aimedEndTime: '2024-01-12T13:55:31+01:00', + expectedEndTime: '2024-01-12T13:55:31+01:00', + expectedStartTime: '2024-01-12T13:53:00+01:00', + realtime: false, + distance: 162.35, + duration: 151, + fromPlace: { + name: 'Alfasetveien', + }, + toPlace: { + name: 'Alfasetveien', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'wnylJqygaA??^QTIHAPGTG@?f@S@P?B@FAJ?J?LAFADEHCHUFk@RAEJO??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAYAAAAIABFSQjpOU1I6UXVheToxMDM5NAARUkI6TlNSOlF1YXk6MTAyNTkAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmQ5OTFhMTk1NGQzYjkyNjRhMTk5ZGY1OTA5YTBlMmE5', + mode: 'bus', + aimedStartTime: '2024-01-12T13:58:00+01:00', + aimedEndTime: '2024-01-12T13:59:00+01:00', + expectedEndTime: '2024-01-12T13:59:00+01:00', + expectedStartTime: '2024-01-12T13:58:00+01:00', + realtime: false, + distance: 872.68, + duration: 60, + fromPlace: { + name: 'Alfasetveien', + }, + toPlace: { + name: 'Postnord', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Helsfyr', + }, + }, + line: { + publicCode: '68', + name: 'Helsfyr T - Grorud T via Alfaset', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'elylJaygaA`A[JALCH?RBBDBBBVBT@HBPDb@?TBbABlBFvBBf@Fr@Dh@Ht@Jr@Np@Lj@Nd@N`@Rb@Td@PZh@x@NP~@nAzAjBHLVZRVNVI\\Sd@Q^GN??KTcApBmA`CIPKREREX@XBXDPdAxCJ\\l@bB', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:59:00+01:00', + aimedEndTime: '2024-01-12T14:03:50+01:00', + expectedEndTime: '2024-01-12T14:03:50+01:00', + expectedStartTime: '2024-01-12T13:59:00+01:00', + realtime: false, + distance: 310.02, + duration: 290, + fromPlace: { + name: 'Postnord', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'q|xlJmweaACFA?m@aBBEDKK]eAyCEQSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T14:07:28+01:00', + expectedEndTime: '2024-01-12T14:07:28+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + duration: 4401, + distance: 26472.179999999997, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T13:05:00+01:00', + expectedEndTime: '2024-01-12T13:05:00+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeRABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADUAAAA7ABBSQjpOU1I6UXVheTo3OTQ0ABBSQjpOU1I6UXVheTo3MzczADtSQjpSVVQ6RGF0ZWRTZXJ2aWNlSm91cm5leTplNjBjM2M1ODE2ZjUxNGExZjk2NTdiZjEwYmQ3ZmJhNw==', + mode: 'bus', + aimedStartTime: '2024-01-12T13:05:00+01:00', + aimedEndTime: '2024-01-12T13:21:00+01:00', + expectedEndTime: '2024-01-12T13:21:00+01:00', + expectedStartTime: '2024-01-12T13:05:00+01:00', + realtime: true, + distance: 15329.9, + duration: 960, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:21:00+01:00', + aimedEndTime: '2024-01-12T13:24:57+01:00', + expectedEndTime: '2024-01-12T13:24:57+01:00', + expectedStartTime: '2024-01-12T13:21:00+01:00', + realtime: false, + distance: 234.7, + duration: 237, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'u~tlJ{}n`A??GYEKIS[w@GKMSOUGKAEAE?G?G@EAECGCGACAAACCGAC?AAECECGAEFOTo@ISEKAFKl@IJO^GRCAIRGRc@p@??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAABAAAAAWABBSQjpOU1I6UXVheTo3MzMzABFSQjpOU1I6UXVheToxMTEzNAA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6YzRjM2QwMjI1YWI5OGFhYjQ4NWNmZjAwZDExM2E0NzA=', + mode: 'metro', + aimedStartTime: '2024-01-12T13:27:00+01:00', + aimedEndTime: '2024-01-12T13:37:00+01:00', + expectedEndTime: '2024-01-12T13:37:00+01:00', + expectedStartTime: '2024-01-12T13:27:00+01:00', + realtime: true, + distance: 4410.74, + duration: 600, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Helsfyr', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Mortensrud', + }, + }, + line: { + publicCode: '3', + name: 'Kolsås - Mortensrud', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'seulJ{co`AHMTm@FKBa@@KJu@NuAL{@Jw@Lu@Ls@Hk@Lo@?AVyAf@oCLs@Lw@Ho@Js@Fs@Hu@HwADaADkAD}@?WP{EDo@Fm@LiELeD??By@NmEBy@Du@Bk@JgAJcAL_APeAX{A\\aBd@iCL_AJ{@H{@Bi@@g@@e@FgCBcA?OHuD??@[JyE@uA@oAAiAGaAGy@Iy@M{@{@sEOeAIo@IiAEkAAeA?qAH}H??@i@D}DDqC@y@@e@B{@Be@H_ArAeMR}BFuA@yAEwAIsAO{ASqAWgAa@mAe@_Ag@m@mByB]k@[q@Yy@YkASkAQsAYkCKy@Ko@Ms@Ka@Me@Ma@O_@O_@Sa@Yi@uAeCa@u@??w@yAQc@Oa@K[K_@Ma@Mg@g@uBOk@Oi@Mc@Oa@O[Q[QYEc@Cs@Am@Am@@o@@g@@g@Bi@Di@De@Fc@Fc@Hg@Nm@Ja@La@N_@N]R_@RYPYVUTSRMPIPIl@WRITKNKNMLKNQPSRYLULUHSJUHUJYHUNc@Lg@Pk@Lg@Lg@P{@Ha@n@{CH]R}@??`@mBH_@Lq@DYDYD]Da@B]Dg@@_@Bi@@g@?c@?c@Ae@A_@Ck@Eo@?AWwCEq@Eq@Cu@Cw@Cc@Ao@?m@?k@?q@?y@@k@B{@j@oOD}@FgAHw@LuANgAn@uFHw@', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:37:00+01:00', + aimedEndTime: '2024-01-12T13:37:32+01:00', + expectedEndTime: '2024-01-12T13:37:32+01:00', + expectedStartTime: '2024-01-12T13:37:00+01:00', + realtime: false, + distance: 33.93, + duration: 32, + fromPlace: { + name: 'Helsfyr', + }, + toPlace: { + name: 'Helsfyr T', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '_utlJws|`ABBAb@i@G??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAIAAAAFABFSQjpOU1I6UXVheToxMTE0MgARUkI6TlNSOlF1YXk6MTA0MDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmIzNDRjZDFmM2FjZWU2MTE5ZGE2N2M3MDNjMTViYmQ1', + mode: 'bus', + aimedStartTime: '2024-01-12T13:40:00+01:00', + aimedEndTime: '2024-01-12T13:44:00+01:00', + expectedEndTime: '2024-01-12T13:44:00+01:00', + expectedStartTime: '2024-01-12T13:40:00+01:00', + realtime: false, + distance: 4040.73, + duration: 240, + fromPlace: { + name: 'Helsfyr T', + }, + toPlace: { + name: 'Trosterud', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Blystadlia', + }, + }, + line: { + publicCode: '300', + name: 'Blystadlia - Ahus - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'wvtlJsr|`AAIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGo@{CWiAYiAcAmDqBeHgBiGqBcHc@cBc@eBUgASiAQoAIi@Gi@ScCKaBKmBMuBCw@CiB?{BAiBAuA?yA?sA@yB@gC@{D?{A?{A?qA?sAAuAAqACuACqAEwAEkACiAGmAGqAI{AKkBKsAKoAKqAMmAMqAGm@K{@MgAM{@UeBWaBSsAc@oCa@kCSwAYsBQqAQ}AQ{AMqAMkAQuBm@yGOcB]cDMoAYwBWmBc@mC_@qB_@mBi@sDSiAe@}BOu@Oq@YeAOk@Qg@Wu@Oe@Q[M[Wk@We@EI', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:44:00+01:00', + aimedEndTime: '2024-01-12T14:07:28+01:00', + expectedEndTime: '2024-01-12T14:07:28+01:00', + expectedStartTime: '2024-01-12T13:44:00+01:00', + realtime: false, + distance: 1694.97, + duration: 1408, + fromPlace: { + name: 'Trosterud', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'sywlJw}haA?A?ECOAM@K?G@E@I@EBCBEFCPEBABCBC@E@G@K@YBSBSDKJQIMCCCCCAE?G@k@JG?IAKESMGCK?I?GDGFGLYt@_@|@Ul@c@bAOZCFAFAFAFAPAVCZAF?HCNGAI@IFIHILKTUh@iA`Cc@dAw@rBQd@M^Od@Mh@Mh@Mb@GPGNINGDI@i@b@YPC@OHQFUHUHu@TBz@BlALADAD?DBFBJHHPCHIx@ABK`AIh@CNIb@Ir@Y~CO~BAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:42:00+01:00', + aimedEndTime: '2024-01-12T14:09:19+01:00', + expectedEndTime: '2024-01-12T14:09:19+01:00', + expectedStartTime: '2024-01-12T12:42:00+01:00', + duration: 5239, + distance: 28576.019999999997, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:42:00+01:00', + aimedEndTime: '2024-01-12T12:59:00+01:00', + expectedEndTime: '2024-01-12T12:59:00+01:00', + expectedStartTime: '2024-01-12T12:42:00+01:00', + realtime: false, + distance: 1019.02, + duration: 1020, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'Slependen stasjon', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@REDCDMLAFERQSy@a@_@IM@sAHkDJcADa@B]Hg@Va@Zc@b@u@n@_ChCcA|@_@h@w@rAA@CICIu@jAq@bAQX_@d@QVMFWFG?GAGCIGCQAI?ICO[iDCQCSEe@AEQHKD_@@??', + }, + }, + { + id: 'rO0ABXeFABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAUAAAAQABBSQjpOU1I6UXVheToxMDYxAA9SQjpOU1I6UXVheTo1MDQAMFJCOk5TQjpEYXRlZFNlcnZpY2VKb3VybmV5OjIxMzRfQVNSLUxMU18yNC0wMS0xMg==', + mode: 'rail', + aimedStartTime: '2024-01-12T12:59:00+01:00', + aimedEndTime: '2024-01-12T13:36:00+01:00', + expectedEndTime: '2024-01-12T13:35:30+01:00', + expectedStartTime: '2024-01-12T12:59:00+01:00', + realtime: true, + distance: 25116.17, + duration: 2190, + fromPlace: { + name: 'Slependen stasjon', + }, + toPlace: { + name: 'Nyland stasjon', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Lillestrøm', + }, + }, + line: { + publicCode: 'L1', + name: 'Spikkestad-Oslo S-Lillestrøm', + }, + authority: { + name: 'Vy', + }, + pointsOnLink: { + points: + 'glolJ}ib_AC@aA^IBUJUHWFYHUFWBUBY?Y?YA[CYGg@K[IWIm@M]K[M[OYQYSYW[_@Y]U_@Ua@[m@Um@Yu@Oe@Me@Mk@Me@Ki@Ms@Ks@Gk@Im@Gw@Em@G_AEu@Co@QcEC]??Q}DEiACw@C}@AmAA_AAqAAcH?mHAoB?uCAiA?m@Am@As@C}@Cw@EcAEgAIkAG}@Gs@Gw@Iu@Gq@McAKu@Ku@Kk@Kk@Ik@Mm@Os@Mo@Ki@??[yAYqA[sAc@mBaAgE????kBeIi@_C]yAYmAc@kBWgAYoAaBkH{@oDmAmFUcAu@_D_@}A??u@gDi@yBEWOq@YkAUaA{@iDc@eBU{@WcAOo@Mm@Mq@Kk@Ig@Ii@Im@Io@I{@I_AEs@Es@Ew@CeACgAAy@?s@@w@@y@@o@By@B}@F}@F}@F{@Hy@J{@Ju@RqAz@iFRkAJm@Js@De@Fc@De@Dc@Dm@Fo@Bo@Ds@@k@Bk@@m@@k@?i@?m@?i@Ak@Au@Cq@Cq@Cu@Es@Gw@AI????Iy@Gi@Gg@Gi@Ig@Ig@Ie@Kg@G]Ka@K]W_AQm@Qi@c@qAQk@M]Ka@K_@Ke@Mg@I_@Ki@Kk@Ik@Im@Gi@Gm@Gm@Ek@Cm@Eo@Cy@Cw@Aq@Am@?_A?q@?{@HeTFyO@i@F}L?_A?o@?o@Ai@Ak@Ck@Ag@Ce@Ck@Cg@Ek@Gi@Ei@Iq@M_AO_AIg@SuAO{@CUw@gFa@mCm@kEMy@mByM????q@mEk@}DQkAQgA]qBUuAWsAUuAIc@g@uCQgAQiAk@aE??a@wC]gCSoASoAMy@Q}@UoAQw@Qy@Sw@U{@W}@Sq@Og@Qk@Oc@Wq@Si@Uk@i@sAUk@Ys@Um@Qe@Oe@Sm@Om@Sq@Oi@Qu@Oo@Ou@Mq@Mo@Kq@Ms@Ks@K{@[{Bo@aFWkBSaBUgBMy@My@Ku@Ku@Mw@O_AO}@Ms@Q}@UkACK????ESOm@Qq@Mi@Og@_@mASs@Uw@a@wAUy@]kAs@cC]kAQs@]oAYeAWiAyA{F}AgGwAuFYmAUy@Sw@a@aB{AcGuAqFyA}F[kAWaAS{@Qq@U{@GYQq@[mAMe@I]Kc@Ka@Ig@Ke@Gc@Ii@Gg@Io@Ee@Gw@Ek@Cm@Ag@Ak@As@As@?s@@s@Bu@@m@Dm@Bq@Fu@Do@Fq@Fo@Fg@Hq@Z{B??JaAFk@Dg@??Jg@DWHc@Jm@??Js@Hq@RsAPsAJu@NiALgAHmAHoADkABeA@iA?E?????u@?aAAs@Cs@Cm@Ce@A_@Ce@Ei@IaAKgAG{@YmDK_AI}@Is@Iu@IcAYcDEo@KiAKcAIs@Kq@MaAQgASoAO{@SeAWkAc@qBm@eC[iAQs@Oo@Om@Mm@Kg@Mo@Ko@Ku@Ks@Iu@I}@I_AGeAEw@GiAEcAIyBEs@Eq@GcAIy@Ek@Iw@Ii@Im@Ig@O{@Km@S_AUaAU}@[aAY{@Ww@u@yBQi@Wo@k@cBe@wAYy@Y{@sAwD{@eCSm@??Sm@I_@Ka@IYMc@Si@??Mi@IYI[EU??Oc@GQMa@i@{AmEoMe@qA[}@Qo@Oc@Oo@Ka@Mk@Kg@Mk@G[E[M_A??Ig@Ic@CO??AOCYC]Kw@OsAE_@Ec@Eo@Ac@Cg@Ao@A}@A_A@cA?}@Bw@@o@??D}@Dy@H_AHy@H{@Hk@Ju@L}@x@cFJq@????BMDQj@eD|@kFX}AZgBXcBf@qCVuAN}@Nu@Nu@R{@XqA`@iBLo@Lm@??VsANu@RgAJm@Jq@NaANmAR_BN_BNeBL_BHqADeAD}@DgABu@B{@@_A@y@@y@@cA?iAA{AAeAA_AAy@C_ACy@C_AMsDKkCGiB??KyCKiDE_BC{AAkA?eAAeA@oA@kA@gABwADoAD_BH{AFaAFiAHgAFaAl@}Jn@}JPoCLuBPeCLuALsALoALkANkATaBn@oE|@_GfAqH@KVcBNaAP}@f@kCTmAVsA??XyAb@aCLo@NcALw@Ho@Hq@Hw@HgAHaADu@Dw@H}Ab@_K????d@gKF_BBs@Dw@DaBBaABs@Bm@Bm@@_@B[B_@Bg@Do@B_@D]Fu@??Fs@Fq@J_AJw@Fk@Hk@Jo@Jq@F_@Lu@Nw@??ZcBPeA\\gBN_ANu@Lu@L{@Jm@Ly@L_ANkAHw@Hs@H_AL}AHqAHkAFsAF{ADoABmAHgDDuABgADcAFy@F_AF}@H_AH{@LqAJ{@??@[B]@]??F[DUFa@Fe@Hs@He@L{@Ny@??RuALw@Jk@Jg@Ji@\\{AR}@Ns@N{@L_AVcB??^gCf@cD????p@qE|@eGh@iD??j@uDb@yCn@aE`@oCNaANgALiAJiADi@Fo@Dw@LwBFiA??Fm@Hu@PcBLsARoB??Z}CH}@`@wDXcDb@}DH_A??Dc@B_@Dq@@]Fk@H}@??Z{C??Ba@D_@@WB]@WDm@??TqBViCTgCL{ALyANiBLaBJqAHuAD_AHkADgADgADeAFqB@[Bu@BoA@y@BcA@mA@uA@}A?aA?_A?{A?}HAsF?mJA_F?qH?qBAsC?aB?oC?{BAoC?eH?mD?sD?gBAoB?kA?qB?qA?}@?k@Ak@?m@Aq@Ai@Ag@As@Cw@Cs@Cs@Ew@Eu@Ci@Gq@Eu@G{@KmAQmBYkDO_BOkBQuBw@aJScCQqBS_CS{BKwAOyAa@eFEe@??C_@C[Cq@AUCY??I_AGu@KmAGq@Gw@KaAIy@Go@Io@Im@ES????G_@Ko@Ke@[sAMg@Mk@Ok@Og@Qi@Sm@Oc@Oc@O]O_@Qa@Sa@Qa@k@kAQ_@u@{A??]o@Uc@S_@]m@Wc@OWEGYe@QW[c@W]QWSUMQSSUYOOo@o@c@a@[W[UWS]U[SUM_@Ue@Wq@][QYQYM_Ag@}BoAsEaCwC}AcAi@s@_@c@Wc@Uk@Yk@[u@a@w@a@cFkCyEgC??gCsA_B{@w@_@e@S]O]OWKWKSGsBs@SGWI[K[I[I_@GUEWE[C[C[C[AU?[@Y?W@a@BWD]DUBwATy@NoB\\a@F[Fa@F_@DO@I@W@[@Y?YAUAYCWE]G_@IYK]Ma@O_@Sa@Si@[MIQKu@c@yD}B????]S}D_Ci@]c@Y_@Wa@[_@Y[[_@[e@g@WYSUSYW]W]U_@Wa@Yc@Yg@Yi@Wi@Wi@Uk@Ug@Qe@Si@Um@Qi@Qk@So@Qo@Mc@Kc@EQKa@Mk@Sy@Qw@ScASaAOu@Qy@QaAO{@O_AOaAMy@MgAM_AKgAMkAIaAI_AIeAIcAImAIwAs@iL_BoXMuBK}AG{@Em@Gs@Gq@I_AIu@E_@Gi@Kw@Iq@Iq@M}@M}@Oy@QgAQcAk@yCWoA]gBI_@??u@}DmDwQcEkTMm@QaA_@iBSaAOw@CI??', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:35:30+01:00', + aimedEndTime: '2024-01-12T14:09:19+01:00', + expectedEndTime: '2024-01-12T14:09:19+01:00', + expectedStartTime: '2024-01-12T13:35:30+01:00', + realtime: false, + distance: 2440.83, + duration: 2029, + fromPlace: { + name: 'Nyland stasjon', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'kxzlJakjaA??~@`EPfAJf@BNUDA?K?GCIGMXIXc@tACNBLFJNZJNFFHHD@FBFANd@Pb@Ph@Lf@Pr@Pt@Nt@VrAhGp[DXL|@BPBPp@hDDVDZ?H@JA`@@D@DBDANEJCHEHEDGFWRIFGHGJGLENENCLCRUhBCPB@@?r@LB?xBZ|@Ll@FlAH^@R@J?BABCBCDIDN?D?H?H?B?DAF?FAHETDBJJBDBDDDBDD@B@B@B?B?B?B?BABCBABEBCBCDCBADA?E?C@C@CBCDEBAFAFAb@APAPAPCb@Id@Ih@MRGLCF?RBJ?N?LAPEt@Uj@STGPAFTLf@HVHRJTMp@ITAX@ZLlAJhA?rA\\bDVrAXlAh@r@Tl@Zb@f@d@^LnAzAj@|@h@jAd@jAEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T14:10:09+01:00', + expectedEndTime: '2024-01-12T14:10:09+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + duration: 4562, + distance: 26424.149999999998, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T13:05:00+01:00', + expectedEndTime: '2024-01-12T13:05:00+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeRABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADUAAAA7ABBSQjpOU1I6UXVheTo3OTQ0ABBSQjpOU1I6UXVheTo3MzczADtSQjpSVVQ6RGF0ZWRTZXJ2aWNlSm91cm5leTplNjBjM2M1ODE2ZjUxNGExZjk2NTdiZjEwYmQ3ZmJhNw==', + mode: 'bus', + aimedStartTime: '2024-01-12T13:05:00+01:00', + aimedEndTime: '2024-01-12T13:21:00+01:00', + expectedEndTime: '2024-01-12T13:21:00+01:00', + expectedStartTime: '2024-01-12T13:05:00+01:00', + realtime: true, + distance: 15329.9, + duration: 960, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:21:00+01:00', + aimedEndTime: '2024-01-12T13:24:57+01:00', + expectedEndTime: '2024-01-12T13:24:57+01:00', + expectedStartTime: '2024-01-12T13:21:00+01:00', + realtime: false, + distance: 234.7, + duration: 237, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'u~tlJ{}n`A??GYEKIS[w@GKMSOUGKAEAE?G?G@EAECGCGACAAACCGAC?AAECECGAEFOTo@ISEKAFKl@IJO^GRCAIRGRc@p@??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAABAAAAAWABBSQjpOU1I6UXVheTo3MzMzABFSQjpOU1I6UXVheToxMTEzNAA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6YzRjM2QwMjI1YWI5OGFhYjQ4NWNmZjAwZDExM2E0NzA=', + mode: 'metro', + aimedStartTime: '2024-01-12T13:27:00+01:00', + aimedEndTime: '2024-01-12T13:37:00+01:00', + expectedEndTime: '2024-01-12T13:37:00+01:00', + expectedStartTime: '2024-01-12T13:27:00+01:00', + realtime: true, + distance: 4410.74, + duration: 600, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Helsfyr', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Mortensrud', + }, + }, + line: { + publicCode: '3', + name: 'Kolsås - Mortensrud', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'seulJ{co`AHMTm@FKBa@@KJu@NuAL{@Jw@Lu@Ls@Hk@Lo@?AVyAf@oCLs@Lw@Ho@Js@Fs@Hu@HwADaADkAD}@?WP{EDo@Fm@LiELeD??By@NmEBy@Du@Bk@JgAJcAL_APeAX{A\\aBd@iCL_AJ{@H{@Bi@@g@@e@FgCBcA?OHuD??@[JyE@uA@oAAiAGaAGy@Iy@M{@{@sEOeAIo@IiAEkAAeA?qAH}H??@i@D}DDqC@y@@e@B{@Be@H_ArAeMR}BFuA@yAEwAIsAO{ASqAWgAa@mAe@_Ag@m@mByB]k@[q@Yy@YkASkAQsAYkCKy@Ko@Ms@Ka@Me@Ma@O_@O_@Sa@Yi@uAeCa@u@??w@yAQc@Oa@K[K_@Ma@Mg@g@uBOk@Oi@Mc@Oa@O[Q[QYEc@Cs@Am@Am@@o@@g@@g@Bi@Di@De@Fc@Fc@Hg@Nm@Ja@La@N_@N]R_@RYPYVUTSRMPIPIl@WRITKNKNMLKNQPSRYLULUHSJUHUJYHUNc@Lg@Pk@Lg@Lg@P{@Ha@n@{CH]R}@??`@mBH_@Lq@DYDYD]Da@B]Dg@@_@Bi@@g@?c@?c@Ae@A_@Ck@Eo@?AWwCEq@Eq@Cu@Cw@Cc@Ao@?m@?k@?q@?y@@k@B{@j@oOD}@FgAHw@LuANgAn@uFHw@', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:37:00+01:00', + aimedEndTime: '2024-01-12T13:37:47+01:00', + expectedEndTime: '2024-01-12T13:37:47+01:00', + expectedStartTime: '2024-01-12T13:37:00+01:00', + realtime: false, + distance: 57.17, + duration: 47, + fromPlace: { + name: 'Helsfyr', + }, + toPlace: { + name: 'Helsfyr T', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '_utlJws|`ABBOtBPhA??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAAJABFSQjpOU1I6UXVheToxMTE0OAARUkI6TlNSOlF1YXk6MTE0NDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmM4MzJiNGVkODUyYmE0ZDQwMTc0YmM3ODRkNWZkZGVm', + mode: 'bus', + aimedStartTime: '2024-01-12T13:45:00+01:00', + aimedEndTime: '2024-01-12T13:55:00+01:00', + expectedEndTime: '2024-01-12T13:55:00+01:00', + expectedStartTime: '2024-01-12T13:45:00+01:00', + realtime: false, + distance: 4589.89, + duration: 600, + fromPlace: { + name: 'Helsfyr T', + }, + toPlace: { + name: 'Alfaset', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Grorud T via Ikea', + }, + }, + line: { + publicCode: '66', + name: 'Helsfyr T - Grorud T', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'yttlJun|`A?@Jn@DZ?N?J?JC?CBCDCHAL?J@JBFDFD@DADCBG@I@GDUFWFs@?AFk@Bi@Bi@@W@S?]?e@CeA?c@Ci@Ae@C]CYKiAGe@CMEa@Cc@AEl@yGDq@Be@B_@Di@Bc@DM@O?OAQEKGGEAC?E@GGEGCICKCMAQiAsNIoA?AG{@Co@Am@Ai@@e@?g@@[Bi@\\eH??HcB@_@D{@DaA@m@@]@cABi@@Q@IFa@@ADEBK?K?KAGCECCCAG_@AQASA[Aa@CiDA]AqA?KA}@EuC?Q????As@?ACg@Ae@C}@GsAGeAMoCMoCC_@?g@@W?Q?CBa@BK@M?K?MAMEKGIGEA?E?GDEFCHI?GEECECCAAEEEGKGOQe@EKQSM_@ISK]M[GO??IQIMEMQWSYUW[YYSWO[KSEUEm@EaAGOCQCQEMEQIQMOMMOMQ[i@iAyB??CC]m@MSQWYa@QSY_@]a@A?Y[g@e@SQeAy@kAcAwAeAa@_@QMe@_@????UOUMQK[MQGECWGe@Ia@G}AOKA}C]k@Ii@GUC[EKKEGEEEIEOM_@AOK_AKaAIw@Ek@??CSGgAEy@Cs@AaAAs@Ay@As@?q@@yA@gDBsD@wD@_C?oDByD?_@@iB@gB@i@@m@@[@Y?EHg@@U@A@E@E?EAEAEACAAA?A?IIECGCOBG?C?[@[BYB_@FSDy@J??C@OBSEE?KAI?AEACCEEACAC@A@KIGKEGUa@KYQ_@o@oAeAuBiAyBS[MW]o@Wc@[c@[c@i@q@EG??c@i@[_@[]s@w@GIIIYc@EIGKIMGMAAAKAGCEEEEAC@A@KIGEEGQOYk@]s@[w@Um@Sk@IYIUESIYEWGYEYEWE_@Ge@Gk@Ec@C]C_@C_@A]GcBC_@A[Ca@EWCWE]G[G]Qy@Qy@e@yBS_AMq@GSCOEQCMKe@S_AAC', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:55:00+01:00', + aimedEndTime: '2024-01-12T14:10:09+01:00', + expectedEndTime: '2024-01-12T14:10:09+01:00', + expectedStartTime: '2024-01-12T13:55:00+01:00', + realtime: false, + distance: 1074.54, + duration: 909, + fromPlace: { + name: 'Alfaset', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'egxlJeigaA@A?BRz@DZA@ILEDA@}@aEAECIACCGAE?IUiA?CAEMaA_Br@KBI?GBGHKNW^w@jA]f@ORSRQLMHMBAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T14:13:28+01:00', + expectedEndTime: '2024-01-12T14:13:28+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + duration: 4761, + distance: 27352.32, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T13:05:00+01:00', + expectedEndTime: '2024-01-12T13:05:00+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADUAAAA-ABBSQjpOU1I6UXVheTo3OTQ0ABFSQjpOU1I6UXVheToxMTk2OQA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6ZTYwYzNjNTgxNmY1MTRhMWY5NjU3YmYxMGJkN2ZiYTc=', + mode: 'bus', + aimedStartTime: '2024-01-12T13:05:00+01:00', + aimedEndTime: '2024-01-12T13:28:00+01:00', + expectedEndTime: '2024-01-12T13:28:00+01:00', + expectedStartTime: '2024-01-12T13:05:00+01:00', + realtime: true, + distance: 17846.09, + duration: 1380, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA??EMIU]{@MYKOMOEIIKIGAK?GCGCGGIECM?GIEIGOWy@EKEKCGIKCCCCOQCCAA[a@QSQU_@c@QU[_@i@o@KMCEOQIKkAyAMQY]KMAAAAACKKCEcAmAUU?M?IAOGyGAg@AQHQDK`AuBx@gB@Eh@cAh@gA??`@y@JSHSHWFOHWJ_@Lg@Pw@Lu@H_@De@Dg@Ba@@s@?s@Eq@GuAEs@MsBGqAEm@E}@C}@AcBAgA?e@?]?Q?U@_@@k@HoANiAT}B@SHu@F]D[J_@H[j@uBBK@EDOFe@@EDYH[VaAJ]@CFODIFG`AwAZa@??@AHKLOFC?A@?DA@?FA@?B?H@??D@F@NBF?D?FADCFCHGl@m@\\[LOFGFEBEDCDE@APMFChC_ALCNEDDB@F?BADEBIBK@OAOJy@VwCBWL_BD[DEBI@I?IAKB]Fi@JsAD{@HiALoAJ_AFg@@G??LeBLyANkBBSBQHk@BEBG@I?I?G?IAGCIACCAECA?C?C@C@ADCDAHAH?H?H@HBF?F?NAL?RMRILEHABINATKhAIbAIbAO`BALE`@ABGt@KlAKvAAL', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:28:00+01:00', + aimedEndTime: '2024-01-12T13:31:42+01:00', + expectedEndTime: '2024-01-12T13:31:42+01:00', + expectedStartTime: '2024-01-12T13:28:00+01:00', + realtime: false, + distance: 213.19, + duration: 222, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'sptlJm|s`A??LoAB[@EPqB@MBa@JD@@FQ??D@HDJsA@@B@DBB@DBDB@@Fu@LwAHwA??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAAJABFSQjpOU1I6UXVheToxMTk2MAARUkI6TlNSOlF1YXk6MTA0MDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmY4MDE0ZDY1OWI3ZWY3ODNhZTdjYjU4NjBiMWMyNzg3', + mode: 'bus', + aimedStartTime: '2024-01-12T13:35:00+01:00', + aimedEndTime: '2024-01-12T13:50:00+01:00', + expectedEndTime: '2024-01-12T13:50:00+01:00', + expectedStartTime: '2024-01-12T13:35:00+01:00', + realtime: false, + distance: 6870.86, + duration: 900, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Trosterud', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Lillestrøm', + }, + }, + line: { + publicCode: '110', + name: 'Lillestrøm - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '}ktlJynt`ADi@BQBSBQHk@BEBG@I?I?G?IAG@QBQBKH_@Ji@BNBN?DDUBGJm@BM?ARy@d@{Bt@mDZ{ANo@H[@E`@oBt@mDFUBM?CJe@DSFU@KHc@?GDe@Nq@TgAj@mC@A@KBMFa@x@wE@E??F_@l@iDXcB`@eCV_BDYV_@BE??LUBM?OOaBBa@VuC`@}D@KZwCb@iEZgDFk@BUKa@CKGWWqAe@{BOu@EMIc@C_@G[YwAAGM[EQI]EQMm@ScAG[Mq@??OaAKo@Ik@Is@Io@MqAQ_BC]YeCs@}GEi@Gi@KeAEY??E[Iu@Gc@Ga@G]Ic@Kc@i@aCa@aBMk@Kc@[sAIa@Kc@S_A?C??I[C_@AKAa@?W@G@E?GHSBMFYN_@Rm@FUDUBOBQ@O@Q@O?MD]@g@?_@BG@I@KAIAICIEEEAE?EDADADO?I?E?C?E@C@CBEFCBCDSd@EHEFCDEDCBE@E@A@C?I?EAIEECs@q@Uw@WcAe@qBeD_OS{ASgAOiAEy@Ca@?U?O@I@G?IAKCICECCCAA?C?CBEIKUKc@COG[Ge@OkAEU??AIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGo@{CWiAYiAcAmDqBeHgBiGqBcHc@cBc@eBUgASiAQoAIi@Gi@ScCKaBKmBMuBCw@CiB?{BAiBAuA?yA?sA@yB@gC@{D?{A?{A?qA?sAAuAAqACuACqAEwAEkACiAGmAGqAI{AKkBKsAKoAKqAMmAMqAGm@K{@MgAM{@UeBWaBSsAc@oCa@kCSwAYsBQqAQ}AQ{AMqAMkAQuBm@yGOcB]cDMoAYwBWmBc@mC_@qB_@mBi@sDSiAe@}BOu@Oq@YeAOk@Qg@Wu@Oe@Q[M[Wk@We@EI', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:50:00+01:00', + aimedEndTime: '2024-01-12T14:13:28+01:00', + expectedEndTime: '2024-01-12T14:13:28+01:00', + expectedStartTime: '2024-01-12T13:50:00+01:00', + realtime: false, + distance: 1694.97, + duration: 1408, + fromPlace: { + name: 'Trosterud', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'sywlJw}haA?A?ECOAM@K?G@E@I@EBCBEFCPEBABCBC@E@G@K@YBSBSDKJQIMCCCCCAE?G@k@JG?IAKESMGCK?I?GDGFGLYt@_@|@Ul@c@bAOZCFAFAFAFAPAVCZAF?HCNGAI@IFIHILKTUh@iA`Cc@dAw@rBQd@M^Od@Mh@Mh@Mb@GPGNINGDI@i@b@YPC@OHQFUHUHu@TBz@BlALADAD?DBFBJHHPCHIx@ABK`AIh@CNIb@Ir@Y~CO~BAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T14:13:45+01:00', + expectedEndTime: '2024-01-12T14:13:45+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + duration: 4778, + distance: 30258.55, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T13:05:00+01:00', + expectedEndTime: '2024-01-12T13:05:00+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADUAAAA-ABBSQjpOU1I6UXVheTo3OTQ0ABFSQjpOU1I6UXVheToxMTk2OQA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6ZTYwYzNjNTgxNmY1MTRhMWY5NjU3YmYxMGJkN2ZiYTc=', + mode: 'bus', + aimedStartTime: '2024-01-12T13:05:00+01:00', + aimedEndTime: '2024-01-12T13:28:00+01:00', + expectedEndTime: '2024-01-12T13:28:00+01:00', + expectedStartTime: '2024-01-12T13:05:00+01:00', + realtime: true, + distance: 17846.09, + duration: 1380, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA??EMIU]{@MYKOMOEIIKIGAK?GCGCGGIECM?GIEIGOWy@EKEKCGIKCCCCOQCCAA[a@QSQU_@c@QU[_@i@o@KMCEOQIKkAyAMQY]KMAAAAACKKCEcAmAUU?M?IAOGyGAg@AQHQDK`AuBx@gB@Eh@cAh@gA??`@y@JSHSHWFOHWJ_@Lg@Pw@Lu@H_@De@Dg@Ba@@s@?s@Eq@GuAEs@MsBGqAEm@E}@C}@AcBAgA?e@?]?Q?U@_@@k@HoANiAT}B@SHu@F]D[J_@H[j@uBBK@EDOFe@@EDYH[VaAJ]@CFODIFG`AwAZa@??@AHKLOFC?A@?DA@?FA@?B?H@??D@F@NBF?D?FADCFCHGl@m@\\[LOFGFEBEDCDE@APMFChC_ALCNEDDB@F?BADEBIBK@OAOJy@VwCBWL_BD[DEBI@I?IAKB]Fi@JsAD{@HiALoAJ_AFg@@G??LeBLyANkBBSBQHk@BEBG@I?I?G?IAGCIACCAECA?C?C@C@ADCDAHAH?H?H@HBF?F?NAL?RMRILEHABINATKhAIbAIbAO`BALE`@ABGt@KlAKvAAL', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:28:00+01:00', + aimedEndTime: '2024-01-12T13:28:32+01:00', + expectedEndTime: '2024-01-12T13:28:32+01:00', + expectedStartTime: '2024-01-12T13:28:00+01:00', + realtime: false, + distance: 24.25, + duration: 32, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'sptlJm|s`A@@@SAAGCGC?A?W@A??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAAMABFSQjpOU1I6UXVheToxMTk4NQARUkI6TlNSOlF1YXk6MTA5NDMAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjU0ZTUxNjljOTBiOTVlZTA0Y2JkMTliOTkzNTA2MGMz', + mode: 'bus', + aimedStartTime: '2024-01-12T13:36:00+01:00', + aimedEndTime: '2024-01-12T13:54:00+01:00', + expectedEndTime: '2024-01-12T13:54:00+01:00', + expectedStartTime: '2024-01-12T13:36:00+01:00', + realtime: false, + distance: 7593.08, + duration: 1080, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Veitvet', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Lillestrøm', + }, + }, + line: { + publicCode: '380', + name: 'Lillestrøm - Rv4 - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'gqtlJg~s`A@[CMCIAKIMCWJwA@UBUBW@SBWBW@WBU@UBUBW@WBU@I@M@UBUBW@UBUDE^W@AZUNDH@D?@?D?FAB?BABBB@B?@?BABCBEBG@I?I?G?IAGCIACCAECA?C?C@C@ADGAE?MEc@UEAGAIBIFGBC@EDEDEHCLENCLCTYpDSfCId@ENELELGJEBCFKAI?KCGCIEKIYUWSmBaB_BuA]YYYSSY[QSGGOQEE??EEKMACEIEIKSAKCIEGECEAGKCGGKGQI]K[W_AyAiFGUQo@_@wAc@cBKUIUEOEOE_@I]Su@Wo@GSCMCOEW]sAQ_@CICMIY_AjAI@G?EACAECIGW_@cAiBqCeF}C}FOe@EIGIIOGIEGKOSO{BoCKWGKSYMKGEKISK{@gAGIGO??KSIOGKIOOUGK]]IOyAwC_@s@mAcCMc@GQEI_AgBGKCGIQEIAIAOAOAK?IAC?I?Wc@G{AKyBQIAWAOCYIIAiAIMCCAEC@]AKAGACACG?YCC?C@ABADAB?BIKIGKKc@[MK??m@c@[UIIQKYUeAq@eAm@YOYQYOIEKCEAICKAMAyEe@[EgAKm@G??[C_@EoAKg@Cm@CoAK_@Ce@E]CWCWEMAIAGCAEAIAIAIEIEIEEEEGAE@G@EBCBCFQEg@UiAo@gAk@}@q@SQa@a@UUm@y@_@q@g@aAEGo@yBs@{BIS??IS_@iAyAkEw@}BG[Ie@?OAQCOEUIQIOKGGCI?A?S[OYK[m@iBWu@??Ma@_@oAY}@q@sBm@cDSoAUsAWaBQiAYqBYsBK{BQ{AUcCCu@C}@Gs@MqAUeBYqCQgBSkBGk@??AIGm@QkAGa@a@qB{@{IyBeTUaCMyAY_DIiDCaBI}CIyCCyA?k@?_@@c@Fo@@C@E?E?I?ICGAEECAAC?C?EEGKK[I_@OiAKw@OiA??SeBs@{DqAgKgAiIk@qEKq@??Ge@MiAI{@GcAE}@CaAA{@AcA@cAB}@BmAHgAJkANsAJu@N_AVgA~@mDXgAR{@Lo@PmALkAHiAFeABoA@oA?yAAoAAo@C_@??A]KoBK}AMaBWyBi@aFIy@Iw@IcAG{AGuACcBByB?}B?cA??AcAEyCGoBI_BCi@AQIw@SeBQkAO{@SeA[sAu@{FeB}Mm@mEUmBGc@', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAACMAAAAoABFSQjpOU1I6UXVheToxMDk0MwARUkI6TlNSOlF1YXk6MTAzOTQAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjQyM2U4OWFhYjNjOTM2MzUwOTlkNzJkOWFiYmVkY2M0', + mode: 'bus', + aimedStartTime: '2024-01-12T13:56:00+01:00', + aimedEndTime: '2024-01-12T14:01:00+01:00', + expectedEndTime: '2024-01-12T14:01:00+01:00', + expectedStartTime: '2024-01-12T13:56:00+01:00', + realtime: false, + distance: 3132.07, + duration: 300, + fromPlace: { + name: 'Veitvet', + }, + toPlace: { + name: 'Alfasetveien', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Haugerud T', + }, + }, + line: { + publicCode: '25', + name: 'Majorstuen-Haugerud', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'uc{lJmkeaAc@gD_@sCQcAMs@WkAQu@Sy@y@sCcAwDcCaJi@kBUu@Sq@Wm@Wi@We@U]_@e@[]a@g@Y]W]SWUa@S_@Q]Qe@Wq@So@Qo@Og@Ou@Os@O_AMs@K{@KaAIu@IaAGkAEy@C}@GqA????]{J@gCAcAC{@Cq@Co@Gu@Iq@OqAGi@Is@AMAMAOAS?Y@E@E?E@EFCDCF?PBF@HCFAd@LRD??@?HBPNHBHBDBFBJBDBFBXDHFf@b@JLHHNPTXRZXd@`@r@^l@`@r@T`@PXPVTXNRVTZTVPTLZLXJVFVDVDz@JNBx@H^DRHH@l@B??J@X@RBH?LBHBT@`@TVN\\VVRXVTTLNNPX`@\\f@T`@Zn@Rd@lCnGR`@P^PZR\\PVJLNPNN??B@LLFDNF\\JXRFBFBFDDHDFLR?FBD@DBDD@DABC@C`@[TIH@ZErAL|@Jp@FlAHh@BH@RJHFHHJLDJBFFFD@FADCDEDKBKHIHGHCNMF?PARANANAPCd@Ib@Gh@K^Il@@PCjA[TG', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T14:01:00+01:00', + aimedEndTime: '2024-01-12T14:13:45+01:00', + expectedEndTime: '2024-01-12T14:13:45+01:00', + expectedStartTime: '2024-01-12T14:01:00+01:00', + realtime: false, + distance: 935.85, + duration: 765, + fromPlace: { + name: 'Alfasetveien', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'ilylJgxgaA??KN@Dj@STGPAFTLf@HVHRJTMp@ITAX@ZLlAJhA?rA\\bDVrAXlAh@r@Tl@Zb@f@d@^LnAzAj@|@h@jAd@jAEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T14:14:09+01:00', + expectedEndTime: '2024-01-12T14:14:09+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + duration: 4802, + distance: 26616.219999999998, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:54:07+01:00', + aimedEndTime: '2024-01-12T13:05:00+01:00', + expectedEndTime: '2024-01-12T13:05:00+01:00', + expectedStartTime: '2024-01-12T12:54:07+01:00', + realtime: false, + distance: 727.21, + duration: 653, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'IKEA Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA\\b@JTAHGVCJ@LBHDPP`@Tb@Xp@f@zAj@nBLd@Hj@@`ACz@@J?JDR@H?D?BAD?BEPAF?D?D@HBCNQDA@BBLDEHKd@a@BAD??O?M@KBKBGBIFGdAeA@?HIZ[??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADUAAAA-ABBSQjpOU1I6UXVheTo3OTQ0ABFSQjpOU1I6UXVheToxMTk2OQA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6ZTYwYzNjNTgxNmY1MTRhMWY5NjU3YmYxMGJkN2ZiYTc=', + mode: 'bus', + aimedStartTime: '2024-01-12T13:05:00+01:00', + aimedEndTime: '2024-01-12T13:28:00+01:00', + expectedEndTime: '2024-01-12T13:28:00+01:00', + expectedStartTime: '2024-01-12T13:05:00+01:00', + realtime: true, + distance: 17846.09, + duration: 1380, + fromPlace: { + name: 'IKEA Slependen', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Oslo bussterminal', + }, + }, + line: { + publicCode: '250', + name: 'Sætre - Slemmestad - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '{lmlJa|a_AFEJKHEFEH?FEFKBM@MASDSLe@@KFSHWFYH[F[Nw@JSHWFMDKDIDABABEL@F@FBDBHHDJFPBP?P@RARERCNGNGFIFI@K@KAw@Sg@o@c@k@m@q@o@m@aA_Aq@o@s@s@k@m@c@e@e@i@]c@]g@U_@S_@Q_@Ue@Uc@]y@[{@_@gA[gA_@qAa@{A[sAmAyEs@uCaAgDwAmEqC{G}DaIgGkKmBiDcAcBcBqCqFeJc@q@U_@mAwB{@wA}@cBO[mA_CcAqB[q@Ys@k@uAQa@GOYs@o@iBe@wAg@{AY_Ag@iBYeAYeAS_A]}A_@_BYyAWqAQeAQcAO}@{@_GaAeIgAiKmAwLaAgJ{@qGmA{H]kBc@_CaAgFYgBMeAIk@Io@Gs@Gy@Gy@Ey@Cw@Ey@A}@Cu@C_BCkDAiACgAAaAE_AC{@Ew@Gy@G{@MsACQUaCuB}SmAoLOyAcBuP}@eIk@mEmA}Iy@_Iu@wLKaBKmAK_AK_AM_AS}ASmASkAMm@ScAq@_DY}A[_BKs@My@Iq@QkAOqAKcAE_@KiAIiAIiAGcAOaCa@sHS_DIwAGsAImAG{@Gu@KgAIcAK}@I_AK{@WsBaAuGcA}GaBaLwBwN{@gGKmAAk@CeCAoACs@E}@MiASsASwA_@yC]}B_@aCEc@Im@SuAM_AKq@CQEWOmAUwBOeBc@qFO_CKkBa@gFo@gFiBsL}A_KoBwMg@iFMuA[}FCY??Iu@QaASe@AGo@oBq@iBg@qBe@yCw@wEm@}Dq@mE_@eCO_A[uBO{@QaAUcAk@}BSw@Uw@e@cB}@sCeB_G}@yCWy@]wAI[[gAK]SaAOs@McAMyA_AyMSiCKyA??OsBKwAG}@Ea@UsBWuBUqBm@qES{AoAsJS}ASmASmAUkA_@mBg@_CYsAYyAYkBQkAMkAKcAKeAWcCIcA??EYKiAYyCUaCUoCSoBUuBKeAQyAW}BYyBc@gDa@_D[wBeC}PSqAMaAIg@Iy@Gm@Ei@Ek@EaAEcAG_BGoAEm@Ec@I{@Ee@EYE_@Mu@Kk@Ki@Mm@Qk@I[Sq@aAsDSm@W{@W}@U{@Sy@Qy@Mq@Ii@Ee@Ge@C_@Ea@Ce@Ci@K_BGwAOkCA[AO?Q@U@U@E@E?G?G?GAEAEAO@K?MBk@JsBFsA???KB]Ba@Dq@Dq@D]D{@LaBr@yFLy@PcAReAVaAPa@Pe@P[n@gAh@}@`@s@Tc@Vm@DOHUZqALq@PgAJ}@D}@DeABeA?eA?iA?q@Ay@Cm@Ew@GqAM}AEo@Aa@Ac@@c@Bk@Fk@D]DYLg@LYJYLSRWd@c@~@gA`AgAPUNSPYP]\\u@Rk@Pe@Le@Pu@Nw@Hc@Jy@LgAHsAF{@H}BF_AFy@NqAPkAVqA^mAf@{AVm@Zm@fB_DpJcP\\k@Tc@d@aAh@}AV{@d@uBZqAXsAJm@Lq@Hm@LaANsAJkAP}BRwCr@iL^eGT_DNmCHsADgA@i@@i@@y@?s@HwADgA?yA?i@Ac@A[A[Ca@E]Ky@_@iCG]EQESKUu@aBGMM[EQGYKc@CSESAO@M?O?MCKCKEGEEAAC?E[EYCY?Y?q@Ac@D{A@o@????Be@BaA@_A?a@?u@Ae@AUAKASCSEa@Ge@G]Ic@GWI[Uq@a@gAcAmCCGGEECCAGOACGOKUQKY{@EIu@kBUq@Oc@KWCEKUMWO_@KWAGGMiA}CiAwCEMGOUo@KWWq@Sk@AA??EMIU]{@MYKOMOEIIKIGAK?GCGCGGIECM?GIEIGOWy@EKEKCGIKCCCCOQCCAA[a@QSQU_@c@QU[_@i@o@KMCEOQIKkAyAMQY]KMAAAAACKKCEcAmAUU?M?IAOGyGAg@AQHQDK`AuBx@gB@Eh@cAh@gA??`@y@JSHSHWFOHWJ_@Lg@Pw@Lu@H_@De@Dg@Ba@@s@?s@Eq@GuAEs@MsBGqAEm@E}@C}@AcBAgA?e@?]?Q?U@_@@k@HoANiAT}B@SHu@F]D[J_@H[j@uBBK@EDOFe@@EDYH[VaAJ]@CFODIFG`AwAZa@??@AHKLOFC?A@?DA@?FA@?B?H@??D@F@NBF?D?FADCFCHGl@m@\\[LOFGFEBEDCDE@APMFChC_ALCNEDDB@F?BADEBIBK@OAOJy@VwCBWL_BD[DEBI@I?IAKB]Fi@JsAD{@HiALoAJ_AFg@@G??LeBLyANkBBSBQHk@BEBG@I?I?G?IAGCIACCAECA?C?C@C@ADCDAHAH?H?H@HBF?F?NAL?RMRILEHABINATKhAIbAIbAO`BALE`@ABGt@KlAKvAAL', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:28:00+01:00', + aimedEndTime: '2024-01-12T13:31:42+01:00', + expectedEndTime: '2024-01-12T13:31:42+01:00', + expectedStartTime: '2024-01-12T13:28:00+01:00', + realtime: false, + distance: 213.19, + duration: 222, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Oslo bussterminal', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'sptlJm|s`A??LoAB[@EPqB@MBa@JD@@FQ??D@HDJsA@@B@DBB@DBDB@@Fu@LwAHwA??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAANABFSQjpOU1I6UXVheToxMTk2MAARUkI6TlNSOlF1YXk6MTE0NDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjZlMjFkOWY5OGIyYmQ4MDg4YjlhN2M4ZjUzNGExOTg2', + mode: 'bus', + aimedStartTime: '2024-01-12T13:40:00+01:00', + aimedEndTime: '2024-01-12T13:59:00+01:00', + expectedEndTime: '2024-01-12T13:59:00+01:00', + expectedStartTime: '2024-01-12T13:40:00+01:00', + realtime: false, + distance: 6755.19, + duration: 1140, + fromPlace: { + name: 'Oslo bussterminal', + }, + toPlace: { + name: 'Alfaset', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Kjeller', + }, + }, + line: { + publicCode: '100', + name: 'Kjeller - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + '}ktlJynt`ADi@BQBSBQHk@BEBG@I?I?G?IAG@QBQBKH_@Ji@BNBN?DDUBGJm@BM?ARy@d@{Bt@mDZ{ANo@H[@E`@oBt@mDFUBM?CJe@DSFU@KHc@?GDe@Nq@TgAj@mC@A@KBMFa@x@wE@E??F_@l@iDXcB`@eCV_BDYV_@BE??LUBM?OOaBBa@VuC`@}D@KZwCb@iEZgDFk@BUKa@CKGWWqAe@{BOu@EMIc@C_@G[YwAAGM[EQI]EQMm@ScAG[Mq@??OaAKo@Ik@Is@Io@MqAQ_BC]YeCs@}GEi@Gi@KeAEY??E[Iu@Gc@Ga@G]Ic@Kc@i@aCa@aBMk@Kc@[sAIa@Kc@S_A?C??I[C_@AKAa@?W@G@E?GHSBMFYN_@Rm@FUDUBOBQ@O@Q@O?MD]@g@?_@BG@I@KAIAICIEEEAE?EDADADO?I?E?C?E@C@CBEFCBCDSd@EHEFCDEDCBE@E@A@C?I?EAIEECs@q@Uw@WcAe@qBeD_OS{ASgAOiAEy@Ca@?U?O@I@G?IAKCICECCCAA?C?CBEIKUKc@COG[Ge@OkAEU??AIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGBUGk@Ce@Ao@Ao@AWA[AQC]CWIe@COOgAMo@OaAGWcA}FCMUgA??AESaASu@WaA[gAUu@]cAWy@W{@K]wAsEIYKWMa@Qo@K_@I[CIAMCKAQ@M?Q@Y@QA]KKEGEEEIEOM_@AOK_AKaAIw@Ek@??CSGgAEy@Cs@AaAAs@Ay@As@?q@@yA@gDBsD@wD@_C?oDByD?_@@iB@gB@i@@m@@[@Y?EHg@@U@A@E@E?EAEAEACAAA?A?IIECGCOBG?C?[@[BYB_@FSDy@J??C@OBSEE?KAI?AEACCEEACAC@A@KIGKEGUa@KYQ_@o@oAeAuBiAyBS[MW]o@Wc@[c@[c@i@q@EG??c@i@[_@[]s@w@GIIIYc@EIGKIMGMAAAKAGCEEEEAC@A@KIGEEGQOYk@]s@[w@Um@Sk@IYIUESIYEWGYEYEWE_@Ge@Gk@Ec@C]C_@C_@A]GcBC_@A[Ca@EWCWE]G[G]Qy@Qy@e@yBS_AMq@GSCOEQCMKe@S_AAC', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:59:00+01:00', + aimedEndTime: '2024-01-12T14:14:09+01:00', + expectedEndTime: '2024-01-12T14:14:09+01:00', + expectedStartTime: '2024-01-12T13:59:00+01:00', + realtime: false, + distance: 1074.54, + duration: 909, + fromPlace: { + name: 'Alfaset', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'egxlJeigaA@A?BRz@DZA@ILEDA@}@aEAECIACCGAE?IUiA?CAEMaA_Br@KBI?GBGHKNW^w@jA]f@ORSRQLMHMBAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:56:02+01:00', + aimedEndTime: '2024-01-12T14:14:09+01:00', + expectedEndTime: '2024-01-12T14:14:09+01:00', + expectedStartTime: '2024-01-12T12:56:02+01:00', + duration: 4687, + distance: 26193.91, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:56:02+01:00', + aimedEndTime: '2024-01-12T13:00:09+01:00', + expectedEndTime: '2024-01-12T13:00:09+01:00', + expectedStartTime: '2024-01-12T12:56:02+01:00', + realtime: false, + distance: 291.84, + duration: 247, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA??', + }, + }, + { + id: 'rO0ABXeRABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAABkAAAAeABBSQjpOU1I6UXVheTo3OTI4ABBSQjpOU1I6UXVheTo3MjYzADtSQjpSVVQ6RGF0ZWRTZXJ2aWNlSm91cm5leToyOWIyODMyMDdlZDg3YmRmZjJlYWM4ODdiMTNlZGE2OA==', + mode: 'bus', + aimedStartTime: '2024-01-12T13:00:00+01:00', + aimedEndTime: '2024-01-12T13:07:00+01:00', + expectedEndTime: '2024-01-12T13:07:09+01:00', + expectedStartTime: '2024-01-12T13:00:09+01:00', + realtime: true, + distance: 3475.48, + duration: 420, + fromPlace: { + name: 'Slependen', + }, + toPlace: { + name: 'Sandvika bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Sandvika', + }, + }, + line: { + publicCode: '265', + name: 'Sandvika - Nesøya - Sandvika', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'yzmlJelb_A[a@QUo@y@WYIKIKQUGKCCEIIOQ]GKEKAGCEAEAICQMi@@I@MAOCKGIK_@E[AYCY?[?_@Dc@Di@LaAJs@B_@BYBY@k@AgAAa@Gi@CUEWG_@EOCMe@{ASq@GUGUMk@EUCSKs@G_@Ek@K_BGiAGg@G_@E[IYEWISO_@KQGKIIMQMKQOWSYSe@]WQOQIKQSOSU]Yg@QYOW??S[]m@y@wAq@mAa@s@Ua@Q_@MUQ[Wo@Yo@M[Ug@Q[CGCCCECEOQOSCKYWMIECCAKEMAIAOAS?I?KBM@]LWLCHe@PODMDQDG@G?K@M?I?IAMAMAKEKCICIE[MCKYOIEECCC?IAGAGCECECCA?C?A?EKCICGCICKIWEKCIUa@??aEaI[k@S]EKEKCIAGGMGK?GAOCMGKGEG?GBGHCHAJAJKLML}@jAe@\\EMGGGAEk@AS?S@QBOFO~AoDzAoDz@wBP]HBHCFIDM@Q?QAOEMGIICIBOOOSSQQ_@Q_@???AO[O]o@eBWu@Ws@k@iBe@aBMYEIIMGEEAEAG@GDIFUV??UZKHSHKBO?SCQGKGKMOQKYK_@E]C[ASA[A}BB[@_@@]?M?MAKEKEECAE?EBCFCFALMPU\\WLUPYV[\\e@l@s@lAq@nAmAnBY\\_@Zc@^[V]@WJCCEAE?C@EFCHCL?F?D@F@F@FBFBBD@D?PX\\l@b@nBRDFDFNd@hB^xALb@d@nBBL?LALCJCFEBE@E?EGEIi@_CI_@[kA]uA', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:07:09+01:00', + aimedEndTime: '2024-01-12T13:09:59+01:00', + expectedEndTime: '2024-01-12T13:09:59+01:00', + expectedStartTime: '2024-01-12T13:07:09+01:00', + realtime: false, + distance: 189.05, + duration: 170, + fromPlace: { + name: 'Sandvika bussterminal', + }, + toPlace: { + name: 'Sandvika stasjon', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'm{plJ}uf_A??nAbD@DB?@DH?L?LOVYS_As@_E@?', + }, + }, + { + id: 'rO0ABXeDABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAEAAAAEAA9SQjpOU1I6UXVheTo5OTMAD1JCOk5TUjpRdWF5OjQ3NwAvUkI6TlNCOkRhdGVkU2VydmljZUpvdXJuZXk6MzE5X0FTUi1MSE1fMjQtMDEtMTI=', + mode: 'rail', + aimedStartTime: '2024-01-12T13:15:00+01:00', + aimedEndTime: '2024-01-12T13:27:00+01:00', + expectedEndTime: '2024-01-12T13:27:10+01:00', + expectedStartTime: '2024-01-12T13:15:00+01:00', + realtime: true, + distance: 12466.92, + duration: 730, + fromPlace: { + name: 'Sandvika stasjon', + }, + toPlace: { + name: 'Nationaltheatret stasjon', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Lillehammer', + }, + }, + line: { + publicCode: 'RE10', + name: 'Drammen-Oslo S-Lillehammer', + }, + authority: { + name: 'Vy', + }, + pointsOnLink: { + points: + '{xplJ{yf_AAEo@kC_@yA]uAo@aC_@wAYgAc@gBWiAWmAa@aBGYQu@q@uCe@oB??e@sB[yAUeAOs@UkA]cBQcAOw@O}@My@o@}Dk@sDuA{I{B{NqAoIe@yCq@{DcAoFs@aDq@iCs@mCw@eCi@cBs@qByAsD}DqI}CgGiAyB}@gB{@kBu@cBs@_By@qBu@kBm@_B{@cCo@kBs@wBq@uBcAiDq@aCe@iBe@kBg@qBe@oBk@iCe@wBc@wB_@sBY{Ae@iCm@qDi@oD_@eCi@}De@uDi@aFi@gF_@eEi@_Hq@wJeCy]k@iIqNarBc@yGWaFUqEMuCMeDIeDI}CGiCGkCCcCEwDGcGs@ax@EsGCwBAqB@_A?w@@o@B{@Bk@@o@Du@Do@Fw@Fq@Fs@Fm@Fi@Ju@Z{B\\iC`@{CJq@Js@NmAPsAHw@JeAHmALgBF}ABsABsA?G?????u@?_AAuAAy@Ai@Ac@Cq@A_@Ci@Ck@Ei@G{@IgAOgBOqB[}D??YcDEo@KiAKcAIs@Kq@MaAQgASoAO{@SeAWkAc@qBm@eC[iAQs@Oo@Om@Mm@Kg@Mo@Ko@Ku@Ks@Iu@I}@I_AGeAEw@GiAEcAIyBEs@Eq@GcAIy@Ek@Iw@Ii@Im@Ig@O{@Km@S_AUaAU}@[aAY{@Ww@u@yBQi@Wo@k@cBe@wAYy@Y{@??a@sAOg@uA_F_@oAYeAi@mBi@iBi@gBe@wA[}@qDoKc@qAY_Aa@sASw@Qu@Oo@Om@Ms@O{@Mq@Ii@MaAKw@Gk@Ee@C]Ee@Cc@Ci@Co@Cs@?[Aa@??AaA?o@?i@@]@q@@m@D}@F{@H}@Hy@Ju@PeARmA~@cFLo@????BMp@wD^uBN}@PcARmARwAZ_CPuAPiAPcARgAVuATmAHa@Lq@Lo@ReALo@Lm@??VsANu@RgAJm@Jq@NaANmAR_BN_BNeBL_BHqADeAD}@DgABu@B{@@_A@y@@y@@cA?iAA{AAeAA_AAy@C_ACy@C_AMsDKkCGiB??KyCKiDE_BC{AAkA?eAAeA@oA@kA@gABwADoAD_BH{AFaAFiAHgAFaAl@}Jn@}JPoCLuBPeCLuALsALoALkANkATaBn@oE|@_GfAqH@KVcBNaAP}@f@kCTmAVsA??XyAb@aCLo@NcALw@Ho@Hq@Hw@HgAHaADu@Dw@H}Ab@_K??', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:27:10+01:00', + aimedEndTime: '2024-01-12T13:32:00+01:00', + expectedEndTime: '2024-01-12T13:32:00+01:00', + expectedStartTime: '2024-01-12T13:27:10+01:00', + realtime: false, + distance: 326.35, + duration: 290, + fromPlace: { + name: 'Nationaltheatret stasjon', + }, + toPlace: { + name: 'Nationaltheatret', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '_fulJefn`A??l@yJNqD@OCSCWWeCCQKcAEOEQ]f@SCt@cB??', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAsAAAARABBSQjpOU1I6UXVheTo3MzMzABFSQjpOU1I6UXVheToxMTEzNAA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6NzQzMTQyMWUzM2FlNDU2YmMzOTQ5OWEyMTAyN2M2Mzg=', + mode: 'metro', + aimedStartTime: '2024-01-12T13:34:00+01:00', + aimedEndTime: '2024-01-12T13:44:00+01:00', + expectedEndTime: '2024-01-12T13:44:00+01:00', + expectedStartTime: '2024-01-12T13:34:00+01:00', + realtime: true, + distance: 4410.74, + duration: 600, + fromPlace: { + name: 'Nationaltheatret', + }, + toPlace: { + name: 'Helsfyr', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Ellingsrudåsen', + }, + }, + line: { + publicCode: '2', + name: 'Østerås - Ellingsrudåsen', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'seulJ{co`AHMTm@FKBa@@KJu@NuAL{@Jw@Lu@Ls@Hk@Lo@?AVyAf@oCLs@Lw@Ho@Js@Fs@Hu@HwADaADkAD}@?WP{EDo@Fm@LiELeD??By@NmEBy@Du@Bk@JgAJcAL_APeAX{A\\aBd@iCL_AJ{@H{@Bi@@g@@e@FgCBcA?OHuD??@[JyE@uA@oAAiAGaAGy@Iy@M{@{@sEOeAIo@IiAEkAAeA?qAH}H??@i@D}DDqC@y@@e@B{@Be@H_ArAeMR}BFuA@yAEwAIsAO{ASqAWgAa@mAe@_Ag@m@mByB]k@[q@Yy@YkASkAQsAYkCKy@Ko@Ms@Ka@Me@Ma@O_@O_@Sa@Yi@uAeCa@u@??w@yAQc@Oa@K[K_@Ma@Mg@g@uBOk@Oi@Mc@Oa@O[Q[QYEc@Cs@Am@Am@@o@@g@@g@Bi@Di@De@Fc@Fc@Hg@Nm@Ja@La@N_@N]R_@RYPYVUTSRMPIPIl@WRITKNKNMLKNQPSRYLULUHSJUHUJYHUNc@Lg@Pk@Lg@Lg@P{@Ha@n@{CH]R}@??`@mBH_@Lq@DYDYD]Da@B]Dg@@_@Bi@@g@?c@?c@Ae@A_@Ck@Eo@?AWwCEq@Eq@Cu@Cw@Cc@Ao@?m@?k@?q@?y@@k@B{@j@oOD}@FgAHw@LuANgAn@uFHw@', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:44:00+01:00', + aimedEndTime: '2024-01-12T13:44:32+01:00', + expectedEndTime: '2024-01-12T13:44:32+01:00', + expectedStartTime: '2024-01-12T13:44:00+01:00', + realtime: false, + distance: 33.93, + duration: 32, + fromPlace: { + name: 'Helsfyr', + }, + toPlace: { + name: 'Helsfyr T', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '_utlJws|`ABBAb@i@G??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAYAAAANABFSQjpOU1I6UXVheToxMTE0MgARUkI6TlNSOlF1YXk6MTE0NDIAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjZlMjFkOWY5OGIyYmQ4MDg4YjlhN2M4ZjUzNGExOTg2', + mode: 'bus', + aimedStartTime: '2024-01-12T13:49:00+01:00', + aimedEndTime: '2024-01-12T13:59:00+01:00', + expectedEndTime: '2024-01-12T13:59:00+01:00', + expectedStartTime: '2024-01-12T13:49:00+01:00', + realtime: false, + distance: 3925.06, + duration: 600, + fromPlace: { + name: 'Helsfyr T', + }, + toPlace: { + name: 'Alfaset', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Kjeller', + }, + }, + line: { + publicCode: '100', + name: 'Kjeller - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'wvtlJsr|`AAIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGBUGk@Ce@Ao@Ao@AWA[AQC]CWIe@COOgAMo@OaAGWcA}FCMUgA??AESaASu@WaA[gAUu@]cAWy@W{@K]wAsEIYKWMa@Qo@K_@I[CIAMCKAQ@M?Q@Y@QA]KKEGEEEIEOM_@AOK_AKaAIw@Ek@??CSGgAEy@Cs@AaAAs@Ay@As@?q@@yA@gDBsD@wD@_C?oDByD?_@@iB@gB@i@@m@@[@Y?EHg@@U@A@E@E?EAEAEACAAA?A?IIECGCOBG?C?[@[BYB_@FSDy@J??C@OBSEE?KAI?AEACCEEACAC@A@KIGKEGUa@KYQ_@o@oAeAuBiAyBS[MW]o@Wc@[c@[c@i@q@EG??c@i@[_@[]s@w@GIIIYc@EIGKIMGMAAAKAGCEEEEAC@A@KIGEEGQOYk@]s@[w@Um@Sk@IYIUESIYEWGYEYEWE_@Ge@Gk@Ec@C]C_@C_@A]GcBC_@A[Ca@EWCWE]G[G]Qy@Qy@e@yBS_AMq@GSCOEQCMKe@S_AAC', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:59:00+01:00', + aimedEndTime: '2024-01-12T14:14:09+01:00', + expectedEndTime: '2024-01-12T14:14:09+01:00', + expectedStartTime: '2024-01-12T13:59:00+01:00', + realtime: false, + distance: 1074.54, + duration: 909, + fromPlace: { + name: 'Alfaset', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'egxlJeigaA@A?BRz@DZA@ILEDA@}@aEAECIACCGAE?IUiA?CAEMaA_Br@KBI?GBGHKNW^w@jA]f@ORSRQLMHMBAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:56:02+01:00', + aimedEndTime: '2024-01-12T14:17:28+01:00', + expectedEndTime: '2024-01-12T14:17:28+01:00', + expectedStartTime: '2024-01-12T12:56:02+01:00', + duration: 4886, + distance: 28471.820000000003, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:56:02+01:00', + aimedEndTime: '2024-01-12T13:00:09+01:00', + expectedEndTime: '2024-01-12T13:00:09+01:00', + expectedStartTime: '2024-01-12T12:56:02+01:00', + realtime: false, + distance: 291.84, + duration: 247, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA??', + }, + }, + { + id: 'rO0ABXeRABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAABkAAAAeABBSQjpOU1I6UXVheTo3OTI4ABBSQjpOU1I6UXVheTo3MjYzADtSQjpSVVQ6RGF0ZWRTZXJ2aWNlSm91cm5leToyOWIyODMyMDdlZDg3YmRmZjJlYWM4ODdiMTNlZGE2OA==', + mode: 'bus', + aimedStartTime: '2024-01-12T13:00:00+01:00', + aimedEndTime: '2024-01-12T13:07:00+01:00', + expectedEndTime: '2024-01-12T13:07:09+01:00', + expectedStartTime: '2024-01-12T13:00:09+01:00', + realtime: true, + distance: 3475.48, + duration: 420, + fromPlace: { + name: 'Slependen', + }, + toPlace: { + name: 'Sandvika bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Sandvika', + }, + }, + line: { + publicCode: '265', + name: 'Sandvika - Nesøya - Sandvika', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'yzmlJelb_A[a@QUo@y@WYIKIKQUGKCCEIIOQ]GKEKAGCEAEAICQMi@@I@MAOCKGIK_@E[AYCY?[?_@Dc@Di@LaAJs@B_@BYBY@k@AgAAa@Gi@CUEWG_@EOCMe@{ASq@GUGUMk@EUCSKs@G_@Ek@K_BGiAGg@G_@E[IYEWISO_@KQGKIIMQMKQOWSYSe@]WQOQIKQSOSU]Yg@QYOW??S[]m@y@wAq@mAa@s@Ua@Q_@MUQ[Wo@Yo@M[Ug@Q[CGCCCECEOQOSCKYWMIECCAKEMAIAOAS?I?KBM@]LWLCHe@PODMDQDG@G?K@M?I?IAMAMAKEKCICIE[MCKYOIEECCC?IAGAGCECECCA?C?A?EKCICGCICKIWEKCIUa@??aEaI[k@S]EKEKCIAGGMGK?GAOCMGKGEG?GBGHCHAJAJKLML}@jAe@\\EMGGGAEk@AS?S@QBOFO~AoDzAoDz@wBP]HBHCFIDM@Q?QAOEMGIICIBOOOSSQQ_@Q_@???AO[O]o@eBWu@Ws@k@iBe@aBMYEIIMGEEAEAG@GDIFUV??UZKHSHKBO?SCQGKGKMOQKYK_@E]C[ASA[A}BB[@_@@]?M?MAKEKEECAE?EBCFCFALMPU\\WLUPYV[\\e@l@s@lAq@nAmAnBY\\_@Zc@^[V]@WJCCEAE?C@EFCHCL?F?D@F@F@FBFBBD@D?PX\\l@b@nBRDFDFNd@hB^xALb@d@nBBL?LALCJCFEBE@E?EGEIi@_CI_@[kA]uA', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:07:09+01:00', + aimedEndTime: '2024-01-12T13:09:59+01:00', + expectedEndTime: '2024-01-12T13:09:59+01:00', + expectedStartTime: '2024-01-12T13:07:09+01:00', + realtime: false, + distance: 189.05, + duration: 170, + fromPlace: { + name: 'Sandvika bussterminal', + }, + toPlace: { + name: 'Sandvika stasjon', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'm{plJ}uf_A??nAbD@DB?@DH?L?LOVYS_As@_E@?', + }, + }, + { + id: 'rO0ABXeDABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAEAAAAFAA9SQjpOU1I6UXVheTo5OTMAD1JCOk5TUjpRdWF5OjU3MQAvUkI6TlNCOkRhdGVkU2VydmljZUpvdXJuZXk6MzE5X0FTUi1MSE1fMjQtMDEtMTI=', + mode: 'rail', + aimedStartTime: '2024-01-12T13:15:00+01:00', + aimedEndTime: '2024-01-12T13:31:00+01:00', + expectedEndTime: '2024-01-12T13:31:00+01:00', + expectedStartTime: '2024-01-12T13:15:00+01:00', + realtime: true, + distance: 14113.62, + duration: 960, + fromPlace: { + name: 'Sandvika stasjon', + }, + toPlace: { + name: 'Oslo S', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Lillehammer', + }, + }, + line: { + publicCode: 'RE10', + name: 'Drammen-Oslo S-Lillehammer', + }, + authority: { + name: 'Vy', + }, + pointsOnLink: { + points: + '{xplJ{yf_AAEo@kC_@yA]uAo@aC_@wAYgAc@gBWiAWmAa@aBGYQu@q@uCe@oB??e@sB[yAUeAOs@UkA]cBQcAOw@O}@My@o@}Dk@sDuA{I{B{NqAoIe@yCq@{DcAoFs@aDq@iCs@mCw@eCi@cBs@qByAsD}DqI}CgGiAyB}@gB{@kBu@cBs@_By@qBu@kBm@_B{@cCo@kBs@wBq@uBcAiDq@aCe@iBe@kBg@qBe@oBk@iCe@wBc@wB_@sBY{Ae@iCm@qDi@oD_@eCi@}De@uDi@aFi@gF_@eEi@_Hq@wJeCy]k@iIqNarBc@yGWaFUqEMuCMeDIeDI}CGiCGkCCcCEwDGcGs@ax@EsGCwBAqB@_A?w@@o@B{@Bk@@o@Du@Do@Fw@Fq@Fs@Fm@Fi@Ju@Z{B\\iC`@{CJq@Js@NmAPsAHw@JeAHmALgBF}ABsABsA?G?????u@?_AAuAAy@Ai@Ac@Cq@A_@Ci@Ck@Ei@G{@IgAOgBOqB[}D??YcDEo@KiAKcAIs@Kq@MaAQgASoAO{@SeAWkAc@qBm@eC[iAQs@Oo@Om@Mm@Kg@Mo@Ko@Ku@Ks@Iu@I}@I_AGeAEw@GiAEcAIyBEs@Eq@GcAIy@Ek@Iw@Ii@Im@Ig@O{@Km@S_AUaAU}@[aAY{@Ww@u@yBQi@Wo@k@cBe@wAYy@Y{@??a@sAOg@uA_F_@oAYeAi@mBi@iBi@gBe@wA[}@qDoKc@qAY_Aa@sASw@Qu@Oo@Om@Ms@O{@Mq@Ii@MaAKw@Gk@Ee@C]Ee@Cc@Ci@Co@Cs@?[Aa@??AaA?o@?i@@]@q@@m@D}@F{@H}@Hy@Ju@PeARmA~@cFLo@????BMp@wD^uBN}@PcARmARwAZ_CPuAPiAPcARgAVuATmAHa@Lq@Lo@ReALo@Lm@??VsANu@RgAJm@Jq@NaANmAR_BN_BNeBL_BHqADeAD}@DgABu@B{@@_A@y@@y@@cA?iAA{AAeAA_AAy@C_ACy@C_AMsDKkCGiB??KyCKiDE_BC{AAkA?eAAeA@oA@kA@gABwADoAD_BH{AFaAFiAHgAFaAl@}Jn@}JPoCLuBPeCLuALsALoALkANkATaBn@oE|@_GfAqH@KVcBNaAP}@f@kCTmAVsA??XyAb@aCLo@NcALw@Ho@Hq@Hw@HgAHaADu@Dw@H}Ab@_K????d@gKF_BBs@Dw@DaBBaABs@Bm@Bm@@_@B[B_@Bg@Do@B_@D]Fu@??Fs@Fq@J_AJw@Fk@Hk@Jo@Jq@F_@Lu@Nw@??ZcBPeA\\gBN_ANu@Lu@L{@Jm@Ly@L_ANkAHw@Hs@H_AL}AHqAHkAFsAF{ADoABmAHgDDuABgADcAFy@F_AF}@H_AH{@LqAJ{@??@[B]@]??F[DUFa@Fe@Hs@He@L{@Ny@??P_AJg@Lk@Lk@Rs@Po@J_@H[J]Nk@Lo@Pq@Jm@Lm@Lw@??^iCf@_D??', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:31:00+01:00', + aimedEndTime: '2024-01-12T13:38:59+01:00', + expectedEndTime: '2024-01-12T13:38:59+01:00', + expectedStartTime: '2024-01-12T13:31:00+01:00', + realtime: false, + distance: 436.66, + duration: 479, + fromPlace: { + name: 'Oslo S', + }, + toPlace: { + name: 'Bjørvika', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + '_gtlJuqs`A??FHER?BCH\\ZZXZXXXBG?EDSb@{B@@@OB@D?F?B?b@yCBMDSXqALFP@BAD?DCDEBGBKBKBIB?@?NJHHLNHH@@@@?@?@BB?BAFADNJp@`@NJ@K?CFc@?G??CC?A?A@A@A?A?ACC????AAAAFc@FYF]AA', + }, + }, + { + id: 'rO0ABXeSABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAEAAAAFABBSQjpOU1I6UXVheTo3MTY5ABFSQjpOU1I6UXVheToxMDQwMgA7UkI6UlVUOkRhdGVkU2VydmljZUpvdXJuZXk6YzA3MTEwYjI3YjM5N2VmZmUwMTRjZDgxYTEzNzhhODI=', + mode: 'bus', + aimedStartTime: '2024-01-12T13:43:00+01:00', + aimedEndTime: '2024-01-12T13:54:00+01:00', + expectedEndTime: '2024-01-12T13:54:00+01:00', + expectedStartTime: '2024-01-12T13:43:00+01:00', + realtime: false, + distance: 8270.2, + duration: 660, + fromPlace: { + name: 'Bjørvika', + }, + toPlace: { + name: 'Trosterud', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Blystadlia', + }, + }, + line: { + publicCode: '300', + name: 'Blystadlia - Ahus - Oslo bussterminal', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'wwslJe~s`ADU`@oCF[`@mCRuAFa@Hg@XeBPiAFc@Fc@ZsBPgAHk@PJr@`@lHhEJFxEnCLHPHPJNFNDHBH@PBP@ZCPCNEPEFANGPIRKZQv@a@pCyAVMHCDABAB?BAD?DFDBD@DADCDGBK@KXQ\\ID?Z?VGBGDI\\s@b@gAl@oB^yAXwARkAPuAL_AJaALwBHwBBmBAoBEuCKmBWcDMoAKqA}BeToAsLg@mEi@wFm@iF[wBi@cCi@sBg@yAe@eAKQk@cAeDyD[]IKSU_BgBs@y@{@cAe@k@k@m@a@e@a@g@uAkB]e@_@m@a@w@Wq@So@WaAM{@QkAM{AKeBMwCQiGGuBG_BKyAMiAOw@Os@Ws@[q@_@i@]]]UYMWEYCW?UDSDUJSLULWT}AtA[VWPYLUFG@]DUCMCMG[SWWSYUa@Qc@Uw@WcAe@qBeD_OS{ASgAOiAEy@Ca@?U?O@I@G?IAKCICECCCAA?C?CBEIKUKc@COG[Ge@OkAEU??AIGg@M_AIc@K]GUMc@Uo@q@gBo@yA{B_G_BeEeCyGiBaFeAqC]_Ae@qAY_AMa@??IWSu@Mi@Ke@Mk@Oq@Ki@[iB[cBk@iDqAyHc@eCMs@??Ii@i@wCKi@Ke@COMk@Ou@YsAk@oCoAcGo@{CWiAYiAcAmDqBeHgBiGqBcHc@cBc@eBUgASiAQoAIi@Gi@ScCKaBKmBMuBCw@CiB?{BAiBAuA?yA?sA@yB@gC@{D?{A?{A?qA?sAAuAAqACuACqAEwAEkACiAGmAGqAI{AKkBKsAKoAKqAMmAMqAGm@K{@MgAM{@UeBWaBSsAc@oCa@kCSwAYsBQqAQ}AQ{AMqAMkAQuBm@yGOcB]cDMoAYwBWmBc@mC_@qB_@mBi@sDSiAe@}BOu@Oq@YeAOk@Qg@Wu@Oe@Q[M[Wk@We@EI', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:54:00+01:00', + aimedEndTime: '2024-01-12T14:17:28+01:00', + expectedEndTime: '2024-01-12T14:17:28+01:00', + expectedStartTime: '2024-01-12T13:54:00+01:00', + realtime: false, + distance: 1694.97, + duration: 1408, + fromPlace: { + name: 'Trosterud', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: + 'sywlJw}haA?A?ECOAM@K?G@E@I@EBCBEFCPEBABCBC@E@G@K@YBSBSDKJQIMCCCCCAE?G@k@JG?IAKESMGCK?I?GDGFGLYt@_@|@Ul@c@bAOZCFAFAFAFAPAVCZAF?HCNGAI@IFIHILKTUh@iA`Cc@dAw@rBQd@M^Od@Mh@Mh@Mb@GPGNINGDI@i@b@YPC@OHQFUHUHu@TBz@BlALADAD?DBFBJHHPCHIx@ABK`AIh@CNIb@Ir@Y~CO~BAbD@fA@`ADtADv@s@?ODm@l@SPGJENGNEPI\\GGC?C?ORGZHLCJ?BV\\BDBH@J@NANAJEJEJUf@IN@@DLcApBmA`CIPKREREX@XBXSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + { + aimedStartTime: '2024-01-12T12:41:00+01:00', + aimedEndTime: '2024-01-12T14:18:50+01:00', + expectedEndTime: '2024-01-12T14:18:50+01:00', + expectedStartTime: '2024-01-12T12:41:00+01:00', + duration: 5870, + distance: 35115.93, + legs: [ + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:41:00+01:00', + aimedEndTime: '2024-01-12T12:45:07+01:00', + expectedEndTime: '2024-01-12T12:45:07+01:00', + expectedStartTime: '2024-01-12T12:41:00+01:00', + realtime: false, + distance: 291.84, + duration: 247, + fromPlace: { + name: 'Origin', + }, + toPlace: { + name: 'Slependen', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'o`nlJaac_AZ|@\\z@On@MAk@~@UZ@J@HEX@RLv@@DJVVd@LRNR\\^p@t@|@fA??', + }, + }, + { + id: 'rO0ABXeRABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAA8AAAAUABBSQjpOU1I6UXVheTo3OTI4ABBSQjpOU1I6UXVheTo3MjY1ADtSQjpSVVQ6RGF0ZWRTZXJ2aWNlSm91cm5leTpiYzAwOGYwN2YxYzRhMDQ1YzE5ZjEwY2Q3MTQyZDliMQ==', + mode: 'bus', + aimedStartTime: '2024-01-12T12:43:00+01:00', + aimedEndTime: '2024-01-12T12:48:00+01:00', + expectedEndTime: '2024-01-12T12:50:07+01:00', + expectedStartTime: '2024-01-12T12:45:07+01:00', + realtime: true, + distance: 3232.21, + duration: 300, + fromPlace: { + name: 'Slependen', + }, + toPlace: { + name: 'Sandvika bussterminal', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Sandvika', + }, + }, + line: { + publicCode: '270', + name: 'Asker - Sandvika (- Fornebu)', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'yzmlJelb_A[a@QUo@y@WYIKIKQUGKCCEIIOQ]GKEKAGCEAEAICQMi@@I@MAOCKGIK_@E[AYCY?[?_@Dc@Di@LaAJs@B_@BYBY@k@AgAAa@Gi@CUEWG_@EOCMe@{ASq@GUGUMk@EUCSKs@G_@Ek@K_BGiAGg@G_@E[IYEWISO_@KQGKIIMQMKQOWSYSe@]WQOQIKQSOSU]Yg@QYOW??S[]m@y@wAq@mAa@s@Ua@Q_@MUQ[Wo@Yo@M[Ug@Q[CGCCCECEOQOSCKYWMIECCAKEMAIAOAS?I?KBM@]LWLCHe@PODMDQDG@G?K@M?I?IAMAMAKEKCICIE[MCKYOIEECCC?IAGAGCECECCA?C?A?EKCICGCICKIWEKCIUa@??aEaI[k@S]EKEKCIAGGMGK?GAOCMGKGEG?GBGHCHAJAJKLML}@jAe@\\EMGGGAMDEJEPAPBV[jAYzA]nB]bBs@lCYv@E@EBEHCJCL?L@F?D@DEVCNEP{@jCm@|A??O\\MZKRIRCDKGMKOQ?A?AAAAC?AAECUCUAM?A??C_@AIASCY]}E?MC]AKEm@AOCa@ASAKAUCUCQCQAMAKIk@_@cCMy@Eg@?C@C?GAEAEAAEOM_AU{ASuAKi@K_@IUUUMOI?{@aBWi@M_@I[GSK]Qw@UcAYuAQy@IYIUKUGq@EY@MLWnA_BNQBBD@D?PX\\l@b@nBRDFDFNd@hB^xABJ', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T12:50:07+01:00', + aimedEndTime: '2024-01-12T12:52:07+01:00', + expectedEndTime: '2024-01-12T12:52:07+01:00', + expectedStartTime: '2024-01-12T12:50:07+01:00', + realtime: false, + distance: 125.59, + duration: 120, + fromPlace: { + name: 'Sandvika bussterminal', + }, + toPlace: { + name: 'Sandvika stasjon', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '}xplJ{pf_A?@@DB?@DH?L?LOVYS_A_AqD??', + }, + }, + { + id: 'rO0ABXeEABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAYAAAARAA9SQjpOU1I6UXVheTo5OTAAD1JCOk5TUjpRdWF5OjYwNAAwUkI6TlNCOkRhdGVkU2VydmljZUpvdXJuZXk6MjEzNF9BU1ItTExTXzI0LTAxLTEy', + mode: 'rail', + aimedStartTime: '2024-01-12T13:02:00+01:00', + aimedEndTime: '2024-01-12T13:37:00+01:00', + expectedEndTime: '2024-01-12T13:37:20+01:00', + expectedStartTime: '2024-01-12T13:02:00+01:00', + realtime: true, + distance: 24463.5, + duration: 2120, + fromPlace: { + name: 'Sandvika stasjon', + }, + toPlace: { + name: 'Grorud stasjon', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Lillestrøm', + }, + }, + line: { + publicCode: 'L1', + name: 'Spikkestad-Oslo S-Lillestrøm', + }, + authority: { + name: 'Vy', + }, + pointsOnLink: { + points: + 'qyplJcyf_AkBeIi@_C]yAYmAc@kBWgAYoAaBkH{@oDmAmFUcAu@_D_@}A??u@gDi@yBEWOq@YkAUaA{@iDc@eBU{@WcAOo@Mm@Mq@Kk@Ig@Ii@Im@Io@I{@I_AEs@Es@Ew@CeACgAAy@?s@@w@@y@@o@By@B}@F}@F}@F{@Hy@J{@Ju@RqAz@iFRkAJm@Js@De@Fc@De@Dc@Dm@Fo@Bo@Ds@@k@Bk@@m@@k@?i@?m@?i@Ak@Au@Cq@Cq@Cu@Es@Gw@AI????Iy@Gi@Gg@Gi@Ig@Ig@Ie@Kg@G]Ka@K]W_AQm@Qi@c@qAQk@M]Ka@K_@Ke@Mg@I_@Ki@Kk@Ik@Im@Gi@Gm@Gm@Ek@Cm@Eo@Cy@Cw@Aq@Am@?_A?q@?{@HeTFyO@i@F}L?_A?o@?o@Ai@Ak@Ck@Ag@Ce@Ck@Cg@Ek@Gi@Ei@Iq@M_AO_AIg@SuAO{@CUw@gFa@mCm@kEMy@mByM????q@mEk@}DQkAQgA]qBUuAWsAUuAIc@g@uCQgAQiAk@aE??a@wC]gCSoASoAMy@Q}@UoAQw@Qy@Sw@U{@W}@Sq@Og@Qk@Oc@Wq@Si@Uk@i@sAUk@Ys@Um@Qe@Oe@Sm@Om@Sq@Oi@Qu@Oo@Ou@Mq@Mo@Kq@Ms@Ks@K{@[{Bo@aFWkBSaBUgBMy@My@Ku@Ku@Mw@O_AO}@Ms@Q}@UkACK????ESOm@Qq@Mi@Og@_@mASs@Uw@a@wAUy@]kAs@cC]kAQs@]oAYeAWiAyA{F}AgGwAuFYmAUy@Sw@a@aB{AcGuAqFyA}F[kAWaAS{@Qq@U{@GYQq@[mAMe@I]Kc@Ka@Ig@Ke@Gc@Ii@Gg@Io@Ee@Gw@Ek@Cm@Ag@Ak@As@As@?s@@s@Bu@@m@Dm@Bq@Fu@Do@Fq@Fo@Fg@Hq@Z{B??JaAFk@Dg@??Jg@DWHc@Jm@??Js@Hq@RsAPsAJu@NiALgAHmAHoADkABeA@iA?E?????u@?aAAs@Cs@Cm@Ce@A_@Ce@Ei@IaAKgAG{@YmDK_AI}@Is@Iu@IcAYcDEo@KiAKcAIs@Kq@MaAQgASoAO{@SeAWkAc@qBm@eC[iAQs@Oo@Om@Mm@Kg@Mo@Ko@Ku@Ks@Iu@I}@I_AGeAEw@GiAEcAIyBEs@Eq@GcAIy@Ek@Iw@Ii@Im@Ig@O{@Km@S_AUaAU}@[aAY{@Ww@u@yBQi@Wo@k@cBe@wAYy@Y{@sAwD{@eCSm@??Sm@I_@Ka@IYMc@Si@??Mi@IYI[EU??Oc@GQMa@i@{AmEoMe@qA[}@Qo@Oc@Oo@Ka@Mk@Kg@Mk@G[E[M_A??Ig@Ic@CO??AOCYC]Kw@OsAE_@Ec@Eo@Ac@Cg@Ao@A}@A_A@cA?}@Bw@@o@??D}@Dy@H_AHy@H{@Hk@Ju@L}@x@cFJq@????BMDQj@eD|@kFX}AZgBXcBf@qCVuAN}@Nu@Nu@R{@XqA`@iBLo@Lm@??VsANu@RgAJm@Jq@NaANmAR_BN_BNeBL_BHqADeAD}@DgABu@B{@@_A@y@@y@@cA?iAA{AAeAA_AAy@C_ACy@C_AMsDKkCGiB??KyCKiDE_BC{AAkA?eAAeA@oA@kA@gABwADoAD_BH{AFaAFiAHgAFaAl@}Jn@}JPoCLuBPeCLuALsALoALkANkATaBn@oE|@_GfAqH@KVcBNaAP}@f@kCTmAVsA??XyAb@aCLo@NcALw@Ho@Hq@Hw@HgAHaADu@Dw@H}Ab@_K????d@gKF_BBs@Dw@DaBBaABs@Bm@Bm@@_@B[B_@Bg@Do@B_@D]Fu@??Fs@Fq@J_AJw@Fk@Hk@Jo@Jq@F_@Lu@Nw@??ZcBPeA\\gBN_ANu@Lu@L{@Jm@Ly@L_ANkAHw@Hs@H_AL}AHqAHkAFsAF{ADoABmAHgDDuABgADcAFy@F_AF}@H_AH{@LqAJ{@??@[B]@]??F[DUFa@Fe@Hs@He@L{@Ny@??RuALw@Jk@Jg@Ji@\\{AR}@Ns@N{@L_AVcB??^gCf@cD????p@qE|@eGh@iD??j@uDb@yCn@aE`@oCNaANgALiAJiADi@Fo@Dw@LwBFiA??Fm@Hu@PcBLsARoB??Z}CH}@`@wDXcDb@}DH_A??Dc@B_@Dq@@]Fk@H}@??Z{C??Ba@D_@@WB]@WDm@??TqBViCTgCL{ALyANiBLaBJqAHuAD_AHkADgADgADeAFqB@[Bu@BoA@y@BcA@mA@uA@}A?aA?_A?{A?}HAsF?mJA_F?qH?qBAsC?aB?oC?{BAoC?eH?mD?sD?gBAoB?kA?qB?qA?}@?k@Ak@?m@Aq@Ai@Ag@As@Cw@Cs@Cs@Ew@Eu@Ci@Gq@Eu@G{@KmAQmBYkDO_BOkBQuBw@aJScCQqBS_CS{BKwAOyAa@eFEe@??C_@C[Cq@AUCY??I_AGu@KmAGq@Gw@KaAIy@Go@Io@Im@ES????G_@Ko@Ke@[sAMg@Mk@Ok@Og@Qi@Sm@Oc@Oc@O]O_@Qa@Sa@Qa@k@kAQ_@u@{A??]o@Uc@S_@]m@Wc@OWEGYe@QW[c@W]QWSUMQSSUYOOo@o@c@a@[W[UWS]U[SUM_@Ue@Wq@][QYQYM_Ag@}BoAsEaCwC}AcAi@s@_@c@Wc@Uk@Yk@[u@a@w@a@cFkCyEgC??gCsA_B{@w@_@e@S]O]OWKWKSGsBs@SGWI[K[I[I_@GUEWE[C[C[C[AU?[@Y?W@a@BWD]DUBwATy@NoB\\a@F[Fa@F_@DO@I@W@[@Y?YAUAYCWE]G_@IYK]Ma@O_@Sa@Si@[MIQKu@c@yD}B????]S}D_Ci@]c@Y_@Wa@[_@Y[[_@[e@g@WYSUSYW]W]U_@Wa@Yc@Yg@Yi@Wi@Wi@Uk@Ug@Qe@Si@Um@Qi@Qk@So@Qo@Mc@Kc@EQKa@Mk@Sy@Qw@ScASaAOu@Qy@QaAO{@O_AOaAMy@MgAM_AKgAMkAIaAI_AIeAIcAImAIwAs@iL_BoXMuBK}AG{@Em@Gs@Gq@I_AIu@E_@Gi@Kw@Iq@Iq@M}@M}@Oy@QgAQcAk@yCWoA]gBI_@??u@}DmDwQcEkTMm@QaA_@iBSaAOw@CI????Kg@]aBQs@Qs@Oo@Oi@Ok@Mi@Sq@Qm@Sw@]iAgBeGe@_Be@aBW{@Qs@Qk@Ok@Mi@Kc@Mk@Qu@Mk@Ow@Mm@Kq@Kg@Mu@Kq@Ik@Ks@Ky@EWGe@YuBOeAKw@UuAEY??I]ESGSK_@EOK]Mc@GWOg@Kc@GQ??So@ESGQGYIUUo@??IQ[q@Q_@Sa@U_@w@oAY_@UYMQ??', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:37:20+01:00', + aimedEndTime: '2024-01-12T13:39:50+01:00', + expectedEndTime: '2024-01-12T13:39:50+01:00', + expectedStartTime: '2024-01-12T13:37:20+01:00', + realtime: false, + distance: 144.57, + duration: 150, + fromPlace: { + name: 'Grorud stasjon', + }, + toPlace: { + name: 'Stjerneblokkveien', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '}|{lJaomaA??c@m@Y[He@ACEEEEACFSHSLUR[V[DGBEBE@G@E@I?I?I?K?C??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAADYAAAA7ABFSQjpOU1I6UXVheToxMDMyNgARUkI6TlNSOlF1YXk6MTA3MjcAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OjZiZjc4NDcxYThmNmMxZTA3YzUyZmM0MmU1NmM5YmI0', + mode: 'bus', + aimedStartTime: '2024-01-12T13:45:00+01:00', + aimedEndTime: '2024-01-12T13:50:00+01:00', + expectedEndTime: '2024-01-12T13:50:00+01:00', + expectedStartTime: '2024-01-12T13:45:00+01:00', + realtime: false, + distance: 2078.2, + duration: 300, + fromPlace: { + name: 'Stjerneblokkveien', + }, + toPlace: { + name: 'Grorud T', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Grorud T', + }, + }, + line: { + publicCode: '79', + name: 'Grorud T - Åsbråten', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'w{{lJ_zmaA?FCd@@N?J@RA?KNKHKJKJQVMTGNGTERERc@dCKXEPGTINCBCDAFMZQZINQZKHMFQHQF??A?QDS?Y@gBFsBH]BO@G?O@K@A?m@B??M?e@BI@G@IDGFGJIPGPETGVEVY~AE\\APCR?N?T@TBJDLDNDJ`@v@NXDLHRJZJ\\d@lBH\\DZB^?V?ZAVEXEPIXGNIPKRKNORONKHGBCBMFSJMDQHIB??GDEBIFMJKJOTGFGLMVK\\CJAFEVEVC\\?JARGAA?E@MBMFLGLCDAH@?`@?v@E^CRADCHCFCDCBEDEBGFG?GCKGMIKKIKIKKSIQGQGWEOAGEWAUE]IsAG_AAUCYCUCOCKEKGGGGGGKEMAcACM?IAGCCAGEIGGKGMEOEQEUC[MaCC[CYEWESIQGMIIIEKCK?M@w@JOBI@G@o@FUB????C?WBi@BS?SGGAIAGAA?C?_@D[BS@S@W?S@MAG@I@I@mA?U??]Ag@?kA?a@M@QBK@I@BrB?V@R', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T13:50:00+01:00', + aimedEndTime: '2024-01-12T13:50:20+01:00', + expectedEndTime: '2024-01-12T13:50:20+01:00', + expectedStartTime: '2024-01-12T13:50:00+01:00', + realtime: false, + distance: 12.76, + duration: 20, + fromPlace: { + name: 'Grorud T', + }, + toPlace: { + name: 'Grorud T', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: '}a~lJ_qlaA??CDC?A?C@A?C??E??', + }, + }, + { + id: 'rO0ABXeTABhTQ0hFRFVMRURfVFJBTlNJVF9MRUdfVjMAAAAKMjAyNC0wMS0xMgAAAAAAAAAIABFSQjpOU1I6UXVheToxMDcyNAARUkI6TlNSOlF1YXk6MTAyNTkAO1JCOlJVVDpEYXRlZFNlcnZpY2VKb3VybmV5OmVhYzk2YWEyZjg0ZmY1ZTdmNDEzYTk5YjRmY2RlMzBk', + mode: 'bus', + aimedStartTime: '2024-01-12T14:07:00+01:00', + aimedEndTime: '2024-01-12T14:14:00+01:00', + expectedEndTime: '2024-01-12T14:14:00+01:00', + expectedStartTime: '2024-01-12T14:07:00+01:00', + realtime: false, + distance: 4457.24, + duration: 420, + fromPlace: { + name: 'Grorud T', + }, + toPlace: { + name: 'Postnord', + }, + toEstimatedCall: { + destinationDisplay: { + frontText: 'Helsfyr', + }, + }, + line: { + publicCode: '68', + name: 'Helsfyr T - Grorud T via Alfaset', + }, + authority: { + name: 'Ruter', + }, + pointsOnLink: { + points: + 'mb~lJcplaA???TH?H?F?DAH?JHL@?W?]Ag@?kA?a@?_C?OAS?O?}@?O@K@IBEBG@IHEFALENCHAFAH?F?HBDDDFDFBHFZBJBTBb@NrHHlDF|BBx@D|@Dp@D~@HvAJzAFt@Fz@LrALpAPxARdBRxAVzAPbAN~@XtAR~@Pv@Pt@Nl@ZjATx@Ph@FPPjALp@BJ??Jd@HNFNd@nAJVNTRTRRb@\\b@t@^n@x@tAr@dApAnBhA`BT\\PVRXRZ^b@NN??XZb@\\`@ZVLX`@\\XTNd@Vt@\\\\L\\NRJPFVFR@R@TAZCTCH?HB@BBD@BDBD@DADCDG@E@E?E@EFCDC@?D?PBF@HCFAd@LRD??@?HBPNHBHBDBFBJBDBFBXDHFf@b@JLHHNPTXRZXd@`@r@^l@`@r@T`@PXPVTXNRVTZTVPTLZLXJVFVDVDz@JNBx@H^DRHH@l@B??J@X@RBH?LBHBT@`@TVN\\VVRXVTTLNNPX`@\\f@T`@Zn@Rd@lCnGR`@P^PZR\\PVJLNPNN??B@LLFDNF\\JXRFBFBFDDHDFLR?FBD@DBDD@DABC@C`@[TIH@ZErAL|@Jp@FlAHh@BH@RJHFHHJLDJBFFFD@FADCDEDKBKHIHGHCNMF?PARANANAPCd@Ib@Gh@K^Il@@PCjA[TG??`A[JALCH?RBBDBBBVBT@HBPDb@?TBbABlBFvBBf@Fr@Dh@Ht@Jr@Np@Lj@Nd@N`@Rb@Td@PZh@x@NP~@nAzAjBHLVZRVNVI\\Sd@Q^GN??KTcApBmA`CIPKREREX@XBXDPdAxCJ\\l@bB', + }, + }, + { + id: null, + mode: 'foot', + aimedStartTime: '2024-01-12T14:14:00+01:00', + aimedEndTime: '2024-01-12T14:18:50+01:00', + expectedEndTime: '2024-01-12T14:18:50+01:00', + expectedStartTime: '2024-01-12T14:14:00+01:00', + realtime: false, + distance: 310.02, + duration: 290, + fromPlace: { + name: 'Postnord', + }, + toPlace: { + name: 'Destination', + }, + toEstimatedCall: null, + line: null, + authority: null, + pointsOnLink: { + points: 'q|xlJmweaACFA?m@aBBEDKK]eAyCEQSm@}@iCaAmCgAaE', + }, + }, + ], + systemNotices: [], + }, + ], + }, +}; + +it('renders without crashing', () => { + render( + {}} + pageResults={() => {}} + loading={false} + />, + ); +}); diff --git a/client-next/src/components/SearchBar/SearchBar.test.tsx b/client-next/src/components/SearchBar/SearchBar.test.tsx new file mode 100644 index 00000000000..88932190288 --- /dev/null +++ b/client-next/src/components/SearchBar/SearchBar.test.tsx @@ -0,0 +1,14 @@ +import { it } from 'vitest'; +import { render } from '@testing-library/react'; +import { SearchBar } from './SearchBar.tsx'; +import { TripQueryVariables } from '../../gql/graphql.ts'; + +const variables: TripQueryVariables = { + from: { coordinates: { longitude: 9.795206, latitude: 60.13776 } }, + to: { coordinates: { longitude: 11.50907, latitude: 59.85208 } }, + dateTime: new Date().toISOString(), +}; + +it('renders without crashing', () => { + render( {}} setTripQueryVariables={() => {}} tripQueryVariables={variables} />); +}); diff --git a/client-next/vite.config.ts b/client-next/vite.config.ts index 8d3ba8000c7..69bfec7f396 100644 --- a/client-next/vite.config.ts +++ b/client-next/vite.config.ts @@ -9,4 +9,8 @@ export default defineConfig({ outDir: 'output', emptyOutDir: true, }, + // @ts-ignore + test: { + environment: 'jsdom', + }, }); From 840ab9ce823acfda7529f3ec1f2898b48560bc74 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 14 Feb 2024 10:10:03 +0100 Subject: [PATCH 347/356] Account for a comma-separated list of X-Forwarded-Host --- .../framework/io/HttpUtils.java | 11 +++++- .../framework/io/HttpUtilsTest.java | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java diff --git a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java b/src/main/java/org/opentripplanner/framework/io/HttpUtils.java index 4981a8ab91b..d8b3dc542a6 100644 --- a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java +++ b/src/main/java/org/opentripplanner/framework/io/HttpUtils.java @@ -3,6 +3,7 @@ import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.UriInfo; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import org.apache.hc.core5.http.ContentType; public final class HttpUtils { @@ -31,7 +32,7 @@ public static String getBaseAddress(UriInfo uri, HttpHeaders headers) { String host; if (headers.getRequestHeader(HEADER_X_FORWARDED_HOST) != null) { - host = headers.getRequestHeader(HEADER_X_FORWARDED_HOST).getFirst(); + host = extractHost(headers.getRequestHeader(HEADER_X_FORWARDED_HOST).getFirst()); } else if (headers.getRequestHeader(HEADER_HOST) != null) { host = headers.getRequestHeader(HEADER_HOST).getFirst(); } else { @@ -40,4 +41,12 @@ public static String getBaseAddress(UriInfo uri, HttpHeaders headers) { return protocol + "://" + host; } + + /** + * The X-Forwarded-Host header can contain a comma-separated list so we account for that. + * https://stackoverflow.com/questions/66042952/http-proxy-behavior-for-x-forwarded-host-header + */ + private static String extractHost(String xForwardedFor) { + return Arrays.stream(xForwardedFor.split(",")).map(String::strip).toList().getFirst(); + } } diff --git a/src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java b/src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java new file mode 100644 index 00000000000..ac8ae52848c --- /dev/null +++ b/src/test/java/org/opentripplanner/framework/io/HttpUtilsTest.java @@ -0,0 +1,38 @@ +package org.opentripplanner.framework.io; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import java.util.Map; +import org.glassfish.jersey.server.internal.routing.UriRoutingContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.test.support.HttpForTest; + +class HttpUtilsTest { + + private static final String HOSTNAME = "example.com"; + + static List testCases() { + return List.of( + HOSTNAME, + "example.com,", + " example.com ,", + "example.com,example.com", + "example.com, example.com", + "example.com, example.net", + "example.com, example.net, example.com", + " example.com, example.net, example.com" + ); + } + + @ParameterizedTest + @MethodSource("testCases") + void extractHost(String headerValue) { + var req = HttpForTest.containerRequest(); + req.headers(Map.of("X-Forwarded-Host", List.of(headerValue))); + var uriInfo = new UriRoutingContext(req); + var baseAddress = HttpUtils.getBaseAddress(uriInfo, req); + assertEquals("https://" + HOSTNAME, baseAddress); + } +} From da66cb11497395a5c99c13b3f3b33e16a8a6abf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Wed, 14 Feb 2024 10:21:39 +0100 Subject: [PATCH 348/356] Fix package-lock --- client-next/package-lock.json | 5386 +++++++++++++++++++++++---------- 1 file changed, 3851 insertions(+), 1535 deletions(-) diff --git a/client-next/package-lock.json b/client-next/package-lock.json index b1dcfecb817..a6c92c55374 100644 --- a/client-next/package-lock.json +++ b/client-next/package-lock.json @@ -46,16 +46,18 @@ }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -66,8 +68,9 @@ }, "node_modules/@ardatan/relay-compiler": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", + "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.14.0", "@babel/generator": "^7.14.0", @@ -96,8 +99,9 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/cliui": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -106,8 +110,9 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/find-up": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -118,8 +123,9 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/locate-path": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -129,8 +135,9 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/p-limit": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -143,8 +150,9 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/p-locate": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -154,13 +162,15 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/y18n": { "version": "4.0.3", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true }, "node_modules/@ardatan/relay-compiler/node_modules/yargs": { "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -180,8 +190,9 @@ }, "node_modules/@ardatan/relay-compiler/node_modules/yargs-parser": { "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -192,8 +203,9 @@ }, "node_modules/@ardatan/sync-fetch": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz", + "integrity": "sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==", "dev": true, - "license": "MIT", "dependencies": { "node-fetch": "^2.6.1" }, @@ -203,8 +215,9 @@ }, "node_modules/@asamuzakjp/dom-selector": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz", + "integrity": "sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==", "dev": true, - "license": "MIT", "dependencies": { "bidi-js": "^1.0.3", "css-tree": "^2.3.1", @@ -213,8 +226,9 @@ }, "node_modules/@babel/code-frame": { "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -225,8 +239,9 @@ }, "node_modules/@babel/code-frame/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -236,8 +251,9 @@ }, "node_modules/@babel/code-frame/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -249,37 +265,42 @@ }, "node_modules/@babel/code-frame/node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/code-frame/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -289,27 +310,29 @@ }, "node_modules/@babel/compat-data": { "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.7", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", + "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.6", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.7", - "@babel/parser": "^7.23.6", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6", + "@babel/helpers": "^7.23.9", + "@babel/parser": "^7.23.9", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -326,8 +349,9 @@ }, "node_modules/@babel/generator": { "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", @@ -340,8 +364,9 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -351,8 +376,9 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-validator-option": "^7.23.5", @@ -365,9 +391,10 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.7", + "version": "7.23.10", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", + "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -388,16 +415,18 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -408,8 +437,9 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -419,8 +449,9 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.23.0" }, @@ -430,8 +461,9 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.15" }, @@ -441,8 +473,9 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -459,8 +492,9 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -470,16 +504,18 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", @@ -494,8 +530,9 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -505,8 +542,9 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -516,8 +554,9 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -527,36 +566,40 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.8", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", + "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6" + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9" }, "engines": { "node": ">=6.9.0" @@ -564,8 +607,9 @@ }, "node_modules/@babel/highlight": { "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -577,8 +621,9 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -588,8 +633,9 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -601,37 +647,42 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -640,9 +691,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.6", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -652,8 +704,10 @@ }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -667,8 +721,10 @@ }, "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.7", @@ -685,8 +741,9 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -696,8 +753,9 @@ }, "node_modules/@babel/plugin-syntax-flow": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", + "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -710,8 +768,9 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -724,8 +783,9 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -738,8 +798,9 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -749,8 +810,9 @@ }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -763,8 +825,9 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -777,8 +840,9 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -791,8 +855,9 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", @@ -812,8 +877,9 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/template": "^7.22.15" @@ -827,8 +893,9 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -841,8 +908,9 @@ }, "node_modules/@babel/plugin-transform-flow-strip-types": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", + "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-flow": "^7.23.3" @@ -856,8 +924,9 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -871,8 +940,9 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-function-name": "^7.23.0", @@ -887,8 +957,9 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -901,8 +972,9 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -915,8 +987,9 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", @@ -931,8 +1004,9 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20" @@ -946,8 +1020,9 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -960,8 +1035,9 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -974,8 +1050,9 @@ }, "node_modules/@babel/plugin-transform-react-display-name": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -988,8 +1065,9 @@ }, "node_modules/@babel/plugin-transform-react-jsx": { "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", @@ -1006,8 +1084,9 @@ }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1020,8 +1099,9 @@ }, "node_modules/@babel/plugin-transform-react-jsx-source": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1034,8 +1114,9 @@ }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1048,8 +1129,9 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1063,8 +1145,9 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1076,8 +1159,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.8", - "license": "MIT", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1086,22 +1170,24 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", + "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.7", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", + "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.6", @@ -1109,8 +1195,8 @@ "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1119,9 +1205,10 @@ } }, "node_modules/@babel/types": { - "version": "7.23.6", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", + "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -1133,229 +1220,586 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@esbuild/darwin-x64": { + "node_modules/@esbuild/android-arm": { "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "cpu": [ - "x64" + "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ - "darwin" + "android" ], "engines": { "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=12" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "(MIT OR CC0-1.0)", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@eslint/js": { - "version": "8.48.0", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@googlemaps/polyline-codec": { - "version": "1.0.28", - "license": "Apache-2.0" - }, - "node_modules/@graphql-codegen/add": { - "version": "5.0.0", + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", - "tslib": "~2.5.0" - }, - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@graphql-codegen/add/node_modules/tslib": { - "version": "2.5.3", + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "0BSD" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@graphql-codegen/cli": { - "version": "5.0.0", + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/generator": "^7.18.13", - "@babel/template": "^7.18.10", - "@babel/types": "^7.18.13", - "@graphql-codegen/core": "^4.0.0", - "@graphql-codegen/plugin-helpers": "^5.0.1", - "@graphql-tools/apollo-engine-loader": "^8.0.0", - "@graphql-tools/code-file-loader": "^8.0.0", - "@graphql-tools/git-loader": "^8.0.0", - "@graphql-tools/github-loader": "^8.0.0", - "@graphql-tools/graphql-file-loader": "^8.0.0", - "@graphql-tools/json-file-loader": "^8.0.0", - "@graphql-tools/load": "^8.0.0", - "@graphql-tools/prisma-loader": "^8.0.0", - "@graphql-tools/url-loader": "^8.0.0", - "@graphql-tools/utils": "^10.0.0", - "@whatwg-node/fetch": "^0.8.0", - "chalk": "^4.1.0", - "cosmiconfig": "^8.1.3", - "debounce": "^1.2.0", - "detect-indent": "^6.0.0", - "graphql-config": "^5.0.2", - "inquirer": "^8.0.0", - "is-glob": "^4.0.1", - "jiti": "^1.17.1", - "json-to-pretty-yaml": "^1.2.2", - "listr2": "^4.0.5", - "log-symbols": "^4.0.0", - "micromatch": "^4.0.5", - "shell-quote": "^1.7.3", - "string-env-interpolation": "^1.0.1", - "ts-log": "^2.2.3", - "tslib": "^2.4.0", - "yaml": "^2.3.1", - "yargs": "^17.0.0" - }, - "bin": { - "gql-gen": "cjs/bin.js", - "graphql-code-generator": "cjs/bin.js", - "graphql-codegen": "cjs/bin.js", - "graphql-codegen-esm": "esm/bin.js" - }, - "peerDependencies": { - "@parcel/watcher": "^2.1.0", - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" - }, - "peerDependenciesMeta": { - "@parcel/watcher": { - "optional": true - } + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@graphql-codegen/client-preset": { - "version": "4.1.0", + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/template": "^7.20.7", - "@graphql-codegen/add": "^5.0.0", - "@graphql-codegen/gql-tag-operations": "4.0.1", - "@graphql-codegen/plugin-helpers": "^5.0.1", - "@graphql-codegen/typed-document-node": "^5.0.1", - "@graphql-codegen/typescript": "^4.0.1", - "@graphql-codegen/typescript-operations": "^4.0.1", - "@graphql-codegen/visitor-plugin-common": "^4.0.1", - "@graphql-tools/documents": "^1.0.0", - "@graphql-tools/utils": "^10.0.0", - "@graphql-typed-document-node/core": "3.2.0", - "tslib": "~2.5.0" - }, - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@graphql-codegen/client-preset/node_modules/tslib": { - "version": "2.5.3", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "0BSD" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@graphql-codegen/core": { - "version": "4.0.0", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@googlemaps/polyline-codec": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/@googlemaps/polyline-codec/-/polyline-codec-1.0.28.tgz", + "integrity": "sha512-m7rh8sbxlrHvebXEweBHX8r1uPtToPRYxWDD6p6k2YG8hyhBe0Wi6xRUVFpxpEseMNgF+OBotFQC5senj8K7TQ==" + }, + "node_modules/@graphql-codegen/add": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-5.0.2.tgz", + "integrity": "sha512-ouBkSvMFUhda5VoKumo/ZvsZM9P5ZTyDsI8LW18VxSNWOjrTeLXBWHG8Gfaai0HwhflPtCYVABbriEcOmrRShQ==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", + "tslib": "~2.6.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-5.0.0.tgz", + "integrity": "sha512-A7J7+be/a6e+/ul2KI5sfJlpoqeqwX8EzktaKCeduyVKgOLA6W5t+NUGf6QumBDXU8PEOqXk3o3F+RAwCWOiqA==", + "dev": true, + "dependencies": { + "@babel/generator": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/types": "^7.18.13", + "@graphql-codegen/core": "^4.0.0", + "@graphql-codegen/plugin-helpers": "^5.0.1", + "@graphql-tools/apollo-engine-loader": "^8.0.0", + "@graphql-tools/code-file-loader": "^8.0.0", + "@graphql-tools/git-loader": "^8.0.0", + "@graphql-tools/github-loader": "^8.0.0", + "@graphql-tools/graphql-file-loader": "^8.0.0", + "@graphql-tools/json-file-loader": "^8.0.0", + "@graphql-tools/load": "^8.0.0", + "@graphql-tools/prisma-loader": "^8.0.0", + "@graphql-tools/url-loader": "^8.0.0", + "@graphql-tools/utils": "^10.0.0", + "@whatwg-node/fetch": "^0.8.0", + "chalk": "^4.1.0", + "cosmiconfig": "^8.1.3", + "debounce": "^1.2.0", + "detect-indent": "^6.0.0", + "graphql-config": "^5.0.2", + "inquirer": "^8.0.0", + "is-glob": "^4.0.1", + "jiti": "^1.17.1", + "json-to-pretty-yaml": "^1.2.2", + "listr2": "^4.0.5", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.5", + "shell-quote": "^1.7.3", + "string-env-interpolation": "^1.0.1", + "ts-log": "^2.2.3", + "tslib": "^2.4.0", + "yaml": "^2.3.1", + "yargs": "^17.0.0" + }, + "bin": { + "gql-gen": "cjs/bin.js", + "graphql-code-generator": "cjs/bin.js", + "graphql-codegen": "cjs/bin.js", + "graphql-codegen-esm": "esm/bin.js" + }, + "peerDependencies": { + "@parcel/watcher": "^2.1.0", + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "@parcel/watcher": { + "optional": true + } + } + }, + "node_modules/@graphql-codegen/client-preset": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/client-preset/-/client-preset-4.1.0.tgz", + "integrity": "sha512-/3Ymb/fjxIF1+HGmaI1YwSZbWsrZAWMSQjh3dU425eBjctjsVQ6gzGRr+l/gE5F1mtmCf+vlbTAT03heAc/QIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7", + "@graphql-codegen/add": "^5.0.0", + "@graphql-codegen/gql-tag-operations": "4.0.1", + "@graphql-codegen/plugin-helpers": "^5.0.1", + "@graphql-codegen/typed-document-node": "^5.0.1", + "@graphql-codegen/typescript": "^4.0.1", + "@graphql-codegen/typescript-operations": "^4.0.1", + "@graphql-codegen/visitor-plugin-common": "^4.0.1", + "@graphql-tools/documents": "^1.0.0", + "@graphql-tools/utils": "^10.0.0", + "@graphql-typed-document-node/core": "3.2.0", + "tslib": "~2.5.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/client-preset/node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true + }, + "node_modules/@graphql-codegen/core": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-4.0.2.tgz", + "integrity": "sha512-IZbpkhwVqgizcjNiaVzNAzm/xbWT6YnGgeOLwVjm4KbJn3V2jchVtuzHH09G5/WkkLSk2wgbXNdwjM41JxO6Eg==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.3", "@graphql-tools/schema": "^10.0.0", "@graphql-tools/utils": "^10.0.0", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-codegen/core/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, "node_modules/@graphql-codegen/gql-tag-operations": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.1.tgz", + "integrity": "sha512-qF6wIbBzW8BNT+wiVsBxrYOs2oYcsxQ7mRvCpfEI3HnNZMAST/uX76W8MqFEJvj4mw7NIDv7xYJAcAZIWM5LWw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/visitor-plugin-common": "4.0.1", @@ -1367,15 +1811,38 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, + "node_modules/@graphql-codegen/gql-tag-operations/node_modules/@graphql-codegen/visitor-plugin-common": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-4.0.1.tgz", + "integrity": "sha512-Bi/1z0nHg4QMsAqAJhds+ForyLtk7A3HQOlkrZNm3xEkY7lcBzPtiOTLBtvziwopBsXUxqeSwVjOOFPLS5Yw1Q==", + "dev": true, + "dependencies": { + "@graphql-codegen/plugin-helpers": "^5.0.0", + "@graphql-tools/optimize": "^2.0.0", + "@graphql-tools/relay-operation-optimizer": "^7.0.0", + "@graphql-tools/utils": "^10.0.0", + "auto-bind": "~4.0.0", + "change-case-all": "1.0.15", + "dependency-graph": "^0.11.0", + "graphql-tag": "^2.11.0", + "parse-filepath": "^1.0.2", + "tslib": "~2.5.0" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, "node_modules/@graphql-codegen/gql-tag-operations/node_modules/tslib": { "version": "2.5.3", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true }, "node_modules/@graphql-codegen/introspection": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@graphql-codegen/introspection/-/introspection-4.0.0.tgz", + "integrity": "sha512-t9g3AkK99dfHblMWtG4ynUM9+A7JrWq5110zSpNV2wlSnv0+bRKagDW8gozwgXfR5i1IIG8QDjJZ6VgXQVqCZw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/visitor-plugin-common": "^4.0.0", @@ -1387,114 +1854,96 @@ }, "node_modules/@graphql-codegen/introspection/node_modules/tslib": { "version": "2.5.3", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true }, "node_modules/@graphql-codegen/plugin-helpers": { - "version": "5.0.1", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.3.tgz", + "integrity": "sha512-yZ1rpULIWKBZqCDlvGIJRSyj1B2utkEdGmXZTBT/GVayP4hyRYlkd36AJV/LfEsVD8dnsKL5rLz2VTYmRNlJ5Q==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-codegen/plugin-helpers/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, "node_modules/@graphql-codegen/schema-ast": { - "version": "4.0.0", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-4.0.2.tgz", + "integrity": "sha512-5mVAOQQK3Oz7EtMl/l3vOQdc2aYClUzVDHHkMvZlunc+KlGgl81j8TLa+X7ANIllqU4fUEsQU3lJmk4hXP6K7Q==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", + "@graphql-codegen/plugin-helpers": "^5.0.3", "@graphql-tools/utils": "^10.0.0", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-codegen/schema-ast/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, "node_modules/@graphql-codegen/typed-document-node": { - "version": "5.0.1", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.4.tgz", + "integrity": "sha512-t66Z6erQ4Dh1j6f9pRZmc8uYtHoUI3A49tLmJAlg9/3IV0kCmwrWKJut/G8SeOefDLG8cXBTVtI/YuZOe1Te+w==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", - "@graphql-codegen/visitor-plugin-common": "4.0.1", + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/visitor-plugin-common": "4.1.2", "auto-bind": "~4.0.0", "change-case-all": "1.0.15", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-codegen/typed-document-node/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, "node_modules/@graphql-codegen/typescript": { - "version": "4.0.1", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-4.0.4.tgz", + "integrity": "sha512-x79CKLfP9UQCX+/I78qxQlMs2Mmq3pF1lKafZo7lAno0f/fvJ+qWUduzdgjRNz+YL+5blGeWcC0pWEDxniO7hw==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", - "@graphql-codegen/schema-ast": "^4.0.0", - "@graphql-codegen/visitor-plugin-common": "4.0.1", + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/schema-ast": "^4.0.2", + "@graphql-codegen/visitor-plugin-common": "4.1.2", "auto-bind": "~4.0.0", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@graphql-codegen/typescript-operations": { - "version": "4.0.1", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-4.1.2.tgz", + "integrity": "sha512-CtCWK+gW7hS+Ely3lohr8CL1HVLswQzMcaUk3k1sxdWCWKTNq7abMsWa31rTVwRCJ+WNEkM/7S8sIBTpEG683A==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", - "@graphql-codegen/typescript": "^4.0.1", - "@graphql-codegen/visitor-plugin-common": "4.0.1", + "@graphql-codegen/plugin-helpers": "^5.0.3", + "@graphql-codegen/typescript": "^4.0.4", + "@graphql-codegen/visitor-plugin-common": "4.1.2", "auto-bind": "~4.0.0", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-codegen/typescript-operations/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, - "node_modules/@graphql-codegen/typescript/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, "node_modules/@graphql-codegen/visitor-plugin-common": { - "version": "4.0.1", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-4.1.2.tgz", + "integrity": "sha512-yk7iEAL1kYZ2Gi/pvVjdsZhul5WsYEM4Zcgh2Ev15VicMdJmPHsMhNUsZWyVJV0CaQCYpNOFlGD/11Ea3pn4GA==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-codegen/plugin-helpers": "^5.0.0", + "@graphql-codegen/plugin-helpers": "^5.0.3", "@graphql-tools/optimize": "^2.0.0", "@graphql-tools/relay-operation-optimizer": "^7.0.0", "@graphql-tools/utils": "^10.0.0", @@ -1503,21 +1952,17 @@ "dependency-graph": "^0.11.0", "graphql-tag": "^2.11.0", "parse-filepath": "^1.0.2", - "tslib": "~2.5.0" + "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-codegen/visitor-plugin-common/node_modules/tslib": { - "version": "2.5.3", - "dev": true, - "license": "0BSD" - }, "node_modules/@graphql-tools/apollo-engine-loader": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-8.0.0.tgz", + "integrity": "sha512-axQTbN5+Yxs1rJ6cWQBOfw3AEeC+fvIuZSfJLPLLvFJLj4pUm9fhxey/g6oQZAAQJqKPfw+tLDUQvnfvRK8Kmg==", "dev": true, - "license": "MIT", "dependencies": { "@ardatan/sync-fetch": "^0.0.1", "@graphql-tools/utils": "^10.0.0", @@ -1533,28 +1978,31 @@ }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, - "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.15", + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", + "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", "dev": true, - "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.5.0", - "urlpattern-polyfill": "^9.0.0" + "@whatwg-node/node-fetch": "^0.5.5", + "urlpattern-polyfill": "^10.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.4", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", + "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", "dev": true, - "license": "MIT", "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", @@ -1567,14 +2015,16 @@ } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "dev": true, - "license": "MIT" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true }, "node_modules/@graphql-tools/batch-execute": { "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-9.0.2.tgz", + "integrity": "sha512-Y2uwdZI6ZnatopD/SYfZ1eGuQFI7OU2KGZ2/B/7G9ISmgMl5K+ZZWz/PfIEXeiHirIDhyk54s4uka5rj2xwKqQ==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.5", "dataloader": "^2.2.2", @@ -1589,12 +2039,13 @@ } }, "node_modules/@graphql-tools/code-file-loader": { - "version": "8.0.3", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-8.1.0.tgz", + "integrity": "sha512-HKWW/B2z15ves8N9+xnVbGmFEVGyHEK80a4ghrjeTa6nwNZaKDVfq5CoYFfF0xpfjtH6gOVUExo2XCOEz4B8mQ==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-tools/graphql-tag-pluck": "8.1.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/graphql-tag-pluck": "8.2.0", + "@graphql-tools/utils": "^10.0.13", "globby": "^11.0.3", "tslib": "^2.4.0", "unixify": "^1.0.0" @@ -1608,8 +2059,9 @@ }, "node_modules/@graphql-tools/delegate": { "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-10.0.3.tgz", + "integrity": "sha512-Jor9oazZ07zuWkykD3OOhT/2XD74Zm6Ar0ENZMk75MDD51wB2UWUIMljtHxbJhV5A6UBC2v8x6iY0xdCGiIlyw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/batch-execute": "^9.0.1", "@graphql-tools/executor": "^1.0.0", @@ -1627,8 +2079,9 @@ }, "node_modules/@graphql-tools/documents": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/documents/-/documents-1.0.0.tgz", + "integrity": "sha512-rHGjX1vg/nZ2DKqRGfDPNC55CWZBMldEVcH+91BThRa6JeT80NqXknffLLEZLRUxyikCfkwMsk6xR3UNMqG0Rg==", "dev": true, - "license": "MIT", "dependencies": { "lodash.sortby": "^4.7.0", "tslib": "^2.4.0" @@ -1642,8 +2095,9 @@ }, "node_modules/@graphql-tools/executor": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.2.0.tgz", + "integrity": "sha512-SKlIcMA71Dha5JnEWlw4XxcaJ+YupuXg0QCZgl2TOLFz4SkGCwU/geAsJvUJFwK2RbVLpQv/UMq67lOaBuwDtg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "@graphql-typed-document-node/core": "3.2.0", @@ -1660,8 +2114,9 @@ }, "node_modules/@graphql-tools/executor-graphql-ws": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-1.1.0.tgz", + "integrity": "sha512-yM67SzwE8rYRpm4z4AuGtABlOp9mXXVy6sxXnTJRoYIdZrmDbKVfIY+CpZUJCqS0FX3xf2+GoHlsj7Qswaxgcg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.2", "@types/ws": "^8.0.0", @@ -1679,8 +2134,9 @@ }, "node_modules/@graphql-tools/executor-http": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor-http/-/executor-http-1.0.7.tgz", + "integrity": "sha512-/MoRYzQS50Tz5mxRfq3ZmeZ2SOins9wGZAGetsJ55F3PxL0PmHdSGlCq12KzffZDbwHV5YMlwigBsSGWq4y9Iw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.2", "@repeaterjs/repeater": "^3.0.4", @@ -1699,28 +2155,31 @@ }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/events": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, - "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/fetch": { - "version": "0.9.15", + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", + "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", "dev": true, - "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.5.0", - "urlpattern-polyfill": "^9.0.0" + "@whatwg-node/node-fetch": "^0.5.5", + "urlpattern-polyfill": "^10.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.4", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", + "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", "dev": true, - "license": "MIT", "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", @@ -1733,14 +2192,16 @@ } }, "node_modules/@graphql-tools/executor-http/node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "dev": true, - "license": "MIT" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true }, "node_modules/@graphql-tools/executor-legacy-ws": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-1.0.5.tgz", + "integrity": "sha512-w54AZ7zkNuvpyV09FH+eGHnnAmaxhBVHg4Yh2ICcsMfRg0brkLt77PlbjBuxZ4HY8XZnKJaYWf+tKazQZtkQtg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "@types/ws": "^8.0.0", @@ -1756,12 +2217,13 @@ } }, "node_modules/@graphql-tools/git-loader": { - "version": "8.0.3", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-8.0.4.tgz", + "integrity": "sha512-fBmKtnOVqzMT2N8L6nggM4skPq3y2t0eBITZJXCOuxeIlIRAeCOdjNLPKgyGb0rezIyGsn55DKMua5101VN0Sg==", "dev": true, - "license": "MIT", "dependencies": { - "@graphql-tools/graphql-tag-pluck": "8.1.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/graphql-tag-pluck": "8.2.0", + "@graphql-tools/utils": "^10.0.13", "is-glob": "4.0.3", "micromatch": "^4.0.4", "tslib": "^2.4.0", @@ -1776,8 +2238,9 @@ }, "node_modules/@graphql-tools/github-loader": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-8.0.0.tgz", + "integrity": "sha512-VuroArWKcG4yaOWzV0r19ElVIV6iH6UKDQn1MXemND0xu5TzrFme0kf3U9o0YwNo0kUYEk9CyFM0BYg4he17FA==", "dev": true, - "license": "MIT", "dependencies": { "@ardatan/sync-fetch": "^0.0.1", "@graphql-tools/executor-http": "^1.0.0", @@ -1796,28 +2259,31 @@ }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, - "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.15", + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", + "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", "dev": true, - "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.5.0", - "urlpattern-polyfill": "^9.0.0" + "@whatwg-node/node-fetch": "^0.5.5", + "urlpattern-polyfill": "^10.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.4", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", + "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", "dev": true, - "license": "MIT", "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", @@ -1830,14 +2296,16 @@ } }, "node_modules/@graphql-tools/github-loader/node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "dev": true, - "license": "MIT" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true }, "node_modules/@graphql-tools/graphql-file-loader": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-8.0.0.tgz", + "integrity": "sha512-wRXj9Z1IFL3+zJG1HWEY0S4TXal7+s1vVhbZva96MSp0kbb/3JBF7j0cnJ44Eq0ClccMgGCDFqPFXty4JlpaPg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/import": "7.0.0", "@graphql-tools/utils": "^10.0.0", @@ -1853,16 +2321,17 @@ } }, "node_modules/@graphql-tools/graphql-tag-pluck": { - "version": "8.1.0", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-8.2.0.tgz", + "integrity": "sha512-aGIuHxyrJB+LlUfXrH73NVlQTA6LkFbLKQzHojFuwXZJpf7wPkxceN2yp7VjMedARkLJg589IoXgZeMb1EztGQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.22.9", "@babel/parser": "^7.16.8", "@babel/plugin-syntax-import-assertions": "^7.20.0", "@babel/traverse": "^7.16.8", "@babel/types": "^7.16.8", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/utils": "^10.0.13", "tslib": "^2.4.0" }, "engines": { @@ -1874,8 +2343,9 @@ }, "node_modules/@graphql-tools/import": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-7.0.0.tgz", + "integrity": "sha512-NVZiTO8o1GZs6OXzNfjB+5CtQtqsZZpQOq+Uu0w57kdUkT4RlQKlwhT8T81arEsbV55KpzkpFsOZP7J1wdmhBw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "resolve-from": "5.0.0", @@ -1890,8 +2360,9 @@ }, "node_modules/@graphql-tools/json-file-loader": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-8.0.0.tgz", + "integrity": "sha512-ki6EF/mobBWJjAAC84xNrFMhNfnUFD6Y0rQMGXekrUgY0NdeYXHU0ZUgHzC9O5+55FslqUmAUHABePDHTyZsLg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.0", "globby": "^11.0.3", @@ -1907,8 +2378,9 @@ }, "node_modules/@graphql-tools/load": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-8.0.1.tgz", + "integrity": "sha512-qSMsKngJhDqRbuWyo3NvakEFqFL6+eSjy8ooJ1o5qYD26N7dqXkKzIMycQsX7rBK19hOuINAUSaRcVWH6hTccw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/schema": "^10.0.0", "@graphql-tools/utils": "^10.0.11", @@ -1924,8 +2396,9 @@ }, "node_modules/@graphql-tools/merge": { "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.1.tgz", + "integrity": "sha512-hIEExWO9fjA6vzsVjJ3s0cCQ+Q/BEeMVJZtMXd7nbaVefVy0YDyYlEkeoYYNV3NVVvu1G9lr6DM1Qd0DGo9Caw==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/utils": "^10.0.10", "tslib": "^2.4.0" @@ -1939,8 +2412,9 @@ }, "node_modules/@graphql-tools/optimize": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-2.0.0.tgz", + "integrity": "sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.4.0" }, @@ -1953,8 +2427,9 @@ }, "node_modules/@graphql-tools/prisma-loader": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-8.0.2.tgz", + "integrity": "sha512-8d28bIB0bZ9Bj0UOz9sHagVPW+6AHeqvGljjERtwCnWl8OCQw2c2pNboYXISLYUG5ub76r4lDciLLTU+Ks7Q0w==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/url-loader": "^8.0.0", "@graphql-tools/utils": "^10.0.8", @@ -1984,28 +2459,31 @@ }, "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, - "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.15", + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", + "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", "dev": true, - "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.5.0", - "urlpattern-polyfill": "^9.0.0" + "@whatwg-node/node-fetch": "^0.5.5", + "urlpattern-polyfill": "^10.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.4", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", + "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", "dev": true, - "license": "MIT", "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", @@ -2018,14 +2496,16 @@ } }, "node_modules/@graphql-tools/prisma-loader/node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "dev": true, - "license": "MIT" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true }, "node_modules/@graphql-tools/relay-operation-optimizer": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.0.tgz", + "integrity": "sha512-UNlJi5y3JylhVWU4MBpL0Hun4Q7IoJwv9xYtmAz+CgRa066szzY7dcuPfxrA7cIGgG/Q6TVsKsYaiF4OHPs1Fw==", "dev": true, - "license": "MIT", "dependencies": { "@ardatan/relay-compiler": "12.0.0", "@graphql-tools/utils": "^10.0.0", @@ -2040,8 +2520,9 @@ }, "node_modules/@graphql-tools/schema": { "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.2.tgz", + "integrity": "sha512-TbPsIZnWyDCLhgPGnDjt4hosiNU2mF/rNtSk5BVaXWnZqvKJ6gzJV4fcHcvhRIwtscDMW2/YTnK6dLVnk8pc4w==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/merge": "^9.0.1", "@graphql-tools/utils": "^10.0.10", @@ -2057,8 +2538,9 @@ }, "node_modules/@graphql-tools/url-loader": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-8.0.1.tgz", + "integrity": "sha512-B2k8KQEkEQmfV1zhurT5GLoXo8jbXP+YQHUayhCSxKYlRV7j/1Fhp1b21PDM8LXIDGlDRXaZ0FbWKOs7eYXDuQ==", "dev": true, - "license": "MIT", "dependencies": { "@ardatan/sync-fetch": "^0.0.1", "@graphql-tools/delegate": "^10.0.0", @@ -2083,28 +2565,31 @@ }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/events": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", + "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", "dev": true, - "license": "MIT", "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": { - "version": "0.9.15", + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", + "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", "dev": true, - "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.5.0", - "urlpattern-polyfill": "^9.0.0" + "@whatwg-node/node-fetch": "^0.5.5", + "urlpattern-polyfill": "^10.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.4", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", + "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", "dev": true, - "license": "MIT", "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", "@whatwg-node/events": "^0.1.0", @@ -2117,14 +2602,16 @@ } }, "node_modules/@graphql-tools/url-loader/node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "dev": true, - "license": "MIT" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true }, "node_modules/@graphql-tools/utils": { - "version": "10.0.12", + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.13.tgz", + "integrity": "sha512-fMILwGr5Dm2zefNItjQ6C2rauigklv69LIwppccICuGTnGaOp3DspLt/6Lxj72cbg5d9z60Sr+Egco3CJKLsNg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.0", @@ -2140,8 +2627,9 @@ }, "node_modules/@graphql-tools/wrap": { "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-10.0.1.tgz", + "integrity": "sha512-Cw6hVrKGM2OKBXeuAGltgy4tzuqQE0Nt7t/uAqnuokSXZhMHXJUb124Bnvxc2gPZn5chfJSDafDe4Cp8ZAVJgg==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/delegate": "^10.0.3", "@graphql-tools/schema": "^10.0.0", @@ -2158,15 +2646,17 @@ }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -2178,8 +2668,9 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -2190,21 +2681,24 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/schemas": { "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -2214,8 +2708,9 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2227,29 +2722,33 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.21", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2257,12 +2756,14 @@ }, "node_modules/@kamilkisiela/fast-url-parser": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz", + "integrity": "sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==", + "dev": true }, "node_modules/@mapbox/geojson-rewind": { "version": "0.5.2", - "license": "ISC", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", "dependencies": { "get-stream": "^6.0.1", "minimist": "^1.2.6" @@ -2273,127 +2774,361 @@ }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", "engines": { "node": ">= 0.6" } }, "node_modules/@mapbox/point-geometry": { "version": "0.1.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" }, "node_modules/@mapbox/tiny-sdf": { "version": "2.0.6", - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", + "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==" }, "node_modules/@mapbox/unitbezier": { "version": "0.0.1", - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==" }, "node_modules/@mapbox/vector-tile": { "version": "1.3.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", "dependencies": { "@mapbox/point-geometry": "~0.1.0" } }, "node_modules/@mapbox/whoots-js": { "version": "3.1.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "19.3.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", + "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^3.0.0", + "minimist": "^1.2.8", + "rw": "^1.3.3", + "sort-object": "^3.0.3" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.3.0.tgz", + "integrity": "sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.3.0", + "@parcel/watcher-darwin-arm64": "2.3.0", + "@parcel/watcher-darwin-x64": "2.3.0", + "@parcel/watcher-freebsd-x64": "2.3.0", + "@parcel/watcher-linux-arm-glibc": "2.3.0", + "@parcel/watcher-linux-arm64-glibc": "2.3.0", + "@parcel/watcher-linux-arm64-musl": "2.3.0", + "@parcel/watcher-linux-x64-glibc": "2.3.0", + "@parcel/watcher-linux-x64-musl": "2.3.0", + "@parcel/watcher-win32-arm64": "2.3.0", + "@parcel/watcher-win32-ia32": "2.3.0", + "@parcel/watcher-win32-x64": "2.3.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz", + "integrity": "sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz", + "integrity": "sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz", + "integrity": "sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz", + "integrity": "sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz", + "integrity": "sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz", + "integrity": "sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@maplibre/maplibre-gl-style-spec": { - "version": "19.3.3", - "license": "ISC", - "dependencies": { - "@mapbox/jsonlint-lines-primitives": "~2.0.2", - "@mapbox/unitbezier": "^0.0.1", - "json-stringify-pretty-compact": "^3.0.0", - "minimist": "^1.2.8", - "rw": "^1.3.3", - "sort-object": "^3.0.3" + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz", + "integrity": "sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" }, - "bin": { - "gl-style-format": "dist/gl-style-format.mjs", - "gl-style-migrate": "dist/gl-style-migrate.mjs", - "gl-style-validate": "dist/gl-style-validate.mjs" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz", + "integrity": "sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz", + "integrity": "sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz", + "integrity": "sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 8" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher": { + "node_modules/@parcel/watcher-win32-ia32": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz", + "integrity": "sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">= 10.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.3.0", - "@parcel/watcher-darwin-arm64": "2.3.0", - "@parcel/watcher-darwin-x64": "2.3.0", - "@parcel/watcher-freebsd-x64": "2.3.0", - "@parcel/watcher-linux-arm-glibc": "2.3.0", - "@parcel/watcher-linux-arm64-glibc": "2.3.0", - "@parcel/watcher-linux-arm64-musl": "2.3.0", - "@parcel/watcher-linux-x64-glibc": "2.3.0", - "@parcel/watcher-linux-x64-musl": "2.3.0", - "@parcel/watcher-win32-arm64": "2.3.0", - "@parcel/watcher-win32-ia32": "2.3.0", - "@parcel/watcher-win32-x64": "2.3.0" } }, - "node_modules/@parcel/watcher-darwin-x64": { + "node_modules/@parcel/watcher-win32-x64": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz", + "integrity": "sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { "node": ">= 10.0.0" @@ -2405,8 +3140,9 @@ }, "node_modules/@peculiar/asn1-schema": { "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz", + "integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==", "dev": true, - "license": "MIT", "dependencies": { "asn1js": "^3.0.5", "pvtsutils": "^1.3.5", @@ -2415,8 +3151,9 @@ }, "node_modules/@peculiar/json-schema": { "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -2425,15 +3162,16 @@ } }, "node_modules/@peculiar/webcrypto": { - "version": "1.4.3", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz", + "integrity": "sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw==", "dev": true, - "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/asn1-schema": "^2.3.8", "@peculiar/json-schema": "^1.1.12", - "pvtsutils": "^1.3.2", - "tslib": "^2.5.0", - "webcrypto-core": "^1.7.7" + "pvtsutils": "^1.3.5", + "tslib": "^2.6.2", + "webcrypto-core": "^1.7.8" }, "engines": { "node": ">=10.12.0" @@ -2441,7 +3179,8 @@ }, "node_modules/@popperjs/core": { "version": "2.11.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -2449,7 +3188,8 @@ }, "node_modules/@react-aria/ssr": { "version": "3.9.1", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.1.tgz", + "integrity": "sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==", "dependencies": { "@swc/helpers": "^0.5.0" }, @@ -2462,12 +3202,14 @@ }, "node_modules/@repeaterjs/repeater": { "version": "3.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.5.tgz", + "integrity": "sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA==", + "dev": true }, "node_modules/@restart/hooks": { - "version": "0.4.15", - "license": "MIT", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", "dependencies": { "dequal": "^2.0.3" }, @@ -2477,7 +3219,8 @@ }, "node_modules/@restart/ui": { "version": "1.6.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", "dependencies": { "@babel/runtime": "^7.21.0", "@popperjs/core": "^2.11.6", @@ -2496,39 +3239,200 @@ }, "node_modules/@restart/ui/node_modules/uncontrollable": { "version": "8.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", "peerDependencies": { "react": ">=16.14.0" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz", + "integrity": "sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz", + "integrity": "sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz", + "integrity": "sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.5", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz", + "integrity": "sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz", + "integrity": "sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz", + "integrity": "sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz", + "integrity": "sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz", + "integrity": "sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz", + "integrity": "sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz", + "integrity": "sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz", + "integrity": "sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz", + "integrity": "sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz", + "integrity": "sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, "node_modules/@swc/helpers": { - "version": "0.5.3", - "license": "Apache-2.0", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz", + "integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==", "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@testing-library/dom": { "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -2545,8 +3449,9 @@ }, "node_modules/@testing-library/react": { "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.1.2.tgz", + "integrity": "sha512-z4p7DVBTPjKM5qDZ0t5ZjzkpSNb+fZy1u6bzO7kk8oeGagpPCAtgh4cx1syrfp7a+QWkM021jGqjJaxJJnXAZg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^9.0.0", @@ -2562,50 +3467,60 @@ }, "node_modules/@types/aria-query": { "version": "5.0.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true }, "node_modules/@types/estree": { "version": "1.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, "node_modules/@types/geojson": { - "version": "7946.0.13", - "license": "MIT" + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true }, "node_modules/@types/js-yaml": { "version": "4.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true }, "node_modules/@types/json-schema": { "version": "7.0.15", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/json-stable-stringify": { "version": "1.0.36", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.36.tgz", + "integrity": "sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw==", + "dev": true }, "node_modules/@types/json5": { "version": "0.0.29", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true }, "node_modules/@types/mapbox__point-geometry": { "version": "0.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==" }, "node_modules/@types/mapbox__vector-tile": { "version": "1.3.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", @@ -2613,31 +3528,36 @@ } }, "node_modules/@types/mapbox-gl": { - "version": "2.7.19", - "license": "MIT", + "version": "2.7.21", + "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.7.21.tgz", + "integrity": "sha512-Dx9MuF2kKgT/N22LsMUB4b3acFZh9clVqz9zv1fomoiPoBrJolwYxpWA/9LPO/2N0xWbKi4V+pkjTaFkkx/4wA==", "dependencies": { "@types/geojson": "*" } }, "node_modules/@types/node": { - "version": "20.11.0", + "version": "20.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", + "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/pbf": { "version": "3.0.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" }, "node_modules/@types/prop-types": { "version": "15.7.11", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { "version": "18.2.21", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", + "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -2646,51 +3566,59 @@ }, "node_modules/@types/react-dom": { "version": "18.2.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", + "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", "dev": true, - "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/react-transition-group": { "version": "4.4.10", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dependencies": { "@types/react": "*" } }, "node_modules/@types/scheduler": { "version": "0.16.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "node_modules/@types/semver": { - "version": "7.5.6", - "dev": true, - "license": "MIT" + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", + "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "dev": true }, "node_modules/@types/supercluster": { "version": "7.1.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", "dependencies": { "@types/geojson": "*" } }, "node_modules/@types/warning": { "version": "3.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, "node_modules/@types/ws": { "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", + "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.5.0", @@ -2723,8 +3651,9 @@ }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -2733,9 +3662,10 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2748,13 +3678,15 @@ }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/@typescript-eslint/parser": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", + "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "6.5.0", "@typescript-eslint/types": "6.5.0", @@ -2780,8 +3712,9 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", + "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.5.0", "@typescript-eslint/visitor-keys": "6.5.0" @@ -2796,8 +3729,9 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", + "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "6.5.0", "@typescript-eslint/utils": "6.5.0", @@ -2822,8 +3756,9 @@ }, "node_modules/@typescript-eslint/types": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", "dev": true, - "license": "MIT", "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -2834,8 +3769,9 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.5.0", "@typescript-eslint/visitor-keys": "6.5.0", @@ -2860,8 +3796,9 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -2870,9 +3807,10 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2885,13 +3823,15 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/@typescript-eslint/utils": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", + "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -2914,8 +3854,9 @@ }, "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -2924,9 +3865,10 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2939,13 +3881,15 @@ }, "node_modules/@typescript-eslint/utils/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.5.0", "eslint-visitor-keys": "^3.4.1" @@ -2960,8 +3904,9 @@ }, "node_modules/@vitejs/plugin-react": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.4.tgz", + "integrity": "sha512-7wU921ABnNYkETiMaZy7XqpueMnpu5VxvVps13MjmCo+utBdD79sZzrApHawHtVX66cCJQQTXFcjH0y9dSUK8g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.22.9", "@babel/plugin-transform-react-jsx-self": "^7.22.5", @@ -2977,8 +3922,9 @@ }, "node_modules/@vitest/coverage-v8": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.1.3.tgz", + "integrity": "sha512-Uput7t3eIcbSTOTQBzGtS+0kah96bX+szW9qQrLeGe3UmgL2Akn8POnyC2lH7XsnREZOds9aCUTxgXf+4HX5RA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.1", "@bcoe/v8-coverage": "^0.2.3", @@ -3003,8 +3949,9 @@ }, "node_modules/@vitest/expect": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.1.3.tgz", + "integrity": "sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==", "dev": true, - "license": "MIT", "dependencies": { "@vitest/spy": "1.1.3", "@vitest/utils": "1.1.3", @@ -3016,8 +3963,9 @@ }, "node_modules/@vitest/runner": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.1.3.tgz", + "integrity": "sha512-Va2XbWMnhSdDEh/OFxyUltgQuuDRxnarK1hW5QNN4URpQrqq6jtt8cfww/pQQ4i0LjoYxh/3bYWvDFlR9tU73g==", "dev": true, - "license": "MIT", "dependencies": { "@vitest/utils": "1.1.3", "p-limit": "^5.0.0", @@ -3029,8 +3977,9 @@ }, "node_modules/@vitest/runner/node_modules/p-limit": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^1.0.0" }, @@ -3043,8 +3992,9 @@ }, "node_modules/@vitest/runner/node_modules/yocto-queue": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.20" }, @@ -3054,8 +4004,9 @@ }, "node_modules/@vitest/snapshot": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.1.3.tgz", + "integrity": "sha512-U0r8pRXsLAdxSVAyGNcqOU2H3Z4Y2dAAGGelL50O0QRMdi1WWeYHdrH/QWpN1e8juWfVKsb8B+pyJwTC+4Gy9w==", "dev": true, - "license": "MIT", "dependencies": { "magic-string": "^0.30.5", "pathe": "^1.1.1", @@ -3067,8 +4018,9 @@ }, "node_modules/@vitest/snapshot/node_modules/ansi-styles": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -3078,8 +4030,9 @@ }, "node_modules/@vitest/snapshot/node_modules/pretty-format": { "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -3091,13 +4044,15 @@ }, "node_modules/@vitest/snapshot/node_modules/react-is": { "version": "18.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, "node_modules/@vitest/spy": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.1.3.tgz", + "integrity": "sha512-Ec0qWyGS5LhATFQtldvChPTAHv08yHIOZfiNcjwRQbFPHpkih0md9KAbs7TfeIfL7OFKoe7B/6ukBTqByubXkQ==", "dev": true, - "license": "MIT", "dependencies": { "tinyspy": "^2.2.0" }, @@ -3107,8 +4062,9 @@ }, "node_modules/@vitest/utils": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.1.3.tgz", + "integrity": "sha512-Dyt3UMcdElTll2H75vhxfpZu03uFpXRCHxWnzcrFjZxT1kTbq8ALUYIeBgGolo1gldVdI0YSlQRacsqxTwNqwg==", "dev": true, - "license": "MIT", "dependencies": { "diff-sequences": "^29.6.3", "estree-walker": "^3.0.3", @@ -3121,8 +4077,9 @@ }, "node_modules/@vitest/utils/node_modules/ansi-styles": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -3132,8 +4089,9 @@ }, "node_modules/@vitest/utils/node_modules/pretty-format": { "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -3145,18 +4103,21 @@ }, "node_modules/@vitest/utils/node_modules/react-is": { "version": "18.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, "node_modules/@whatwg-node/events": { "version": "0.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz", + "integrity": "sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==", + "dev": true }, "node_modules/@whatwg-node/fetch": { "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.8.8.tgz", + "integrity": "sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg==", "dev": true, - "license": "MIT", "dependencies": { "@peculiar/webcrypto": "^1.4.0", "@whatwg-node/node-fetch": "^0.3.6", @@ -3167,8 +4128,9 @@ }, "node_modules/@whatwg-node/node-fetch": { "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz", + "integrity": "sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA==", "dev": true, - "license": "MIT", "dependencies": { "@whatwg-node/events": "^0.0.3", "busboy": "^1.6.0", @@ -3179,8 +4141,9 @@ }, "node_modules/acorn": { "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3190,24 +4153,27 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -3217,8 +4183,9 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, - "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3229,8 +4196,9 @@ }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3244,8 +4212,9 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -3258,16 +4227,18 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3280,31 +4251,38 @@ }, "node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/aria-query": { "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "deep-equal": "^2.0.5" } }, "node_modules/arr-union": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "engines": { "node": ">=0.10.0" } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3312,8 +4290,9 @@ }, "node_modules/array-includes": { "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3330,22 +4309,43 @@ }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3356,8 +4356,9 @@ }, "node_modules/array.prototype.flat": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3373,8 +4374,9 @@ }, "node_modules/array.prototype.flatmap": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3389,28 +4391,31 @@ } }, "node_modules/array.prototype.tosorted": { - "version": "1.1.2", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, - "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" }, "engines": { @@ -3422,13 +4427,15 @@ }, "node_modules/asap": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true }, "node_modules/asn1js": { "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "pvtsutils": "^1.3.2", "pvutils": "^1.1.3", @@ -3440,49 +4447,56 @@ }, "node_modules/assertion-error": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/assign-symbols": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "engines": { "node": ">=0.10.0" } }, "node_modules/ast-types-flow": { "version": "0.0.7", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "dev": true }, "node_modules/astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asynciterator.prototype": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", "dev": true, - "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" } }, "node_modules/asynckit": { "version": "0.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/auto-bind": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -3491,9 +4505,10 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.5", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", + "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3502,30 +4517,34 @@ } }, "node_modules/axe-core": { - "version": "4.8.3", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.4.tgz", + "integrity": "sha512-CZLSKisu/bhJ2awW4kJndluz2HLZYIHh5Uy1+ZwDRkJi69811xgIXXfdU9HSLX0Th+ILrHj8qfL/5wzamsFtQg==", "dev": true, - "license": "MPL-2.0", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } }, "node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", + "dev": true }, "node_modules/babel-preset-fbjs": { "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", "dev": true, - "license": "MIT", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", @@ -3561,11 +4580,14 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { @@ -3580,21 +4602,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/bidi-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "dev": true, - "license": "MIT", "dependencies": { "require-from-string": "^2.0.2" } }, "node_modules/bl": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, - "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -3603,6 +4626,8 @@ }, "node_modules/bootstrap": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz", + "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==", "funding": [ { "type": "github", @@ -3613,15 +4638,15 @@ "url": "https://opencollective.com/bootstrap" } ], - "license": "MIT", "peerDependencies": { "@popperjs/core": "^2.11.8" } }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3629,8 +4654,9 @@ }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -3639,7 +4665,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", + "version": "4.22.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", + "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", "dev": true, "funding": [ { @@ -3655,10 +4683,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001580", + "electron-to-chromium": "^1.4.648", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -3671,14 +4698,17 @@ }, "node_modules/bser": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { @@ -3694,7 +4724,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -3702,6 +4731,8 @@ }, "node_modules/busboy": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dev": true, "dependencies": { "streamsearch": "^1.1.0" @@ -3712,7 +4743,8 @@ }, "node_modules/bytewise": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", "dependencies": { "bytewise-core": "^1.2.2", "typewise": "^1.0.3" @@ -3720,27 +4752,35 @@ }, "node_modules/bytewise-core": { "version": "1.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", "dependencies": { "typewise-core": "^1.2" } }, "node_modules/cac": { "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/call-bind": { - "version": "1.0.5", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, - "license": "MIT", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3748,16 +4788,18 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camel-case": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, - "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" @@ -3765,14 +4807,17 @@ }, "node_modules/camelcase": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001576", + "version": "1.0.30001587", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", + "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", "dev": true, "funding": [ { @@ -3787,13 +4832,13 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/capital-case": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", "dev": true, - "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -3801,9 +4846,10 @@ } }, "node_modules/chai": { - "version": "4.4.0", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, - "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -3819,8 +4865,9 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3834,8 +4881,9 @@ }, "node_modules/change-case": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", "dev": true, - "license": "MIT", "dependencies": { "camel-case": "^4.1.2", "capital-case": "^1.0.4", @@ -3853,8 +4901,9 @@ }, "node_modules/change-case-all": { "version": "1.0.15", + "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz", + "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", "dev": true, - "license": "MIT", "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", @@ -3870,13 +4919,15 @@ }, "node_modules/chardet": { "version": "0.7.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true }, "node_modules/check-error": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, - "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, @@ -3886,20 +4937,23 @@ }, "node_modules/classnames": { "version": "2.5.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/clean-stack": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/cli-cursor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, - "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -3909,8 +4963,9 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" }, @@ -3920,8 +4975,9 @@ }, "node_modules/cli-truncate": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, - "license": "MIT", "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -3935,16 +4991,18 @@ }, "node_modules/cli-width": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, - "license": "ISC", "engines": { "node": ">= 10" } }, "node_modules/cliui": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -3956,8 +5014,9 @@ }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -3972,16 +5031,18 @@ }, "node_modules/clone": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3991,18 +5052,21 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4012,21 +5076,24 @@ }, "node_modules/common-tags": { "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4.0.0" } }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/constant-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", "dev": true, - "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -4035,13 +5102,15 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, "node_modules/cosmiconfig": { "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, - "license": "MIT", "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -4065,15 +5134,17 @@ }, "node_modules/cross-fetch": { "version": "3.1.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", "dependencies": { "node-fetch": "^2.6.12" } }, "node_modules/cross-inspect": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.0.tgz", + "integrity": "sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.4.0" }, @@ -4083,8 +5154,9 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4096,8 +5168,9 @@ }, "node_modules/css-tree": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dev": true, - "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -4108,8 +5181,9 @@ }, "node_modules/cssstyle": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", "dev": true, - "license": "MIT", "dependencies": { "rrweb-cssom": "^0.6.0" }, @@ -4119,17 +5193,20 @@ }, "node_modules/csstype": { "version": "3.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true }, "node_modules/data-urls": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, - "license": "MIT", "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" @@ -4140,18 +5217,21 @@ }, "node_modules/dataloader": { "version": "2.2.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.2.tgz", + "integrity": "sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==", + "dev": true }, "node_modules/debounce": { "version": "1.2.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true }, "node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -4166,21 +5246,24 @@ }, "node_modules/decamelize": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decimal.js": { "version": "10.4.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true }, "node_modules/deep-eql": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, - "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -4190,8 +5273,9 @@ }, "node_modules/deep-equal": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", "dev": true, - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.5", @@ -4221,13 +5305,15 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/defaults": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, - "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -4236,22 +5322,27 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, - "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -4266,39 +5357,44 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/dependency-graph": { "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/dequal": { "version": "2.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "engines": { "node": ">=6" } }, "node_modules/detect-indent": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/detect-libc": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, - "license": "Apache-2.0", "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -4308,16 +5404,18 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -4327,8 +5425,9 @@ }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4338,12 +5437,14 @@ }, "node_modules/dom-accessibility-api": { "version": "0.5.16", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true }, "node_modules/dom-helpers": { "version": "5.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -4351,50 +5452,57 @@ }, "node_modules/dot-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, - "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/dotenv": { - "version": "16.3.1", + "version": "16.4.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", + "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dset": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", + "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/earcut": { "version": "2.2.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", + "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" }, "node_modules/electron-to-chromium": { - "version": "1.4.629", - "dev": true, - "license": "ISC" + "version": "1.4.668", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.668.tgz", + "integrity": "sha512-ZOBocMYCehr9W31+GpMclR+KBaDZOoAEabLdhpZ8oU1JFDwIaFY0UDbpXVEUFc0BIP2O2Qn3rkfCjQmMR4T/bQ==", + "dev": true }, "node_modules/emoji-regex": { "version": "9.2.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/entities": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -4404,56 +5512,60 @@ }, "node_modules/error-ex": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { - "version": "1.22.3", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", + "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", + "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.8", "string.prototype.trimend": "^1.0.7", "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", + "typed-array-buffer": "^1.0.1", "typed-array-byte-length": "^1.0.0", "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -4462,10 +5574,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-get-iterator": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -4482,30 +5622,36 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.15", + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", + "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", "dev": true, - "license": "MIT", "dependencies": { "asynciterator.prototype": "^1.0.0", - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.1", - "es-set-tostringtag": "^2.0.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.2.1", + "es-abstract": "^1.22.4", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", + "internal-slot": "^1.0.7", "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.0.1" + "safe-array-concat": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-set-tostringtag": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, - "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2", "has-tostringtag": "^1.0.0", @@ -4517,16 +5663,18 @@ }, "node_modules/es-shim-unscopables": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, - "license": "MIT", "dependencies": { "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -4541,9 +5689,10 @@ }, "node_modules/esbuild": { "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -4576,17 +5725,19 @@ } }, "node_modules/escalade": { - "version": "3.1.1", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -4596,8 +5747,9 @@ }, "node_modules/eslint": { "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4649,8 +5801,9 @@ }, "node_modules/eslint-config-prettier": { "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", "dev": true, - "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4660,8 +5813,9 @@ }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -4670,16 +5824,18 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -4694,16 +5850,18 @@ }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import": { "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, - "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.findlastindex": "^1.2.2", @@ -4732,16 +5890,18 @@ }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4751,8 +5911,9 @@ }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", + "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.7", "aria-query": "^5.1.3", @@ -4780,8 +5941,9 @@ }, "node_modules/eslint-plugin-react": { "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", "dev": true, - "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flatmap": "^1.3.1", @@ -4809,8 +5971,9 @@ }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -4820,16 +5983,18 @@ }, "node_modules/eslint-plugin-react-refresh": { "version": "0.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz", + "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==", "dev": true, - "license": "MIT", "peerDependencies": { "eslint": ">=7" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4839,8 +6004,9 @@ }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -4855,8 +6021,9 @@ }, "node_modules/eslint-scope": { "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -4870,8 +6037,9 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4881,8 +6049,9 @@ }, "node_modules/eslint/node_modules/globals": { "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -4895,8 +6064,9 @@ }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -4906,8 +6076,9 @@ }, "node_modules/espree": { "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -4922,8 +6093,9 @@ }, "node_modules/esquery": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -4933,8 +6105,9 @@ }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -4944,32 +6117,36 @@ }, "node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estree-walker": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/execa": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -4990,8 +6167,9 @@ }, "node_modules/execa/node_modules/get-stream": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "license": "MIT", "engines": { "node": ">=16" }, @@ -5001,8 +6179,9 @@ }, "node_modules/execa/node_modules/mimic-fn": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -5012,8 +6191,9 @@ }, "node_modules/execa/node_modules/onetime": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -5026,8 +6206,9 @@ }, "node_modules/execa/node_modules/signal-exit": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC", "engines": { "node": ">=14" }, @@ -5037,7 +6218,8 @@ }, "node_modules/extend-shallow": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -5047,8 +6229,9 @@ }, "node_modules/external-editor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, - "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -5060,8 +6243,9 @@ }, "node_modules/extract-files": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", + "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", "dev": true, - "license": "MIT", "engines": { "node": "^12.20 || >= 14.13" }, @@ -5071,18 +6255,21 @@ }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "dev": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-glob": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5096,8 +6283,9 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -5107,50 +6295,57 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fast-querystring": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "dev": true, - "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "node_modules/fast-url-parser": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", "dev": true, - "license": "MIT", "dependencies": { "punycode": "^1.3.2" } }, "node_modules/fastq": { - "version": "1.16.0", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, "node_modules/fbjs": { "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", + "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", "dev": true, - "license": "MIT", "dependencies": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", @@ -5163,13 +6358,15 @@ }, "node_modules/fbjs-css-vars": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "dev": true }, "node_modules/figures": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -5182,16 +6379,18 @@ }, "node_modules/figures/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -5201,8 +6400,9 @@ }, "node_modules/fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5212,8 +6412,9 @@ }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -5227,8 +6428,9 @@ }, "node_modules/flat-cache": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, - "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -5240,21 +6442,24 @@ }, "node_modules/flatted": { "version": "3.2.9", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true }, "node_modules/for-each": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/form-data": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5266,13 +6471,16 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -5283,16 +6491,18 @@ }, "node_modules/function-bind": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -5308,57 +6518,68 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/geojson-vt": { "version": "3.2.1", - "license": "ISC" + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", + "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.2.2", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, - "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-stream": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "engines": { "node": ">=10" }, @@ -5367,12 +6588,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -5383,19 +6606,22 @@ }, "node_modules/get-value": { "version": "2.0.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "engines": { "node": ">=0.10.0" } }, "node_modules/gl-matrix": { "version": "3.4.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" }, "node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5413,8 +6639,9 @@ }, "node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -5424,7 +6651,8 @@ }, "node_modules/global-prefix": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -5436,7 +6664,8 @@ }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dependencies": { "isexe": "^2.0.0" }, @@ -5446,16 +6675,18 @@ }, "node_modules/globals": { "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globalthis": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.1.3" }, @@ -5468,8 +6699,9 @@ }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -5487,8 +6719,9 @@ }, "node_modules/gopd": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -5498,20 +6731,23 @@ }, "node_modules/graphemer": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/graphql": { "version": "16.8.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.0.tgz", + "integrity": "sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg==", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, "node_modules/graphql-config": { "version": "5.0.3", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-5.0.3.tgz", + "integrity": "sha512-BNGZaoxIBkv9yy6Y7omvsaBUHOzfFcII3UN++tpH8MGOKFPFkCPZuwx09ggANMt8FgyWP1Od8SWPmrUEZca4NQ==", "dev": true, - "license": "MIT", "dependencies": { "@graphql-tools/graphql-file-loader": "^8.0.0", "@graphql-tools/json-file-loader": "^8.0.0", @@ -5540,8 +6776,9 @@ }, "node_modules/graphql-config/node_modules/minimatch": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", + "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5551,7 +6788,8 @@ }, "node_modules/graphql-request": { "version": "6.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-6.1.0.tgz", + "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", "dependencies": { "@graphql-typed-document-node/core": "^3.2.0", "cross-fetch": "^3.1.5" @@ -5562,8 +6800,9 @@ }, "node_modules/graphql-tag": { "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.1.0" }, @@ -5575,9 +6814,10 @@ } }, "node_modules/graphql-ws": { - "version": "5.14.3", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.15.0.tgz", + "integrity": "sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -5587,34 +6827,38 @@ }, "node_modules/has": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/has-bigints": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, - "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5622,8 +6866,9 @@ }, "node_modules/has-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5633,8 +6878,9 @@ }, "node_modules/has-symbols": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5643,11 +6889,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, - "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -5657,9 +6904,10 @@ } }, "node_modules/hasown": { - "version": "2.0.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dev": true, - "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -5669,8 +6917,9 @@ }, "node_modules/header-case": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", "dev": true, - "license": "MIT", "dependencies": { "capital-case": "^1.0.4", "tslib": "^2.0.3" @@ -5678,8 +6927,9 @@ }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, - "license": "MIT", "dependencies": { "whatwg-encoding": "^3.1.1" }, @@ -5689,13 +6939,15 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, "node_modules/http-proxy-agent": { - "version": "7.0.0", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.1.tgz", + "integrity": "sha512-My1KCEPs6A0hb4qCVzYp8iEvA8j8YqcvXLZZH8C9OFuTYpYjHE7N2dtG3mRl1HMD4+VGXpF3XcDVcxGBT7yDZQ==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -5705,9 +6957,10 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.3.tgz", + "integrity": "sha512-kCnwztfX0KZJSLOBrcL0emLeFako55NWMovvyPP2AjsghNk9RB1yjSI+jVumPHYZsNXegNoqupSW9IY3afSH8w==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -5718,16 +6971,18 @@ }, "node_modules/human-signals": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/iconv-lite": { "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5737,6 +6992,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -5750,29 +7007,31 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/ignore": { - "version": "5.3.0", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immutable": { "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.8.0" } }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5786,16 +7045,18 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/import-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.2" }, @@ -5805,24 +7066,27 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5830,17 +7094,20 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/ini": { "version": "1.3.8", - "license": "ISC" + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inquirer": { "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -5863,11 +7130,12 @@ } }, "node_modules/internal-slot": { - "version": "1.0.6", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, - "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", + "es-errors": "^1.3.0", "hasown": "^2.0.0", "side-channel": "^1.0.4" }, @@ -5877,15 +7145,17 @@ }, "node_modules/invariant": { "version": "2.2.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/is-absolute": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, - "license": "MIT", "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" @@ -5896,8 +7166,9 @@ }, "node_modules/is-arguments": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5910,13 +7181,16 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5924,13 +7198,15 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-async-function": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5943,8 +7219,9 @@ }, "node_modules/is-bigint": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -5954,8 +7231,9 @@ }, "node_modules/is-boolean-object": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5969,8 +7247,9 @@ }, "node_modules/is-callable": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5980,8 +7259,9 @@ }, "node_modules/is-core-module": { "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -5991,8 +7271,9 @@ }, "node_modules/is-date-object": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6005,23 +7286,26 @@ }, "node_modules/is-extendable": { "version": "0.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-finalizationregistry": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6031,16 +7315,18 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-generator-function": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6053,8 +7339,9 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -6064,32 +7351,36 @@ }, "node_modules/is-interactive": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-lower-case": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", + "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/is-map": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-negative-zero": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6099,16 +7390,18 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-number-object": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6121,15 +7414,17 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-object": { "version": "2.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dependencies": { "isobject": "^3.0.1" }, @@ -6139,13 +7434,15 @@ }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true }, "node_modules/is-regex": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6159,8 +7456,9 @@ }, "node_modules/is-relative": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, - "license": "MIT", "dependencies": { "is-unc-path": "^1.0.0" }, @@ -6170,16 +7468,18 @@ }, "node_modules/is-set": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6189,8 +7489,9 @@ }, "node_modules/is-stream": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -6200,8 +7501,9 @@ }, "node_modules/is-string": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6214,8 +7516,9 @@ }, "node_modules/is-symbol": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6227,11 +7530,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, - "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -6242,8 +7546,9 @@ }, "node_modules/is-unc-path": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, - "license": "MIT", "dependencies": { "unc-path-regex": "^0.1.2" }, @@ -6253,8 +7558,9 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -6264,24 +7570,27 @@ }, "node_modules/is-upper-case": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", + "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/is-weakmap": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakref": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6291,8 +7600,9 @@ }, "node_modules/is-weakset": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -6303,48 +7613,55 @@ }, "node_modules/is-windows": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isarray": { "version": "2.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } }, "node_modules/isomorphic-ws": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", "dev": true, - "license": "MIT", "peerDependencies": { "ws": "*" } }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-report": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -6356,8 +7673,9 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -6369,8 +7687,9 @@ }, "node_modules/istanbul-reports": { "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -6381,8 +7700,9 @@ }, "node_modules/iterator.prototype": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "get-intrinsic": "^1.2.1", @@ -6393,28 +7713,32 @@ }, "node_modules/jiti": { "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", "dev": true, - "license": "MIT", "bin": { "jiti": "bin/jiti.js" } }, "node_modules/jose": { - "version": "5.2.0", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz", + "integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } }, "node_modules/js-tokens": { "version": "4.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6424,8 +7748,9 @@ }, "node_modules/jsdom": { "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.2.0.tgz", + "integrity": "sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==", "dev": true, - "license": "MIT", "dependencies": { "@asamuzakjp/dom-selector": "^2.0.1", "cssstyle": "^4.0.1", @@ -6463,8 +7788,9 @@ }, "node_modules/jsesc": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -6474,23 +7800,27 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify": { - "version": "1.1.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "isarray": "^2.0.5", @@ -6506,17 +7836,20 @@ }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/json-stringify-pretty-compact": { "version": "3.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==" }, "node_modules/json-to-pretty-yaml": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz", + "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==", "dev": true, - "license": "Apache-2.0", "dependencies": { "remedial": "^1.0.7", "remove-trailing-spaces": "^1.0.6" @@ -6527,8 +7860,9 @@ }, "node_modules/json5": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -6537,22 +7871,25 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "dev": true, - "license": "MIT" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true }, "node_modules/jsonify": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", "dev": true, - "license": "Public Domain", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/jsx-ast-utils": { "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, - "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -6565,40 +7902,46 @@ }, "node_modules/kdbush": { "version": "4.0.2", - "license": "ISC" + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" }, "node_modules/keyv": { "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kind-of": { "version": "6.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "engines": { "node": ">=0.10.0" } }, "node_modules/language-subtag-registry": { "version": "0.3.22", - "dev": true, - "license": "CC0-1.0" + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true }, "node_modules/language-tags": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "dev": true, - "license": "MIT", "dependencies": { "language-subtag-registry": "~0.3.2" } }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6609,13 +7952,15 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/listr2": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", "dev": true, - "license": "MIT", "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -6640,8 +7985,9 @@ }, "node_modules/listr2/node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6656,8 +8002,9 @@ }, "node_modules/local-pkg": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", "dev": true, - "license": "MIT", "dependencies": { "mlly": "^1.4.2", "pkg-types": "^1.0.3" @@ -6671,8 +8018,9 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -6685,23 +8033,27 @@ }, "node_modules/lodash": { "version": "4.17.21", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.sortby": { "version": "4.7.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -6715,8 +8067,9 @@ }, "node_modules/log-update": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", @@ -6732,8 +8085,9 @@ }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -6748,7 +8102,8 @@ }, "node_modules/loose-envify": { "version": "1.4.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -6758,48 +8113,54 @@ }, "node_modules/loupe": { "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, - "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } }, "node_modules/lower-case": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lower-case-first": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", + "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lru-cache": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/lz-string": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, - "license": "MIT", "bin": { "lz-string": "bin/bin.js" } }, "node_modules/magic-string": { - "version": "0.30.5", + "version": "0.30.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", + "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -6808,19 +8169,21 @@ } }, "node_modules/magicast": { - "version": "0.3.2", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.3.tgz", + "integrity": "sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/parser": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", "source-map-js": "^1.0.2" } }, "node_modules/make-dir": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -6833,8 +8196,9 @@ }, "node_modules/make-dir/node_modules/lru-cache": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -6843,9 +8207,10 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6858,13 +8223,15 @@ }, "node_modules/make-dir/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/map-cache": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6910,26 +8277,30 @@ }, "node_modules/mdn-data": { "version": "2.0.30", - "dev": true, - "license": "CC0-1.0" + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true }, "node_modules/merge-stream": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/meros": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz", + "integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==", "dev": true, - "license": "MIT", "engines": { "node": ">=13" }, @@ -6944,8 +8315,9 @@ }, "node_modules/micromatch": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -6956,16 +8328,18 @@ }, "node_modules/mime-db": { "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, - "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -6975,16 +8349,18 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6994,15 +8370,17 @@ }, "node_modules/minimist": { "version": "1.2.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/mlly": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.5.0.tgz", + "integrity": "sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==", "dev": true, - "license": "MIT", "dependencies": { "acorn": "^8.11.3", "pathe": "^1.1.2", @@ -7012,20 +8390,25 @@ }, "node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/murmurhash-js": { "version": "1.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" }, "node_modules/mute-stream": { "version": "0.0.8", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -7033,7 +8416,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7043,26 +8425,33 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/no-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, - "license": "MIT", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "node_modules/node-addon-api": { - "version": "7.0.0", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.0.tgz", + "integrity": "sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==", "dev": true, - "license": "MIT" + "engines": { + "node": "^16 || ^18 || >= 20" + } }, "node_modules/node-fetch": { "version": "2.7.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7080,15 +8469,18 @@ }, "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -7096,18 +8488,21 @@ }, "node_modules/node-int64": { "version": "0.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true }, "node_modules/node-releases": { "version": "2.0.14", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, "node_modules/normalize-path": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, - "license": "MIT", "dependencies": { "remove-trailing-separator": "^1.0.1" }, @@ -7117,8 +8512,9 @@ }, "node_modules/npm-run-path": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -7131,8 +8527,9 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -7142,28 +8539,32 @@ }, "node_modules/nullthrows": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true }, "node_modules/object-assign": { "version": "4.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-is": { "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -7177,16 +8578,18 @@ }, "node_modules/object-keys": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -7202,8 +8605,9 @@ }, "node_modules/object.entries": { "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7215,8 +8619,9 @@ }, "node_modules/object.fromentries": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7230,20 +8635,23 @@ } }, "node_modules/object.groupby": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" } }, "node_modules/object.hasown": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.2.0", "es-abstract": "^1.22.1" @@ -7254,8 +8662,9 @@ }, "node_modules/object.values": { "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7270,16 +8679,18 @@ }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -7292,8 +8703,9 @@ }, "node_modules/optionator": { "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "license": "MIT", "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -7308,8 +8720,9 @@ }, "node_modules/ora": { "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, - "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -7330,16 +8743,18 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7352,8 +8767,9 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -7366,8 +8782,9 @@ }, "node_modules/p-map": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, - "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -7380,16 +8797,18 @@ }, "node_modules/p-try": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/param-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, - "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -7397,8 +8816,9 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -7408,8 +8828,9 @@ }, "node_modules/parse-filepath": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dev": true, - "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", @@ -7421,8 +8842,9 @@ }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -7438,8 +8860,9 @@ }, "node_modules/parse5": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, - "license": "MIT", "dependencies": { "entities": "^4.4.0" }, @@ -7449,8 +8872,9 @@ }, "node_modules/pascal-case": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dev": true, - "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -7458,8 +8882,9 @@ }, "node_modules/path-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "dev": true, - "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -7467,37 +8892,42 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-root": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dev": true, - "license": "MIT", "dependencies": { "path-root-regex": "^0.1.0" }, @@ -7507,36 +8937,41 @@ }, "node_modules/path-root-regex": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pathe": { "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true }, "node_modules/pathval": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/pbf": { "version": "3.2.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", + "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" @@ -7547,13 +8982,15 @@ }, "node_modules/picocolors": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -7563,8 +9000,9 @@ }, "node_modules/pkg-types": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", "dev": true, - "license": "MIT", "dependencies": { "jsonc-parser": "^3.2.0", "mlly": "^1.2.0", @@ -7572,7 +9010,9 @@ } }, "node_modules/postcss": { - "version": "8.4.33", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "dev": true, "funding": [ { @@ -7588,7 +9028,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -7600,20 +9039,23 @@ }, "node_modules/potpack": { "version": "2.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", + "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==" }, "node_modules/prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", "dev": true, - "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -7626,8 +9068,9 @@ }, "node_modules/pretty-format": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -7639,8 +9082,9 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -7650,15 +9094,17 @@ }, "node_modules/promise": { "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, - "license": "MIT", "dependencies": { "asap": "~2.0.3" } }, "node_modules/prop-types": { "version": "15.8.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -7667,7 +9113,8 @@ }, "node_modules/prop-types-extra": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", "dependencies": { "react-is": "^16.3.2", "warning": "^4.0.0" @@ -7678,49 +9125,59 @@ }, "node_modules/prop-types-extra/node_modules/react-is": { "version": "16.13.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, "node_modules/psl": { "version": "1.9.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true }, "node_modules/punycode": { "version": "1.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true }, "node_modules/pvtsutils": { "version": "1.3.5", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", + "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.6.1" } }, "node_modules/pvutils": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/querystringify": { "version": "2.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -7735,16 +9192,17 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/quickselect": { "version": "2.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" }, "node_modules/react": { "version": "18.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -7754,7 +9212,8 @@ }, "node_modules/react-bootstrap": { "version": "2.8.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", + "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", "dependencies": { "@babel/runtime": "^7.21.0", "@restart/hooks": "^0.4.9", @@ -7782,7 +9241,8 @@ }, "node_modules/react-dom": { "version": "18.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -7793,16 +9253,19 @@ }, "node_modules/react-is": { "version": "17.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "node_modules/react-map-gl": { "version": "7.1.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-7.1.5.tgz", + "integrity": "sha512-YS2u2cSLlZVGjfa394f0snO6f6ZwZVTKqQwjbq/jj0w7fHU01Mn+Xqvm/Qr7nZChoT3OG7kh8JluDcXeBrDG/g==", "dependencies": { "@maplibre/maplibre-gl-style-spec": "^19.2.1", "@types/mapbox-gl": ">=1.0.0" @@ -7824,15 +9287,17 @@ }, "node_modules/react-refresh": { "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-transition-group": { "version": "4.4.5", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -7846,8 +9311,9 @@ }, "node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -7858,14 +9324,16 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.4", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" }, @@ -7878,16 +9346,19 @@ }, "node_modules/regenerator-runtime": { "version": "0.14.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.1", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -7898,8 +9369,9 @@ }, "node_modules/relay-runtime": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", + "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.0.0", "fbjs": "^3.0.0", @@ -7908,52 +9380,60 @@ }, "node_modules/remedial": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", + "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", "dev": true, - "license": "(MIT OR Apache-2.0)", "engines": { "node": "*" } }, "node_modules/remove-trailing-separator": { "version": "1.1.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true }, "node_modules/remove-trailing-spaces": { "version": "1.0.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz", + "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==", + "dev": true }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "node_modules/requires-port": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/resolve": { "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -7968,23 +9448,26 @@ }, "node_modules/resolve-from": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/resolve-protobuf-schema": { "version": "2.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", "dependencies": { "protocol-buffers-schema": "^3.3.1" } }, "node_modules/restore-cursor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, - "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -7995,22 +9478,25 @@ }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rfdc": { - "version": "1.3.0", - "dev": true, - "license": "MIT" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -8023,8 +9509,9 @@ }, "node_modules/rollup": { "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "dev": true, - "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -8038,19 +9525,23 @@ }, "node_modules/rrweb-cssom": { "version": "0.6.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true }, "node_modules/run-async": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -8066,30 +9557,32 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rw": { "version": "1.3.3", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "node_modules/rxjs": { "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-array-concat": { - "version": "1.0.1", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -8102,6 +9595,8 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -8116,16 +9611,16 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/safe-regex-test": { - "version": "1.0.2", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, "engines": { @@ -8137,13 +9632,15 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "node_modules/saxes": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, - "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, @@ -8153,28 +9650,32 @@ }, "node_modules/scheduler": { "version": "0.23.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/scuid": { "version": "1.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", + "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==", + "dev": true }, "node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/sentence-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", "dev": true, - "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -8183,18 +9684,22 @@ }, "node_modules/set-blocking": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "node_modules/set-function-length": { - "version": "1.1.1", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", "dev": true, - "license": "MIT", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -8202,8 +9707,9 @@ }, "node_modules/set-function-name": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", "dev": true, - "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "functions-have-names": "^1.2.3", @@ -8215,7 +9721,8 @@ }, "node_modules/set-value": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -8228,13 +9735,15 @@ }, "node_modules/setimmediate": { "version": "1.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -8244,28 +9753,35 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.0.4", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8273,31 +9789,36 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true }, "node_modules/signal-exit": { "version": "3.0.7", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/signedsource": { "version": "1.0.0", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==", + "dev": true }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-ansi": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -8309,8 +9830,9 @@ }, "node_modules/snake-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "dev": true, - "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -8318,21 +9840,24 @@ }, "node_modules/sort-asc": { "version": "0.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", + "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", "engines": { "node": ">=0.10.0" } }, "node_modules/sort-desc": { "version": "0.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", + "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", "engines": { "node": ">=0.10.0" } }, "node_modules/sort-object": { "version": "3.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", + "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", "dependencies": { "bytewise": "^1.1.0", "get-value": "^2.0.2", @@ -8347,23 +9872,26 @@ }, "node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/split-string": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dependencies": { "extend-shallow": "^3.0.0" }, @@ -8373,7 +9901,8 @@ }, "node_modules/split-string/node_modules/extend-shallow": { "version": "3.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -8384,7 +9913,8 @@ }, "node_modules/split-string/node_modules/is-extendable": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -8394,26 +9924,30 @@ }, "node_modules/sponge-case": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", + "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/stackback": { "version": "0.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true }, "node_modules/std-env": { "version": "3.7.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", "dev": true, - "license": "MIT", "dependencies": { "internal-slot": "^1.0.4" }, @@ -8423,6 +9957,8 @@ }, "node_modules/streamsearch": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -8430,21 +9966,24 @@ }, "node_modules/string_decoder": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string-env-interpolation": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz", + "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", + "dev": true }, "node_modules/string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8456,13 +9995,15 @@ }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/string.prototype.matchall": { "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -8480,8 +10021,9 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -8496,8 +10038,9 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -8509,8 +10052,9 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -8522,8 +10066,9 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -8533,16 +10078,18 @@ }, "node_modules/strip-bom": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/strip-final-newline": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -8552,8 +10099,9 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -8563,8 +10111,9 @@ }, "node_modules/strip-literal": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", "dev": true, - "license": "MIT", "dependencies": { "acorn": "^8.10.0" }, @@ -8574,15 +10123,17 @@ }, "node_modules/supercluster": { "version": "8.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", "dependencies": { "kdbush": "^4.0.2" } }, "node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -8592,8 +10143,9 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8603,21 +10155,24 @@ }, "node_modules/swap-case": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", + "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/symbol-tree": { "version": "3.2.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true }, "node_modules/test-exclude": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -8629,51 +10184,59 @@ }, "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/through": { "version": "2.3.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true }, "node_modules/tinybench": { - "version": "2.5.1", - "dev": true, - "license": "MIT" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", + "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", + "dev": true }, "node_modules/tinypool": { - "version": "0.8.1", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", + "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tinyqueue": { "version": "2.0.3", - "license": "ISC" + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", + "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" }, "node_modules/tinyspy": { - "version": "2.2.0", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/title-case": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/tmp": { "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, - "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -8683,16 +10246,18 @@ }, "node_modules/to-fast-properties": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -8702,8 +10267,9 @@ }, "node_modules/tough-cookie": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -8716,16 +10282,18 @@ }, "node_modules/tough-cookie/node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/tr46": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "dev": true, - "license": "MIT", "dependencies": { "punycode": "^2.3.1" }, @@ -8735,18 +10303,20 @@ }, "node_modules/tr46/node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ts-api-utils": { - "version": "1.0.3", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -8754,13 +10324,15 @@ }, "node_modules/ts-log": { "version": "2.2.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", + "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", + "dev": true }, "node_modules/tsconfig-paths": { "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, - "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -8770,8 +10342,9 @@ }, "node_modules/tsconfig-paths/node_modules/json5": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, - "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -8781,12 +10354,14 @@ }, "node_modules/tslib": { "version": "2.6.2", - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -8796,16 +10371,18 @@ }, "node_modules/type-detect": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -8814,13 +10391,14 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", + "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -8828,8 +10406,9 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -8845,8 +10424,9 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, - "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -8863,8 +10443,9 @@ }, "node_modules/typed-array-length": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -8876,8 +10457,9 @@ }, "node_modules/typescript": { "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8888,17 +10470,21 @@ }, "node_modules/typewise": { "version": "1.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", "dependencies": { "typewise-core": "^1.2.0" } }, "node_modules/typewise-core": { "version": "1.2.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==" }, "node_modules/ua-parser-js": { "version": "1.0.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", + "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", "dev": true, "funding": [ { @@ -8914,20 +10500,21 @@ "url": "https://github.com/sponsors/faisalman" } ], - "license": "MIT", "engines": { "node": "*" } }, "node_modules/ufo": { - "version": "1.3.2", - "dev": true, - "license": "MIT" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", + "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", + "dev": true }, "node_modules/unbox-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -8940,15 +10527,17 @@ }, "node_modules/unc-path-regex": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/uncontrollable": { "version": "7.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", "dependencies": { "@babel/runtime": "^7.6.3", "@types/react": ">=16.9.11", @@ -8961,12 +10550,14 @@ }, "node_modules/undici-types": { "version": "5.26.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/union-value": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -8979,16 +10570,18 @@ }, "node_modules/universalify": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/unixify": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", + "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", "dev": true, - "license": "MIT", "dependencies": { "normalize-path": "^2.1.1" }, @@ -8998,6 +10591,8 @@ }, "node_modules/update-browserslist-db": { "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -9013,7 +10608,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -9027,40 +10621,45 @@ }, "node_modules/upper-case": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/upper-case-first": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/uri-js/node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/url-parse": { "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, - "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -9068,18 +10667,21 @@ }, "node_modules/urlpattern-polyfill": { "version": "8.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "dev": true }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/v8-to-istanbul": { "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, - "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -9091,16 +10693,18 @@ }, "node_modules/value-or-promise": { "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/vite": { "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -9153,45 +10757,384 @@ }, "node_modules/vite-node": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.1.3.tgz", + "integrity": "sha512-BLSO72YAkIUuNrOx+8uznYICJfTEbvBAmWClY3hpath5+h1mbPS5OMn42lrTxXuyCazVyZoDkSRnju78GiVCqA==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node": ">=12" } }, - "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { - "version": "0.19.11", + "node_modules/vite-node/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { "node": ">=12" } }, "node_modules/vite-node/node_modules/esbuild": { - "version": "0.19.11", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -9199,35 +11142,36 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.11", - "@esbuild/android-arm": "0.19.11", - "@esbuild/android-arm64": "0.19.11", - "@esbuild/android-x64": "0.19.11", - "@esbuild/darwin-arm64": "0.19.11", - "@esbuild/darwin-x64": "0.19.11", - "@esbuild/freebsd-arm64": "0.19.11", - "@esbuild/freebsd-x64": "0.19.11", - "@esbuild/linux-arm": "0.19.11", - "@esbuild/linux-arm64": "0.19.11", - "@esbuild/linux-ia32": "0.19.11", - "@esbuild/linux-loong64": "0.19.11", - "@esbuild/linux-mips64el": "0.19.11", - "@esbuild/linux-ppc64": "0.19.11", - "@esbuild/linux-riscv64": "0.19.11", - "@esbuild/linux-s390x": "0.19.11", - "@esbuild/linux-x64": "0.19.11", - "@esbuild/netbsd-x64": "0.19.11", - "@esbuild/openbsd-x64": "0.19.11", - "@esbuild/sunos-x64": "0.19.11", - "@esbuild/win32-arm64": "0.19.11", - "@esbuild/win32-ia32": "0.19.11", - "@esbuild/win32-x64": "0.19.11" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "node_modules/vite-node/node_modules/rollup": { - "version": "4.9.5", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.10.0.tgz", + "integrity": "sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -9239,29 +11183,30 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.5", - "@rollup/rollup-android-arm64": "4.9.5", - "@rollup/rollup-darwin-arm64": "4.9.5", - "@rollup/rollup-darwin-x64": "4.9.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.5", - "@rollup/rollup-linux-arm64-gnu": "4.9.5", - "@rollup/rollup-linux-arm64-musl": "4.9.5", - "@rollup/rollup-linux-riscv64-gnu": "4.9.5", - "@rollup/rollup-linux-x64-gnu": "4.9.5", - "@rollup/rollup-linux-x64-musl": "4.9.5", - "@rollup/rollup-win32-arm64-msvc": "4.9.5", - "@rollup/rollup-win32-ia32-msvc": "4.9.5", - "@rollup/rollup-win32-x64-msvc": "4.9.5", + "@rollup/rollup-android-arm-eabi": "4.10.0", + "@rollup/rollup-android-arm64": "4.10.0", + "@rollup/rollup-darwin-arm64": "4.10.0", + "@rollup/rollup-darwin-x64": "4.10.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.10.0", + "@rollup/rollup-linux-arm64-gnu": "4.10.0", + "@rollup/rollup-linux-arm64-musl": "4.10.0", + "@rollup/rollup-linux-riscv64-gnu": "4.10.0", + "@rollup/rollup-linux-x64-gnu": "4.10.0", + "@rollup/rollup-linux-x64-musl": "4.10.0", + "@rollup/rollup-win32-arm64-msvc": "4.10.0", + "@rollup/rollup-win32-ia32-msvc": "4.10.0", + "@rollup/rollup-win32-x64-msvc": "4.10.0", "fsevents": "~2.3.2" } }, "node_modules/vite-node/node_modules/vite": { - "version": "5.0.11", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.1.tgz", + "integrity": "sha512-wclpAgY3F1tR7t9LL5CcHC41YPkQIpKUGeIuT8MdNwNZr6OqOTLs7JX5vIHAtzqLWXts0T+GDrh9pN2arneKqg==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.19.3", - "postcss": "^8.4.32", + "postcss": "^8.4.35", "rollup": "^4.2.0" }, "bin": { @@ -9311,8 +11256,9 @@ }, "node_modules/vitest": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.1.3.tgz", + "integrity": "sha512-2l8om1NOkiA90/Y207PsEvJLYygddsOyr81wLQ20Ra8IlLKbyQncWsGZjnbkyG2KwwuTXLQjEPOJuxGMG8qJBQ==", "dev": true, - "license": "MIT", "dependencies": { "@vitest/expect": "1.1.3", "@vitest/runner": "1.1.3", @@ -9374,13 +11320,78 @@ } } }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/vitest/node_modules/@esbuild/darwin-x64": { - "version": "0.19.11", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -9389,11 +11400,284 @@ "node": ">=12" } }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/vitest/node_modules/esbuild": { - "version": "0.19.11", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -9401,35 +11685,36 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.11", - "@esbuild/android-arm": "0.19.11", - "@esbuild/android-arm64": "0.19.11", - "@esbuild/android-x64": "0.19.11", - "@esbuild/darwin-arm64": "0.19.11", - "@esbuild/darwin-x64": "0.19.11", - "@esbuild/freebsd-arm64": "0.19.11", - "@esbuild/freebsd-x64": "0.19.11", - "@esbuild/linux-arm": "0.19.11", - "@esbuild/linux-arm64": "0.19.11", - "@esbuild/linux-ia32": "0.19.11", - "@esbuild/linux-loong64": "0.19.11", - "@esbuild/linux-mips64el": "0.19.11", - "@esbuild/linux-ppc64": "0.19.11", - "@esbuild/linux-riscv64": "0.19.11", - "@esbuild/linux-s390x": "0.19.11", - "@esbuild/linux-x64": "0.19.11", - "@esbuild/netbsd-x64": "0.19.11", - "@esbuild/openbsd-x64": "0.19.11", - "@esbuild/sunos-x64": "0.19.11", - "@esbuild/win32-arm64": "0.19.11", - "@esbuild/win32-ia32": "0.19.11", - "@esbuild/win32-x64": "0.19.11" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "node_modules/vitest/node_modules/rollup": { - "version": "4.9.5", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.10.0.tgz", + "integrity": "sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -9441,29 +11726,30 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.5", - "@rollup/rollup-android-arm64": "4.9.5", - "@rollup/rollup-darwin-arm64": "4.9.5", - "@rollup/rollup-darwin-x64": "4.9.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.5", - "@rollup/rollup-linux-arm64-gnu": "4.9.5", - "@rollup/rollup-linux-arm64-musl": "4.9.5", - "@rollup/rollup-linux-riscv64-gnu": "4.9.5", - "@rollup/rollup-linux-x64-gnu": "4.9.5", - "@rollup/rollup-linux-x64-musl": "4.9.5", - "@rollup/rollup-win32-arm64-msvc": "4.9.5", - "@rollup/rollup-win32-ia32-msvc": "4.9.5", - "@rollup/rollup-win32-x64-msvc": "4.9.5", + "@rollup/rollup-android-arm-eabi": "4.10.0", + "@rollup/rollup-android-arm64": "4.10.0", + "@rollup/rollup-darwin-arm64": "4.10.0", + "@rollup/rollup-darwin-x64": "4.10.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.10.0", + "@rollup/rollup-linux-arm64-gnu": "4.10.0", + "@rollup/rollup-linux-arm64-musl": "4.10.0", + "@rollup/rollup-linux-riscv64-gnu": "4.10.0", + "@rollup/rollup-linux-x64-gnu": "4.10.0", + "@rollup/rollup-linux-x64-musl": "4.10.0", + "@rollup/rollup-win32-arm64-msvc": "4.10.0", + "@rollup/rollup-win32-ia32-msvc": "4.10.0", + "@rollup/rollup-win32-x64-msvc": "4.10.0", "fsevents": "~2.3.2" } }, "node_modules/vitest/node_modules/vite": { - "version": "5.0.11", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.1.tgz", + "integrity": "sha512-wclpAgY3F1tR7t9LL5CcHC41YPkQIpKUGeIuT8MdNwNZr6OqOTLs7JX5vIHAtzqLWXts0T+GDrh9pN2arneKqg==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.19.3", - "postcss": "^8.4.32", + "postcss": "^8.4.35", "rollup": "^4.2.0" }, "bin": { @@ -9513,7 +11799,8 @@ }, "node_modules/vt-pbf": { "version": "3.1.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", "dependencies": { "@mapbox/point-geometry": "0.1.0", "@mapbox/vector-tile": "^1.3.1", @@ -9522,8 +11809,9 @@ }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, - "license": "MIT", "dependencies": { "xml-name-validator": "^5.0.0" }, @@ -9533,51 +11821,57 @@ }, "node_modules/warning": { "version": "4.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/wcwidth": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, - "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/web-streams-polyfill": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", + "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/webcrypto-core": { - "version": "1.7.7", + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.8.tgz", + "integrity": "sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg==", "dev": true, - "license": "MIT", "dependencies": { - "@peculiar/asn1-schema": "^2.3.6", + "@peculiar/asn1-schema": "^2.3.8", "@peculiar/json-schema": "^1.1.12", "asn1js": "^3.0.1", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.0" + "pvtsutils": "^1.3.5", + "tslib": "^2.6.2" } }, "node_modules/webidl-conversions": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=12" } }, "node_modules/whatwg-encoding": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, - "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, @@ -9587,8 +11881,9 @@ }, "node_modules/whatwg-encoding/node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -9598,16 +11893,18 @@ }, "node_modules/whatwg-mimetype": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/whatwg-url": { "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "dev": true, - "license": "MIT", "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -9618,8 +11915,9 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -9632,8 +11930,9 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -9647,8 +11946,9 @@ }, "node_modules/which-builtin-type": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", "dev": true, - "license": "MIT", "dependencies": { "function.prototype.name": "^1.1.5", "has-tostringtag": "^1.0.0", @@ -9672,8 +11972,9 @@ }, "node_modules/which-collection": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "dev": true, - "license": "MIT", "dependencies": { "is-map": "^2.0.1", "is-set": "^2.0.1", @@ -9686,19 +11987,21 @@ }, "node_modules/which-module": { "version": "2.0.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true }, "node_modules/which-typed-array": { - "version": "1.1.13", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", "dev": true, - "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -9709,8 +12012,9 @@ }, "node_modules/why-is-node-running": { "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", "dev": true, - "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -9724,8 +12028,9 @@ }, "node_modules/wrap-ansi": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9737,13 +12042,15 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/ws": { "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -9762,47 +12069,54 @@ }, "node_modules/xml-name-validator": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=18" } }, "node_modules/xmlchars": { "version": "2.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "3.1.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yaml": { "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "dev": true, - "license": "ISC", "engines": { "node": ">= 14" } }, "node_modules/yaml-ast-parser": { "version": "0.0.43", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true }, "node_modules/yargs": { "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9818,16 +12132,18 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, From e55c2c91d234de98f15dde60401823bf051f23ff Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 14 Feb 2024 17:37:19 +0100 Subject: [PATCH 349/356] Apply review feedback --- docs/sandbox/MapboxVectorTilesApi.md | 7 ++++--- .../java/org/opentripplanner/apis/support/TileJson.java | 2 +- .../java/org/opentripplanner/framework/io/HttpUtils.java | 2 +- .../standalone/config/routerconfig/VectorTileConfig.java | 7 ++++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/sandbox/MapboxVectorTilesApi.md b/docs/sandbox/MapboxVectorTilesApi.md index 11bd195a9d8..7183bdf8b7f 100644 --- a/docs/sandbox/MapboxVectorTilesApi.md +++ b/docs/sandbox/MapboxVectorTilesApi.md @@ -169,12 +169,13 @@ For each layer, the configuration includes: Custom attribution to be returned in `tilejson.json` -By default the `attribution` property in `tilejson.json` is computed from the names and +By default the, `attribution` property in `tilejson.json` is computed from the names and URLs of the feed publishers. If the OTP deployment contains many fields, this can become very unwieldy. -This configuration parameter allows you to set the `attribution` to any string you wish, -for example `TriMet, C-Tran, SMART and Friends`. +This configuration parameter allows you to set the `attribution` to any string you wish +including HTML tags, +for example `Regional Partners`.

      basePath

      diff --git a/src/main/java/org/opentripplanner/apis/support/TileJson.java b/src/main/java/org/opentripplanner/apis/support/TileJson.java index fcd6e84cc06..1f5c090c16d 100644 --- a/src/main/java/org/opentripplanner/apis/support/TileJson.java +++ b/src/main/java/org/opentripplanner/apis/support/TileJson.java @@ -98,7 +98,7 @@ private static String attributionFromFeedInfo(Collection feedInfos) { return feedInfos .stream() .map(feedInfo -> - "" + feedInfo.getPublisherName() + "" + "%s".formatted(feedInfo.getPublisherUrl(), feedInfo.getPublisherName()) ) .distinct() .collect(Collectors.joining(", ")); diff --git a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java b/src/main/java/org/opentripplanner/framework/io/HttpUtils.java index d8b3dc542a6..672c9b9c481 100644 --- a/src/main/java/org/opentripplanner/framework/io/HttpUtils.java +++ b/src/main/java/org/opentripplanner/framework/io/HttpUtils.java @@ -47,6 +47,6 @@ public static String getBaseAddress(UriInfo uri, HttpHeaders headers) { * https://stackoverflow.com/questions/66042952/http-proxy-behavior-for-x-forwarded-host-header */ private static String extractHost(String xForwardedFor) { - return Arrays.stream(xForwardedFor.split(",")).map(String::strip).toList().getFirst(); + return Arrays.stream(xForwardedFor.split(",")).map(String::strip).findFirst().get(); } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index f0c6cb7d9b0..d6beac6d256 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -87,12 +87,13 @@ public static VectorTileConfig mapVectorTilesParameters(NodeAdapter node, String .summary("Custom attribution to be returned in `tilejson.json`") .description( """ - By default the `attribution` property in `tilejson.json` is computed from the names and + By default the, `attribution` property in `tilejson.json` is computed from the names and URLs of the feed publishers. If the OTP deployment contains many fields, this can become very unwieldy. - This configuration parameter allows you to set the `attribution` to any string you wish, - for example `TriMet, C-Tran, SMART and Friends`. + This configuration parameter allows you to set the `attribution` to any string you wish + including HTML tags, + for example `Regional Partners`. """ ) .asString(DEFAULT.attribution) From 6e7fbdaf5d307d7314331de7920cca38440155c7 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 15 Feb 2024 09:21:33 +0000 Subject: [PATCH 350/356] Add changelog entry for #5632 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 86f6355f37f..39aa4b8c329 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -91,6 +91,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Remove `VehicleToStopHeuristics` [#5381](https://github.com/opentripplanner/OpenTripPlanner/pull/5381) - Set defaults of the modes WALK, even if one and not the others are set [#5675](https://github.com/opentripplanner/OpenTripPlanner/pull/5675) - Reduce flex default access/egress penalty [#5674](https://github.com/opentripplanner/OpenTripPlanner/pull/5674) +- Add scooter preferences [#5632](https://github.com/opentripplanner/OpenTripPlanner/pull/5632) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 635ce6786ae71a72dcff786dfdba27cb1eebacd3 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Thu, 15 Feb 2024 09:22:00 +0000 Subject: [PATCH 351/356] Bump serialization version id for #5632 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c066d35e112..f12da275eb6 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 144 + 145 30.2 2.50 From 9163978720f51bc5b3e23a683d6885c004a02a23 Mon Sep 17 00:00:00 2001 From: Eivind Morris Bakke Date: Thu, 15 Feb 2024 10:55:26 +0100 Subject: [PATCH 352/356] Add GroupStop layer to new debug frontend (#5666) * Adds GroupStop areas to new debug UI. Done with a listing of all GroupStops for now. * Adds comment explaining why we precompute geometries in the GroupStopLayerBuilder. * Adds top level JavaDoc to GroupStopLayerBuilder. --- .../src/components/MapView/MapView.tsx | 2 +- .../apis/vectortiles/DebugStyleSpec.java | 10 ++++ .../GraphInspectorVectorTileResource.java | 15 +++++- .../apis/vectortiles/model/LayerType.java | 1 + .../vector/stop/GroupStopLayerBuilder.java | 50 +++++++++++++++++++ .../service/DefaultTransitService.java | 7 +++ .../transit/service/TransitService.java | 3 ++ .../apis/vectortiles/DebugStyleSpecTest.java | 3 +- .../apis/vectortiles/style.json | 13 +++++ 9 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java diff --git a/client-next/src/components/MapView/MapView.tsx b/client-next/src/components/MapView/MapView.tsx index 96b4e820bae..36d98be79b6 100644 --- a/client-next/src/components/MapView/MapView.tsx +++ b/client-next/src/components/MapView/MapView.tsx @@ -75,7 +75,7 @@ export function MapView({ }} // it's unfortunate that you have to list these layers here. // maybe there is a way around it: https://github.com/visgl/react-map-gl/discussions/2343 - interactiveLayerIds={['regular-stop', 'area-stop', 'vertex', 'edge', 'link']} + interactiveLayerIds={['regular-stop', 'area-stop', 'group-stop', 'vertex', 'edge', 'link']} onClick={showFeaturePropPopup} // put lat/long in URL and pan to it on page reload hash={true} diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java index f45d7d36413..8350a10d670 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java @@ -53,6 +53,7 @@ public class DebugStyleSpec { static StyleSpec build( VectorSourceLayer regularStops, VectorSourceLayer areaStops, + VectorSourceLayer groupStops, VectorSourceLayer edges, VectorSourceLayer vertices ) { @@ -122,6 +123,15 @@ static StyleSpec build( .fillOutlineColor(BLACK) .minZoom(6) .maxZoom(MAX_ZOOM), + StyleBuilder + .ofId("group-stop") + .typeFill() + .vectorSourceLayer(groupStops) + .fillColor(GREEN) + .fillOpacity(0.5f) + .fillOutlineColor(BLACK) + .minZoom(6) + .maxZoom(MAX_ZOOM), StyleBuilder .ofId("regular-stop") .typeCircle() diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java index dc6ba627e0e..f97830232bd 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/GraphInspectorVectorTileResource.java @@ -3,6 +3,7 @@ import static org.opentripplanner.apis.vectortiles.model.LayerType.AreaStop; import static org.opentripplanner.apis.vectortiles.model.LayerType.Edge; import static org.opentripplanner.apis.vectortiles.model.LayerType.GeofencingZones; +import static org.opentripplanner.apis.vectortiles.model.LayerType.GroupStop; import static org.opentripplanner.apis.vectortiles.model.LayerType.RegularStop; import static org.opentripplanner.apis.vectortiles.model.LayerType.Vertex; import static org.opentripplanner.framework.io.HttpUtils.APPLICATION_X_PROTOBUF; @@ -35,6 +36,7 @@ import org.opentripplanner.inspector.vector.VectorTileResponseFactory; import org.opentripplanner.inspector.vector.edge.EdgeLayerBuilder; import org.opentripplanner.inspector.vector.geofencing.GeofencingZonesLayerBuilder; +import org.opentripplanner.inspector.vector.stop.GroupStopLayerBuilder; import org.opentripplanner.inspector.vector.stop.StopLayerBuilder; import org.opentripplanner.inspector.vector.vertex.VertexLayerBuilder; import org.opentripplanner.model.FeedInfo; @@ -49,6 +51,7 @@ public class GraphInspectorVectorTileResource { private static final LayerParams REGULAR_STOPS = new LayerParams("regularStops", RegularStop); private static final LayerParams AREA_STOPS = new LayerParams("areaStops", AreaStop); + private static final LayerParams GROUP_STOPS = new LayerParams("groupStops", GroupStop); private static final LayerParams GEOFENCING_ZONES = new LayerParams( "geofencingZones", GeofencingZones @@ -58,6 +61,7 @@ public class GraphInspectorVectorTileResource { private static final List> DEBUG_LAYERS = List.of( REGULAR_STOPS, AREA_STOPS, + GROUP_STOPS, GEOFENCING_ZONES, EDGES, VERTICES @@ -128,11 +132,11 @@ public TileJson getTileJson( public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) { var base = HttpUtils.getBaseAddress(uri, headers); - // these two could also be loaded together but are put into separate sources because + // these could also be loaded together but are put into separate sources because // the stops are fast and the edges are relatively slow var stopsSource = new VectorSource( "stops", - tileJsonUrl(base, List.of(REGULAR_STOPS, AREA_STOPS)) + tileJsonUrl(base, List.of(REGULAR_STOPS, AREA_STOPS, GROUP_STOPS)) ); var streetSource = new VectorSource( "street", @@ -142,6 +146,7 @@ public StyleSpec getTileJson(@Context UriInfo uri, @Context HttpHeaders headers) return DebugStyleSpec.build( REGULAR_STOPS.toVectorSourceLayer(stopsSource), AREA_STOPS.toVectorSourceLayer(stopsSource), + GROUP_STOPS.toVectorSourceLayer(stopsSource), EDGES.toVectorSourceLayer(streetSource), VERTICES.toVectorSourceLayer(streetSource) ); @@ -186,6 +191,12 @@ private static LayerBuilder createLayerBuilder( locale, e -> context.transitService().findAreaStops(e) ); + case GroupStop -> new GroupStopLayerBuilder( + layerParameters, + locale, + // There are not many GroupStops, so we can just list them all. + context.transitService().listGroupStops() + ); case GeofencingZones -> new GeofencingZonesLayerBuilder(context.graph(), layerParameters); case Edge -> new EdgeLayerBuilder(context.graph(), layerParameters); case Vertex -> new VertexLayerBuilder(context.graph(), layerParameters); diff --git a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java index ece75f29b60..585725d0707 100644 --- a/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java +++ b/src/main/java/org/opentripplanner/apis/vectortiles/model/LayerType.java @@ -3,6 +3,7 @@ public enum LayerType { RegularStop, AreaStop, + GroupStop, GeofencingZones, Edge, Vertex, diff --git a/src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java b/src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java new file mode 100644 index 00000000000..1e66397bc05 --- /dev/null +++ b/src/main/java/org/opentripplanner/inspector/vector/stop/GroupStopLayerBuilder.java @@ -0,0 +1,50 @@ +package org.opentripplanner.inspector.vector.stop; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.inspector.vector.LayerBuilder; +import org.opentripplanner.inspector.vector.LayerParameters; +import org.opentripplanner.transit.model.site.GroupStop; +import org.opentripplanner.transit.model.site.StopLocation; + +/** + * A vector tile layer for {@link GroupStop}s inside the vector tile bounds. The builder does not + * query for the GroupStops to draw, but instead uses the geometries of the GroupStops that are + * passed to the constructor. + */ +public class GroupStopLayerBuilder extends LayerBuilder { + + private final List geometries; + + public GroupStopLayerBuilder( + LayerParameters layerParameters, + Locale locale, + Collection groupStops + ) { + super( + new StopLocationPropertyMapper(locale), + layerParameters.name(), + layerParameters.expansionFactor() + ); + // Because there are very few GroupStops with relevant geometries, we can precompute the + // geometries and store them in a list at the time of construction. + this.geometries = + groupStops + .stream() + .filter(groupStop -> groupStop.getEncompassingAreaGeometry().isPresent()) + .map(stop -> { + Geometry geometry = stop.getEncompassingAreaGeometry().get().copy(); + geometry.setUserData(stop); + return geometry; + }) + .toList(); + } + + @Override + protected List getGeometries(Envelope query) { + return geometries; + } +} diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 3050fca6a3d..ca88b7d3130 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -41,6 +41,7 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.AreaStop; +import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.MultiModalStation; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; @@ -226,6 +227,12 @@ public Collection listRegularStops() { return transitModel.getStopModel().listRegularStops(); } + @Override + public Collection listGroupStops() { + OTPRequestTimeoutException.checkForTimeout(); + return transitModel.getStopModel().listGroupStops(); + } + @Override public StopLocation getStopLocation(FeedScopedId id) { return transitModel.getStopModel().getStopLocation(id); diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index fdb6dda8749..17354ec4a20 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -32,6 +32,7 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.AreaStop; +import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.MultiModalStation; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; @@ -95,6 +96,8 @@ public interface TransitService { Collection listRegularStops(); + Collection listGroupStops(); + StopLocation getStopLocation(FeedScopedId parseId); Collection getStopOrChildStops(FeedScopedId id); diff --git a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java index f2c3ebf49de..d971cefe2e2 100644 --- a/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java +++ b/src/test/java/org/opentripplanner/apis/vectortiles/DebugStyleSpecTest.java @@ -17,9 +17,10 @@ void spec() { var vectorSource = new VectorSource("vectorSource", "https://example.com"); var regularStops = new VectorSourceLayer(vectorSource, "stops"); var areaStops = new VectorSourceLayer(vectorSource, "stops"); + var groupStops = new VectorSourceLayer(vectorSource, "stops"); var edges = new VectorSourceLayer(vectorSource, "edges"); var vertices = new VectorSourceLayer(vectorSource, "vertices"); - var spec = DebugStyleSpec.build(regularStops, areaStops, edges, vertices); + var spec = DebugStyleSpec.build(regularStops, areaStops, groupStops, edges, vertices); var json = ObjectMappers.ignoringExtraFields().valueToTree(spec); var expectation = RESOURCES.fileToString("style.json"); diff --git a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json index e62c3968924..7e611171409 100644 --- a/src/test/resources/org/opentripplanner/apis/vectortiles/style.json +++ b/src/test/resources/org/opentripplanner/apis/vectortiles/style.json @@ -154,6 +154,19 @@ "fill-outline-color" : "#140d0e" } }, + { + "id" : "group-stop", + "type" : "fill", + "source" : "vectorSource", + "source-layer" : "stops", + "minzoom" : 6, + "maxzoom" : 23, + "paint" : { + "fill-color" : "#22DD9E", + "fill-opacity" : 0.5, + "fill-outline-color" : "#140d0e" + } + }, { "id" : "regular-stop", "type" : "circle", From f104386016c2aeb6cb58f0aa1243e3a89b9c1621 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 15 Feb 2024 09:55:43 +0000 Subject: [PATCH 353/356] Add changelog entry for #5666 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 39aa4b8c329..f67b40f5a3b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -92,6 +92,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Set defaults of the modes WALK, even if one and not the others are set [#5675](https://github.com/opentripplanner/OpenTripPlanner/pull/5675) - Reduce flex default access/egress penalty [#5674](https://github.com/opentripplanner/OpenTripPlanner/pull/5674) - Add scooter preferences [#5632](https://github.com/opentripplanner/OpenTripPlanner/pull/5632) +- Add GroupStop layer to new debug frontend [#5666](https://github.com/opentripplanner/OpenTripPlanner/pull/5666) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From ad2cf7aefc839879f4dc476b7f2ff6eea5f07d54 Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 15 Feb 2024 09:56:46 +0000 Subject: [PATCH 354/356] Upgrade debug client to version 2024/02/2024-02-15T09:56 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index 2653fdf36c2..d72598680fe 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
      From 9007ad7d1eb11cc69cae54b1445ef163cb68d6e3 Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Thu, 15 Feb 2024 12:10:11 +0000 Subject: [PATCH 355/356] Bump serialization version id for #5673 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f12da275eb6..8adaaec352a 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 145 + 146 30.2 2.50 From 821a135f2be346e65080e6b73e9593ca4f4a56c1 Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Thu, 15 Feb 2024 17:25:20 +0000 Subject: [PATCH 356/356] Upgrade debug client to version 2024/02/2024-02-15T17:24 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index d72598680fe..7224399b258 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +