diff --git a/docs/api/schemas/motis/import.yaml b/docs/api/schemas/motis/import.yaml index ad73dc1031..46f75d170c 100644 --- a/docs/api/schemas/motis/import.yaml +++ b/docs/api/schemas/motis/import.yaml @@ -79,7 +79,7 @@ ScheduleEvent: description: TODO NigiriEvent: description: TODO - fields: {} + fields: { hash: { description: TODO } } StationsEvent: description: TODO fields: {} diff --git a/docs/api/schemas/motis/ris.yaml b/docs/api/schemas/motis/ris.yaml index ecd0cbac3c..5cf04aa9dd 100644 --- a/docs/api/schemas/motis/ris.yaml +++ b/docs/api/schemas/motis/ris.yaml @@ -415,6 +415,12 @@ RISStatusResponse: description: TODO init_status: description: TODO + delayed_init: + description: TODO + init_forward_started: + description: TODO + init_forward_done: + description: TODO FullTripMessageType: description: TODO TripFormationMessageType: diff --git a/modules/paxforecast/src/monitoring_update.cc b/modules/paxforecast/src/monitoring_update.cc index 44a8740048..9289917d20 100644 --- a/modules/paxforecast/src/monitoring_update.cc +++ b/modules/paxforecast/src/monitoring_update.cc @@ -283,12 +283,19 @@ void handle_major_delays(paxforecast& mod, universe& uv, schedule const& sched, } last_pgi = pgwrap.pgwr_.pg_; - auto& ar = affected_routes.emplace_back(affected_route_info{ - .pgwrap_ = pgwrap, - .destination_station_id_ = get_destination_station_id( - sched, event->group_route()->route()->journey()), - .loc_now_ = from_fbs(sched, event->localization_type(), - event->localization())}); + auto loc_now = + from_fbs(sched, event->localization_type(), event->localization()); + auto const destination_station_id = get_destination_station_id( + sched, event->group_route()->route()->journey()); + + if (loc_now.at_station_->index_ == destination_station_id) { + continue; + } + + auto& ar = affected_routes.emplace_back( + affected_route_info{.pgwrap_ = pgwrap, + .destination_station_id_ = destination_station_id, + .loc_now_ = std::move(loc_now)}); ar.alts_now_ = alts_set.add_request(ar.loc_now_, ar.destination_station_id_); diff --git a/modules/paxmon/include/motis/paxmon/delayed_init.h b/modules/paxmon/include/motis/paxmon/delayed_init.h new file mode 100644 index 0000000000..943c7f03e4 --- /dev/null +++ b/modules/paxmon/include/motis/paxmon/delayed_init.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "motis/core/schedule/schedule.h" + +#include "motis/paxmon/paxmon_data.h" + +namespace motis::paxmon { + +struct delay_init_options { + bool reroute_unmatched_{}; + std::string initial_reroute_router_; +}; + +void delayed_init(paxmon_data& data, universe& uv, schedule const& sched, + delay_init_options const& opt); + +} // namespace motis::paxmon diff --git a/modules/paxmon/include/motis/paxmon/loaded_files.h b/modules/paxmon/include/motis/paxmon/loaded_files.h index 623fb8554d..0475bb6bc8 100644 --- a/modules/paxmon/include/motis/paxmon/loaded_files.h +++ b/modules/paxmon/include/motis/paxmon/loaded_files.h @@ -2,10 +2,12 @@ #include #include +#include #include "motis/core/common/unixtime.h" #include "motis/paxmon/loader/capacities/load_capacities.h" +#include "motis/paxmon/loader/unmatched_journey.h" namespace motis::paxmon { @@ -13,17 +15,19 @@ struct loaded_journey_file { std::filesystem::path path_; unixtime last_modified_{}; - std::size_t matched_journeys_{}; - std::size_t unmatched_journeys_{}; - std::size_t unmatched_journeys_rerouted_{}; + std::size_t matched_journey_count_{}; + std::size_t unmatched_journey_count_{}; + std::size_t unmatched_journey_rerouted_count_{}; - std::size_t matched_groups_{}; - std::size_t unmatched_groups_{}; - std::size_t unmatched_groups_rerouted_{}; + std::size_t matched_group_count_{}; + std::size_t unmatched_group_count_{}; + std::size_t unmatched_group_rerouted_count_{}; - std::size_t matched_pax_{}; - std::size_t unmatched_pax_{}; - std::size_t unmatched_pax_rerouted_{}; + std::size_t matched_pax_count_{}; + std::size_t unmatched_pax_count_{}; + std::size_t unmatched_pax_rerouted_count_{}; + + std::vector unmatched_journeys_; }; struct loaded_capacity_file { diff --git a/modules/paxmon/include/motis/paxmon/loader/unmatched_journey.h b/modules/paxmon/include/motis/paxmon/loader/unmatched_journey.h index 106ac8bb1e..ffdc4420e9 100644 --- a/modules/paxmon/include/motis/paxmon/loader/unmatched_journey.h +++ b/modules/paxmon/include/motis/paxmon/loader/unmatched_journey.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "motis/core/schedule/time.h" @@ -11,9 +12,11 @@ namespace motis::paxmon::loader { struct unmatched_journey { std::uint32_t start_station_idx_{}; std::uint32_t destination_station_idx_{}; - time departure_time_{}; + time departure_time_{INVALID_TIME}; + time arrival_time_{INVALID_TIME}; motis::paxmon::data_source source_{}; std::uint16_t passengers_{}; + std::vector group_sizes_; }; } // namespace motis::paxmon::loader diff --git a/modules/paxmon/include/motis/paxmon/paxmon.h b/modules/paxmon/include/motis/paxmon/paxmon.h index c867499a86..4d35a42ac9 100644 --- a/modules/paxmon/include/motis/paxmon/paxmon.h +++ b/modules/paxmon/include/motis/paxmon/paxmon.h @@ -32,6 +32,7 @@ struct paxmon : public motis::module::module { void reg_subc(motis::module::subc_reg&) override; void import(motis::module::import_dispatcher& reg) override; void init(motis::module::registry&) override; + void init_op(); bool import_successful() const override { return import_successful_; } @@ -56,7 +57,6 @@ struct paxmon : public motis::module::module { std::string capacity_match_log_file_{}; std::string initial_over_capacity_report_file_{}; std::string initial_broken_report_file_{}; - std::string initial_reroute_query_file_{}; std::string initial_reroute_router_{"/tripbased"}; conf::time start_time_{}; conf::time end_time_{}; diff --git a/modules/paxmon/src/api/dataset_info.cc b/modules/paxmon/src/api/dataset_info.cc index a512299d88..5116a48c9e 100644 --- a/modules/paxmon/src/api/dataset_info.cc +++ b/modules/paxmon/src/api/dataset_info.cc @@ -21,11 +21,13 @@ msg_ptr dataset_info(paxmon_data& data, schedule const& sched) { [&](auto const& ljf) { return CreatePaxMonJourneyFileInfo( mc, mc.CreateString(ljf.path_.filename().string()), - ljf.last_modified_, ljf.matched_journeys_, - ljf.unmatched_journeys_, ljf.unmatched_journeys_rerouted_, - ljf.matched_groups_, ljf.unmatched_groups_, - ljf.unmatched_groups_rerouted_, ljf.matched_pax_, - ljf.unmatched_pax_, ljf.unmatched_pax_rerouted_); + ljf.last_modified_, ljf.matched_journey_count_, + ljf.unmatched_journey_count_, + ljf.unmatched_journey_rerouted_count_, + ljf.matched_group_count_, ljf.unmatched_group_count_, + ljf.unmatched_group_rerouted_count_, ljf.matched_pax_count_, + ljf.unmatched_pax_count_, + ljf.unmatched_pax_rerouted_count_); })), mc.CreateVector(utl::to_vec( data.loaded_capacity_files_, diff --git a/modules/paxmon/src/delayed_init.cc b/modules/paxmon/src/delayed_init.cc new file mode 100644 index 0000000000..ccd9f42de7 --- /dev/null +++ b/modules/paxmon/src/delayed_init.cc @@ -0,0 +1,175 @@ +#include "motis/paxmon/delayed_init.h" + +#include +#include +#include +#include + +#include "utl/verify.h" + +#include "motis/core/common/logging.h" +#include "motis/core/access/time_access.h" +#include "motis/core/journey/message_to_journeys.h" + +#include "motis/module/context/motis_call.h" +#include "motis/module/message.h" + +#include "motis/paxmon/loader/motis_journeys/motis_journeys.h" + +using namespace motis::module; +using namespace motis::logging; + +namespace motis::paxmon { + +msg_ptr initial_reroute_query(schedule const& sched, + loader::unmatched_journey const& uj, + std::string const& router, + unixtime const min_time, + unixtime const max_time) { + using namespace motis::routing; + + message_creator fbb; + + auto const planned_departure = static_cast( + motis_to_unixtime(sched.schedule_begin_, uj.departure_time_)); + + // should be ensured while loading the journey + utl::verify(planned_departure >= min_time && planned_departure <= max_time, + "initial_reroute_query: departure time out of range"); + + auto const interval = + Interval{std::max(min_time, planned_departure - 2 * 60 * 60), + std::min(max_time, planned_departure + 2 * 60 * 60)}; + auto const& start_station = sched.stations_.at(uj.start_station_idx_); + auto const& destination_station = + sched.stations_.at(uj.destination_station_idx_); + fbb.create_and_finish( + MsgContent_RoutingRequest, + CreateRoutingRequest( + fbb, Start_PretripStart, + CreatePretripStart( + fbb, + CreateInputStation(fbb, fbb.CreateString(start_station->eva_nr_), + fbb.CreateString(start_station->name_)), + &interval) + .Union(), + CreateInputStation(fbb, + fbb.CreateString(destination_station->eva_nr_), + fbb.CreateString(destination_station->name_)), + SearchType_Default, SearchDir_Forward, + fbb.CreateVector(std::vector>{}), + fbb.CreateVector( + std::vector>{})) + .Union(), + router); + return make_msg(fbb); +} + +journey const* get_closest_journey(schedule const& sched, + loader::unmatched_journey const& uj, + std::vector const& journeys) { + journey const* best_journey = nullptr; + auto best_score = std::numeric_limits::max(); + auto const planned_dep = static_cast( + motis_to_unixtime(sched.schedule_begin_, uj.departure_time_)); + auto const planned_arr = static_cast( + motis_to_unixtime(sched.schedule_begin_, uj.arrival_time_)); + + for (auto const& j : journeys) { + if (j.stops_.empty()) { + continue; + } + auto const dep_diff = static_cast( + j.stops_.front().departure_.schedule_timestamp_) - + planned_dep; + auto const arr_diff = static_cast( + j.stops_.back().arrival_.schedule_timestamp_) - + planned_arr; + auto const score = dep_diff * dep_diff + arr_diff * arr_diff; + if (score < best_score) { + best_score = score; + best_journey = &j; + } + } + + return best_journey; +} + +void delayed_init(paxmon_data& data, universe& uv, schedule const& sched, + delay_init_options const& opt) { + using namespace motis::ris; + using namespace motis::routing; + + auto const ris_status_msg = motis_call(make_no_msg("/ris/status"))->val(); + auto const ris_status = motis_content(RISStatusResponse, ris_status_msg); + + if (!ris_status->delayed_init()) { + LOG(warn) << "required option ris.delayed_init=1 not set, rerouting " + "unmatched journeys not possible"; + return; + } + + if (opt.reroute_unmatched_) { + auto const min_time = external_schedule_begin(sched); + auto const max_time = external_schedule_end(sched); + + for (auto& ljf : data.loaded_journey_files_) { + if (ljf.unmatched_journeys_.empty()) { + continue; + } + + scoped_timer const timer{"reroute unmatched journeys"}; + LOG(info) << "routing " << ljf.unmatched_journeys_.size() + << " unmatched journeys from " << ljf.path_.filename() + << " using " << opt.initial_reroute_router_ << "..."; + auto const futures = + utl::to_vec(ljf.unmatched_journeys_, [&](auto const& uj) { + return motis_call(initial_reroute_query( + sched, uj, opt.initial_reroute_router_, min_time, max_time)); + }); + ctx::await_all(futures); + LOG(info) << "adding replacement journeys..."; + for (auto const& [uj, fut] : utl::zip(ljf.unmatched_journeys_, futures)) { + auto const rr_msg = fut->val(); + auto const rr = motis_content(RoutingResponse, rr_msg); + auto const journeys = message_to_journeys(rr); + auto const* journey = get_closest_journey(sched, uj, journeys); + if (journey == nullptr) { + continue; + } + ++ljf.unmatched_journey_rerouted_count_; + ljf.unmatched_pax_rerouted_count_ += uj.passengers_; + + if (uj.group_sizes_.empty()) { + loader::motis_journeys::load_journey( + sched, uv, *journey, uj.source_, uj.passengers_, + route_source_flags::MATCH_REROUTED); + ++ljf.unmatched_group_rerouted_count_; + } else { + auto source = uj.source_; + for (auto const& group_size : uj.group_sizes_) { + loader::motis_journeys::load_journey( + sched, uv, *journey, source, group_size, + route_source_flags::MATCH_REROUTED); + ++source.secondary_ref_; + ++ljf.unmatched_group_rerouted_count_; + } + } + } + ljf.unmatched_journeys_.clear(); + } + } else { + for (auto& ljf : data.loaded_journey_files_) { + if (!ljf.unmatched_journeys_.empty()) { + LOG(warn) << "ignoring " << ljf.unmatched_journeys_.size() + << " unmatched journeys from " << ljf.path_.filename() + << ", set paxmon.reroute_unmatched=1 to enable rerouting"; + ljf.unmatched_journeys_.clear(); + } + } + } + + motis_call(make_no_msg("/ris/delayed_init"))->val(); +} + +} // namespace motis::paxmon diff --git a/modules/paxmon/src/loader/csv_journeys/csv_journeys.cc b/modules/paxmon/src/loader/csv_journeys/csv_journeys.cc index fd3588371e..b2e292f629 100644 --- a/modules/paxmon/src/loader/csv_journeys/csv_journeys.cc +++ b/modules/paxmon/src/loader/csv_journeys/csv_journeys.cc @@ -29,6 +29,7 @@ #include "motis/core/common/logging.h" #include "motis/core/schedule/time.h" #include "motis/core/access/station_access.h" +#include "motis/core/access/time_access.h" #include "motis/core/access/trip_iterator.h" #include "motis/core/conv/trip_conv.h" @@ -244,18 +245,24 @@ struct input_journey_leg { inline bool trip_found() const { return trp_candidate_.trp_ != nullptr; } - journey_leg to_journey_leg() const { + journey_leg to_journey_leg(bool adjust_times_to_schedule = true) const { utl::verify(stations_found(), "input_journey_leg.to_journey_leg(): stations not found"); utl::verify(valid_times(), "input_journey_leg.to_journey_leg(): invalid times"); utl::verify(trip_found(), "input_journey_leg.to_journey_leg(): trip not found"); + + auto const enter_time = + adjust_times_to_schedule ? trp_candidate_.enter_time_ : enter_time_; + auto const exit_time = + adjust_times_to_schedule ? trp_candidate_.exit_time_ : exit_time_; + return journey_leg{trp_candidate_.trp_->trip_idx_, from_station_idx_.value(), to_station_idx_.value(), - enter_time_, - exit_time_, + enter_time, + exit_time, enter_transfer_}; } @@ -471,6 +478,30 @@ time parse_trek_timestamp(std::string_view const val, date::time_zone const* tz, return unix_to_motistime(sched.schedule_begin_, unix_ts); } +compact_journey to_compact_journey( + std::vector const& input_legs, + std::size_t const start_idx, std::size_t const end_idx) { + auto cj = compact_journey{}; + + for (auto i = start_idx; i < end_idx; ++i) { + auto const& il = input_legs.at(i); + auto jl = il.to_journey_leg(); + if (!cj.legs_.empty() && cj.legs_.back().trip_idx_ == jl.trip_idx_) { + auto& prev_jl = cj.legs_.back(); + prev_jl.exit_station_id_ = jl.exit_station_id_; + prev_jl.exit_time_ = jl.exit_time_; + } else { + cj.legs_.push_back(jl); + } + } + + if (!cj.legs_.empty()) { + cj.legs_.front().enter_transfer_ = {}; + } + + return cj; +} + loader_result load_journeys(schedule const& sched, universe& uv, std::string const& journey_file, journey_input_settings const& settings) { @@ -509,6 +540,11 @@ loader_result load_journeys(schedule const& sched, universe& uv, std::uint16_t current_passengers = 0; auto const check_station_wait_time = settings.max_station_wait_time_ != 0; + auto const ext_begin = + unix_to_motistime(sched.schedule_begin_, external_schedule_begin(sched)); + auto const ext_end = + unix_to_motistime(sched.schedule_begin_, external_schedule_end(sched)); + auto const add_journey = [&](std::size_t start_idx, std::size_t end_idx, route_source_flags source_flags) { if (start_idx == end_idx) { @@ -545,13 +581,9 @@ loader_result load_journeys(schedule const& sched, universe& uv, if (all_trips_found && !invalid_transfer_times) { ++result.loaded_journey_count_; result.loaded_pax_count_ += current_passengers; - auto current_journey = compact_journey{}; - current_journey.legs_ = - utl::to_vec(std::next(begin(current_input_legs), start_idx), - std::next(begin(current_input_legs), end_idx), - [&](auto const& leg) { return leg.to_journey_leg(); }); + auto const current_journey = + to_compact_journey(current_input_legs, start_idx, end_idx); utl::verify(!current_journey.legs_.empty(), "empty csv journey"); - current_journey.legs_.front().enter_transfer_ = {}; if (current_journey.scheduled_duration() > 24 * 60) { ++journeys_too_long; return; @@ -579,6 +611,17 @@ loader_result load_journeys(schedule const& sched, universe& uv, add_passenger_group(uv, sched, tpg, false); } } else { + auto const& first_leg = current_input_legs.at(start_idx); + auto const& last_leg = current_input_legs.at(end_idx - 1); + + auto const departure_time = first_leg.enter_time_; + auto const arrival_time = last_leg.exit_time_; + + if (departure_time == INVALID_TIME || departure_time < ext_begin || + departure_time > ext_end) { + return; + } + if (!all_trips_found) { ++journeys_with_missing_trips; } @@ -587,28 +630,27 @@ loader_result load_journeys(schedule const& sched, universe& uv, } ++result.unmatched_journey_count_; result.unmatched_pax_count_ += current_passengers; - auto const& first_leg = current_input_legs.at(start_idx); - auto const& last_leg = current_input_legs.at(end_idx - 1); + + auto& uj = result.unmatched_journeys_.emplace_back(unmatched_journey{ + .start_station_idx_ = first_leg.from_station_idx_.value(), + .destination_station_idx_ = last_leg.to_station_idx_.value(), + .departure_time_ = departure_time, + .arrival_time_ = arrival_time, + .source_ = source, + .passengers_ = current_passengers}); + if (split_groups) { - source.secondary_ref_ *= 100; + uj.source_.secondary_ref_ *= 100; auto distributed = 0U; while (distributed < current_passengers) { auto const group_size = group_gen.get_group_size(current_passengers - distributed); - ++source.secondary_ref_; distributed += group_size; ++result.unmatched_group_count_; - result.unmatched_journeys_.emplace_back( - unmatched_journey{first_leg.from_station_idx_.value(), - last_leg.to_station_idx_.value(), - first_leg.enter_time_, source, group_size}); + uj.group_sizes_.emplace_back(group_size); } } else { ++result.unmatched_group_count_; - result.unmatched_journeys_.emplace_back(unmatched_journey{ - first_leg.from_station_idx_.value(), - last_leg.to_station_idx_.value(), first_leg.enter_time_, source, - current_passengers}); } } }; diff --git a/modules/paxmon/src/paxmon.cc b/modules/paxmon/src/paxmon.cc index 96fc05aefd..3d1fbfa7cd 100644 --- a/modules/paxmon/src/paxmon.cc +++ b/modules/paxmon/src/paxmon.cc @@ -16,7 +16,6 @@ #include "motis/core/common/timing.h" #include "motis/core/conv/station_conv.h" #include "motis/core/conv/trip_conv.h" -#include "motis/core/journey/message_to_journeys.h" #include "motis/module/context/motis_call.h" #include "motis/module/context/motis_publish.h" #include "motis/module/event_collector.h" @@ -51,6 +50,7 @@ #include "motis/paxmon/broken_interchanges_report.h" #include "motis/paxmon/checks.h" +#include "motis/paxmon/delayed_init.h" #include "motis/paxmon/file_time.h" #include "motis/paxmon/generate_capacities.h" #include "motis/paxmon/get_universe.h" @@ -109,8 +109,6 @@ paxmon::paxmon() : module("Passenger Monitoring", "paxmon"), data_{*this} { param(initial_broken_report_file_, "broken_report", "initial broken interchanges report file"); param(reroute_unmatched_, "reroute_unmatched", "reroute unmatched journeys"); - param(initial_reroute_query_file_, "reroute_file", - "output file for initial rerouted journeys"); param(initial_reroute_router_, "reroute_router", "router for initial reroute queries"); param(start_time_, "start_time", "evaluation start time"); @@ -209,24 +207,11 @@ void paxmon::init(motis::module::registry& reg) { stats_writer_ = std::make_unique(stats_file_); reg.subscribe( - "/init", - [&]() { - auto const& primary_uv = primary_universe(); - if (primary_uv.capacity_maps_.trip_capacity_map_.empty() && - primary_uv.capacity_maps_.category_capacity_map_.empty()) { - LOG(warn) << "no capacity information available"; - } - LOG(info) << "tracking " << primary_uv.passenger_groups_.size() - << " passenger groups"; - - shared_data_->register_timer("PaxMon Universe GC", - boost::posix_time::seconds{10}, - [this]() { universe_gc(); }, {}); - }, + "/init", [&]() { init_op(); }, {ctx::access_request{to_res_id(global_res_id::SCHEDULE), ctx::access_t::READ}, ctx::access_request{to_res_id(global_res_id::PAX_DEFAULT_UNIVERSE), - ctx::access_t::READ}}); + ctx::access_t::WRITE}}); reg.register_op("/paxmon/flush", [&](msg_ptr const&) -> msg_ptr { @@ -493,6 +478,25 @@ void paxmon::init(motis::module::registry& reg) { } } +void paxmon::init_op() { + delayed_init( + data_, primary_universe(), get_sched(), + delay_init_options{.reroute_unmatched_ = reroute_unmatched_, + .initial_reroute_router_ = initial_reroute_router_}); + + auto const& primary_uv = primary_universe(); + if (primary_uv.capacity_maps_.trip_capacity_map_.empty() && + primary_uv.capacity_maps_.category_capacity_map_.empty()) { + LOG(warn) << "no capacity information available"; + } + LOG(info) << "tracking " << primary_uv.passenger_groups_.size() + << " passenger groups"; + + shared_data_->register_timer("PaxMon Universe GC", + boost::posix_time::seconds{10}, + [this]() { universe_gc(); }, {}); +} + loader::loader_result paxmon::load_journeys(std::string const& file) { auto const journey_path = fs::path{file}; if (!fs::exists(journey_path)) { @@ -517,39 +521,6 @@ loader::loader_result paxmon::load_journeys(std::string const& file) { return result; } -msg_ptr initial_reroute_query(schedule const& sched, - loader::unmatched_journey const& uj, - std::string const& router) { - message_creator fbb; - auto const planned_departure = - motis_to_unixtime(sched.schedule_begin_, uj.departure_time_); - auto const interval = Interval{planned_departure - 2 * 60 * 60, - planned_departure + 2 * 60 * 60}; - auto const& start_station = sched.stations_.at(uj.start_station_idx_); - auto const& destination_station = - sched.stations_.at(uj.destination_station_idx_); - fbb.create_and_finish( - MsgContent_RoutingRequest, - CreateRoutingRequest( - fbb, Start_PretripStart, - CreatePretripStart( - fbb, - CreateInputStation(fbb, fbb.CreateString(start_station->eva_nr_), - fbb.CreateString(start_station->name_)), - &interval) - .Union(), - CreateInputStation(fbb, - fbb.CreateString(destination_station->eva_nr_), - fbb.CreateString(destination_station->name_)), - SearchType_Default, SearchDir_Forward, - fbb.CreateVector(std::vector>{}), - fbb.CreateVector( - std::vector>{})) - .Union(), - router); - return make_msg(fbb); -} - void paxmon::load_journeys() { auto const& sched = get_sched(); auto& uv = primary_universe(); @@ -564,57 +535,19 @@ void paxmon::load_journeys() { } { - std::unique_ptr converter; - if (reroute_unmatched_ && !initial_reroute_query_file_.empty()) { - converter = std::make_unique( - initial_reroute_query_file_); - } for (auto const& file : journey_files_) { - auto const result = load_journeys(file); + auto result = load_journeys(file); auto const path = std::filesystem::path{file}; - auto& ljf = data_.loaded_journey_files_.emplace_back(loaded_journey_file{ + data_.loaded_journey_files_.emplace_back(loaded_journey_file{ .path_ = path, .last_modified_ = get_last_modified_time(path), - .matched_journeys_ = result.loaded_journey_count_, - .unmatched_journeys_ = result.unmatched_journey_count_, - .matched_groups_ = result.loaded_group_count_, - .unmatched_groups_ = result.unmatched_group_count_, - .matched_pax_ = result.loaded_pax_count_, - .unmatched_pax_ = result.unmatched_pax_count_}); - if (reroute_unmatched_) { - // TODO(pablo): needs to be moved out of import - // TODO(pablo): group by journey, not pax group - scoped_timer const timer{"reroute unmatched journeys"}; - LOG(info) << "routing " << result.unmatched_journeys_.size() - << " unmatched journeys using " << initial_reroute_router_ - << "..."; - auto const futures = - utl::to_vec(result.unmatched_journeys_, [&](auto const& uj) { - return motis_call( - initial_reroute_query(sched, uj, initial_reroute_router_)); - }); - ctx::await_all(futures); - LOG(info) << "adding replacement journeys..."; - for (auto const& [uj, fut] : - utl::zip(result.unmatched_journeys_, futures)) { - auto const rr_msg = fut->val(); - auto const rr = motis_content(RoutingResponse, rr_msg); - auto const journeys = message_to_journeys(rr); - if (journeys.empty()) { - continue; - } - ++ljf.unmatched_groups_rerouted_; - ljf.unmatched_pax_rerouted_ += uj.passengers_; - // TODO(pablo): select journey(s) - if (converter) { - converter->write_journey(journeys.front(), uj.source_.primary_ref_, - uj.source_.secondary_ref_, uj.passengers_); - } - loader::motis_journeys::load_journey( - sched, uv, journeys.front(), uj.source_, uj.passengers_, - route_source_flags::MATCH_REROUTED); - } - } + .matched_journey_count_ = result.loaded_journey_count_, + .unmatched_journey_count_ = result.unmatched_journey_count_, + .matched_group_count_ = result.loaded_group_count_, + .unmatched_group_count_ = result.unmatched_group_count_, + .matched_pax_count_ = result.loaded_pax_count_, + .unmatched_pax_count_ = result.unmatched_pax_count_, + .unmatched_journeys_ = std::move(result.unmatched_journeys_)}); progress_tracker->increment(); } } diff --git a/modules/ris/include/motis/ris/ribasis/ribasis_receiver.h b/modules/ris/include/motis/ris/ribasis/ribasis_receiver.h index 4547a60dce..7408a04c8b 100644 --- a/modules/ris/include/motis/ris/ribasis/ribasis_receiver.h +++ b/modules/ris/include/motis/ris/ribasis/ribasis_receiver.h @@ -23,6 +23,7 @@ struct receiver { msg_handler_fn msg_handler, amqp::get_stream_options_fn_t get_stream_options); + void start(); void stop(); std::string const& queue_id() const; diff --git a/modules/ris/include/motis/ris/ris.h b/modules/ris/include/motis/ris/ris.h index 0e1ef725d3..ae7e786116 100644 --- a/modules/ris/include/motis/ris/ris.h +++ b/modules/ris/include/motis/ris/ris.h @@ -17,6 +17,7 @@ struct config { std::string db_path_{"ris.mdb"}; std::vector input_; conf::time init_time_{0}; + bool delayed_init_{false}; bool clear_db_ = false; conf::duration init_purge_{}; size_t db_max_size_{static_cast(1024) * 1024 * 1024 * 512}; diff --git a/modules/ris/src/ribasis/ribasis_receiver.cc b/modules/ris/src/ribasis/ribasis_receiver.cc index 4c7c2b9e41..81786f0ce2 100644 --- a/modules/ris/src/ribasis/ribasis_receiver.cc +++ b/modules/ris/src/ribasis/ribasis_receiver.cc @@ -27,7 +27,6 @@ receiver::receiver(rabbitmq_config config, source_status& status, status_{status} { status_.enabled_ = true; status_.update_interval_ = config_.update_interval_; - connection_.run([this](amqp::msg const& m) { on_msg(m); }); } void receiver::log(std::string const& log_msg) { @@ -49,6 +48,10 @@ void receiver::on_msg(amqp::msg const& m) { } } +void receiver::start() { + connection_.run([this](amqp::msg const& m) { on_msg(m); }); +} + void receiver::stop() { connection_.stop(); } std::string const& receiver::queue_id() const { return queue_id_; } diff --git a/modules/ris/src/ris.cc b/modules/ris/src/ris.cc index 5ce275deb3..86920b8d5c 100644 --- a/modules/ris/src/ris.cc +++ b/modules/ris/src/ris.cc @@ -266,7 +266,8 @@ struct ris::impl { std::unique_ptr con_; }; - explicit impl(config& c) : config_{c} {} + explicit impl(config& c) + : perform_init_forward_{!c.delayed_init_}, config_{c} {} void init_ribasis_receivers(dispatcher* d, schedule* sched) { for_each_rabbitmq_config(config_, [this, &d, &sched]( @@ -473,11 +474,34 @@ struct ris::impl { ctx::access_t::WRITE}}); } + init_ribasis_receivers(&d, &sched); + + init_done_ = true; + if (perform_init_forward_) { + init_forward(sched); + } + } + + bool init_forward(schedule& sched) { + if (init_forward_started_.exchange(true)) { + return false; + } if (config_.init_time_.unix_time_ != 0) { forward(sched, 0U, config_.init_time_.unix_time_, true, true); } + for (auto& r : ribasis_receivers_) { + r->start(); + } + init_forward_done_ = true; + return true; + } - init_ribasis_receivers(&d, &sched); + msg_ptr delayed_init(schedule& sched) { + perform_init_forward_ = true; + if (init_done_) { + init_forward(sched); + } + return {}; } static std::string_view get_content_type(HTTPRequest const* req) { @@ -747,7 +771,7 @@ struct ris::impl { } pub.flush(); - sched.system_time_ = to; + update_system_time(sched, pub); if (init_forward) { init_status_.enabled_ = true; init_status_.add_update(pub.message_count_, pub.max_timestamp_); @@ -1176,7 +1200,8 @@ struct ris::impl { status_to_fbs(ribasis_fahrt_status_), status_to_fbs(ribasis_formation_status_), status_to_fbs(upload_status_), status_to_fbs(read_status_), - status_to_fbs(init_status_)) + status_to_fbs(init_status_), config_.delayed_init_, + init_forward_started_, init_forward_done_) .Union()); return make_msg(mc); } @@ -1185,6 +1210,11 @@ struct ris::impl { std::mutex min_max_mutex_; std::mutex merge_mutex_; + std::atomic perform_init_forward_; + std::atomic init_forward_started_; + std::atomic init_done_; + bool init_forward_done_{}; + config& config_; std::unique_ptr file_upload_; @@ -1207,6 +1237,8 @@ ris::ris() : module("RIS", "ris") { "timetable)"); param(config_.db_max_size_, "db_max_size", "virtual memory map size"); param(config_.init_time_, "init_time", "initial forward time"); + param(config_.delayed_init_, "delayed_init", + "delayed init (required for RSL)"); param(config_.clear_db_, "clear_db", "clean db before init"); param(config_.init_purge_, "init_purge", "remove messages older than this value from the database during " @@ -1337,6 +1369,18 @@ void ris::init(motis::module::registry& r) { r.register_op("/ris/status", [this](auto&& /*m*/) { return impl_->status(get_sched()); }, {kScheduleReadAccess}); + r.register_op( + "/ris/delayed_init", + [this](auto&& /*m*/) { + return impl_->delayed_init( + const_cast(get_sched())); // NOLINT + }, + ctx::accesses_t{ctx::access_request{ + to_res_id(::motis::module::global_res_id::RIS_DATA), + ctx::access_t::WRITE}, + ctx::access_request{ + to_res_id(::motis::module::global_res_id::SCHEDULE), + ctx::access_t::WRITE}}); } void ris::import(motis::module::import_dispatcher& reg) { diff --git a/protocol/ris/RISStatusResponse.fbs b/protocol/ris/RISStatusResponse.fbs index 570cab3d43..c781edcee8 100644 --- a/protocol/ris/RISStatusResponse.fbs +++ b/protocol/ris/RISStatusResponse.fbs @@ -20,4 +20,8 @@ table RISStatusResponse { upload_status: RISSourceStatus; read_status: RISSourceStatus; init_status: RISSourceStatus; + + delayed_init: bool; + init_forward_started: bool; + init_forward_done: bool; } diff --git a/ui/rsl/package.json b/ui/rsl/package.json index af528b665f..45ae613d91 100644 --- a/ui/rsl/package.json +++ b/ui/rsl/package.json @@ -30,8 +30,8 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", - "@tanstack/react-query": "^5.10.0", - "@tanstack/react-query-devtools": "^5.10.0", + "@tanstack/react-query": "^5.12.2", + "@tanstack/react-query-devtools": "^5.13.3", "@visx/axis": "^3.5.0", "@visx/clip-path": "^3.3.0", "@visx/event": "^3.3.0", @@ -58,37 +58,37 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.48.2", - "react-router-dom": "^6.20.0", + "react-router-dom": "^6.20.1", "react-virtuoso": "^4.6.2", - "tailwind-merge": "^2.0.0", + "tailwind-merge": "^2.1.0", "tailwindcss-animate": "^1.0.7", "uuid": "^9.0.1" }, "devDependencies": { "@limegrass/eslint-plugin-import-alias": "^1.1.0", "@tailwindcss/forms": "^0.5.7", - "@tanstack/eslint-plugin-query": "^5.10.0", + "@tanstack/eslint-plugin-query": "^5.12.1", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/d3-array": "^3.2.1", "@types/d3-force": "^3.0.9", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.10.1", - "@types/react": "^18.2.39", + "@types/node": "^20.10.3", + "@types/react": "^18.2.42", "@types/react-dom": "^18.2.17", "@types/uuid": "^9.0.7", - "@typescript-eslint/eslint-plugin": "^6.13.1", - "@typescript-eslint/parser": "^6.13.1", - "@vitejs/plugin-react": "^4.2.0", + "@typescript-eslint/eslint-plugin": "^6.13.2", + "@typescript-eslint/parser": "^6.13.2", + "@vitejs/plugin-react": "^4.2.1", "autoprefixer": "^10.4.16", - "eslint": "^8.54.0", - "eslint-config-prettier": "^9.0.0", + "eslint": "^8.55.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", - "postcss": "^8.4.31", + "postcss": "^8.4.32", "prettier": "^3.1.0", - "prettier-plugin-tailwindcss": "^0.5.7", - "tailwindcss": "^3.3.5", + "prettier-plugin-tailwindcss": "^0.5.9", + "tailwindcss": "^3.3.6", "typescript": "^5.3.2", - "vite": "^5.0.4" + "vite": "^5.0.6" } } diff --git a/ui/rsl/pnpm-lock.yaml b/ui/rsl/pnpm-lock.yaml index e28da98c97..69a97c51b3 100644 --- a/ui/rsl/pnpm-lock.yaml +++ b/ui/rsl/pnpm-lock.yaml @@ -10,46 +10,46 @@ dependencies: version: 1.7.17(react-dom@18.2.0)(react@18.2.0) '@headlessui/tailwindcss': specifier: ^0.2.0 - version: 0.2.0(tailwindcss@3.3.5) + version: 0.2.0(tailwindcss@3.3.6) '@heroicons/react': specifier: ^2.0.18 version: 2.0.18(react@18.2.0) '@radix-ui/react-checkbox': specifier: ^1.0.4 - version: 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-dialog': specifier: ^1.0.5 - version: 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-hover-card': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-label': specifier: ^2.0.2 - version: 2.0.2(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 2.0.2(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-popover': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-select': specifier: ^2.0.0 - version: 2.0.0(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 2.0.0(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-slot': specifier: ^1.0.2 - version: 1.0.2(@types/react@18.2.39)(react@18.2.0) + version: 1.0.2(@types/react@18.2.42)(react@18.2.0) '@radix-ui/react-switch': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-tabs': specifier: ^1.0.4 - version: 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-tooltip': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) '@tanstack/react-query': - specifier: ^5.10.0 - version: 5.10.0(react@18.2.0) + specifier: ^5.12.2 + version: 5.12.2(react@18.2.0) '@tanstack/react-query-devtools': - specifier: ^5.10.0 - version: 5.10.0(@tanstack/react-query@5.10.0)(react@18.2.0) + specifier: ^5.13.3 + version: 5.13.3(@tanstack/react-query@5.12.2)(react@18.2.0) '@visx/axis': specifier: ^3.5.0 version: 3.5.0(react@18.2.0) @@ -94,7 +94,7 @@ dependencies: version: 2.0.0 cmdk: specifier: ^0.2.0 - version: 0.2.0(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + version: 0.2.0(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) d3-array: specifier: ^3.2.4 version: 3.2.4 @@ -106,7 +106,7 @@ dependencies: version: 8.2.3(react@18.2.0) jotai: specifier: ^2.6.0 - version: 2.6.0(@types/react@18.2.39)(react@18.2.0) + version: 2.6.0(@types/react@18.2.42)(react@18.2.0) jotai-optics: specifier: ^0.3.1 version: 0.3.1(jotai@2.6.0)(optics-ts@2.4.1) @@ -129,17 +129,17 @@ dependencies: specifier: ^7.48.2 version: 7.48.2(react@18.2.0) react-router-dom: - specifier: ^6.20.0 - version: 6.20.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^6.20.1 + version: 6.20.1(react-dom@18.2.0)(react@18.2.0) react-virtuoso: specifier: ^4.6.2 version: 4.6.2(react-dom@18.2.0)(react@18.2.0) tailwind-merge: - specifier: ^2.0.0 - version: 2.0.0 + specifier: ^2.1.0 + version: 2.1.0 tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.3.5) + version: 1.0.7(tailwindcss@3.3.6) uuid: specifier: ^9.0.1 version: 9.0.1 @@ -147,13 +147,13 @@ dependencies: devDependencies: '@limegrass/eslint-plugin-import-alias': specifier: ^1.1.0 - version: 1.1.0(eslint@8.54.0) + version: 1.1.0(eslint@8.55.0) '@tailwindcss/forms': specifier: ^0.5.7 - version: 0.5.7(tailwindcss@3.3.5) + version: 0.5.7(tailwindcss@3.3.6) '@tanstack/eslint-plugin-query': - specifier: ^5.10.0 - version: 5.10.0(eslint@8.54.0)(typescript@5.3.2) + specifier: ^5.12.1 + version: 5.12.1(eslint@8.55.0)(typescript@5.3.2) '@trivago/prettier-plugin-sort-imports': specifier: ^4.3.0 version: 4.3.0(prettier@3.1.0) @@ -167,11 +167,11 @@ devDependencies: specifier: ^4.17.12 version: 4.17.12 '@types/node': - specifier: ^20.10.1 - version: 20.10.1 + specifier: ^20.10.3 + version: 20.10.3 '@types/react': - specifier: ^18.2.39 - version: 18.2.39 + specifier: ^18.2.42 + version: 18.2.42 '@types/react-dom': specifier: ^18.2.17 version: 18.2.17 @@ -179,47 +179,47 @@ devDependencies: specifier: ^9.0.7 version: 9.0.7 '@typescript-eslint/eslint-plugin': - specifier: ^6.13.1 - version: 6.13.1(@typescript-eslint/parser@6.13.1)(eslint@8.54.0)(typescript@5.3.2) + specifier: ^6.13.2 + version: 6.13.2(@typescript-eslint/parser@6.13.2)(eslint@8.55.0)(typescript@5.3.2) '@typescript-eslint/parser': - specifier: ^6.13.1 - version: 6.13.1(eslint@8.54.0)(typescript@5.3.2) + specifier: ^6.13.2 + version: 6.13.2(eslint@8.55.0)(typescript@5.3.2) '@vitejs/plugin-react': - specifier: ^4.2.0 - version: 4.2.0(vite@5.0.4) + specifier: ^4.2.1 + version: 4.2.1(vite@5.0.6) autoprefixer: specifier: ^10.4.16 - version: 10.4.16(postcss@8.4.31) + version: 10.4.16(postcss@8.4.32) eslint: - specifier: ^8.54.0 - version: 8.54.0 + specifier: ^8.55.0 + version: 8.55.0 eslint-config-prettier: - specifier: ^9.0.0 - version: 9.0.0(eslint@8.54.0) + specifier: ^9.1.0 + version: 9.1.0(eslint@8.55.0) eslint-plugin-react: specifier: ^7.33.2 - version: 7.33.2(eslint@8.54.0) + version: 7.33.2(eslint@8.55.0) eslint-plugin-react-hooks: specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) + version: 4.6.0(eslint@8.55.0) postcss: - specifier: ^8.4.31 - version: 8.4.31 + specifier: ^8.4.32 + version: 8.4.32 prettier: specifier: ^3.1.0 version: 3.1.0 prettier-plugin-tailwindcss: - specifier: ^0.5.7 - version: 0.5.7(@trivago/prettier-plugin-sort-imports@4.3.0)(prettier@3.1.0) + specifier: ^0.5.9 + version: 0.5.9(@trivago/prettier-plugin-sort-imports@4.3.0)(prettier@3.1.0) tailwindcss: - specifier: ^3.3.5 - version: 3.3.5 + specifier: ^3.3.6 + version: 3.3.6 typescript: specifier: ^5.3.2 version: 5.3.2 vite: - specifier: ^5.0.4 - version: 5.0.4(@types/node@20.10.1) + specifier: ^5.0.6 + version: 5.0.6(@types/node@20.10.3) packages: @@ -301,7 +301,7 @@ packages: dependencies: '@babel/compat-data': 7.23.5 '@babel/helper-validator-option': 7.23.5 - browserslist: 4.22.1 + browserslist: 4.22.2 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -696,13 +696,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.54.0 + eslint: 8.55.0 eslint-visitor-keys: 3.4.3 dev: true @@ -711,8 +711,8 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.3: - resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -728,13 +728,13 @@ packages: - supports-color dev: true - /@eslint/js@8.54.0: - resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} + /@eslint/js@8.55.0: + resolution: {integrity: sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@floating-ui/core@1.5.0: - resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==} + /@floating-ui/core@1.5.2: + resolution: {integrity: sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==} dependencies: '@floating-ui/utils': 0.1.6 dev: false @@ -742,7 +742,7 @@ packages: /@floating-ui/dom@1.5.3: resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==} dependencies: - '@floating-ui/core': 1.5.0 + '@floating-ui/core': 1.5.2 '@floating-ui/utils': 0.1.6 dev: false @@ -773,13 +773,13 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@headlessui/tailwindcss@0.2.0(tailwindcss@3.3.5): + /@headlessui/tailwindcss@0.2.0(tailwindcss@3.3.6): resolution: {integrity: sha512-fpL830Fln1SykOCboExsWr3JIVeQKieLJ3XytLe/tt1A0XzqUthOftDmjcCYLW62w7mQI7wXcoPXr3tZ9QfGxw==} engines: {node: '>=10'} peerDependencies: tailwindcss: ^3.0 dependencies: - tailwindcss: 3.3.5 + tailwindcss: 3.3.6 dev: false /@heroicons/react@2.0.18(react@18.2.0): @@ -835,12 +835,12 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 - /@limegrass/eslint-plugin-import-alias@1.1.0(eslint@8.54.0): + /@limegrass/eslint-plugin-import-alias@1.1.0(eslint@8.55.0): resolution: {integrity: sha512-nC7fz4c+HXYoE+ZP7KxSURl8nEdcvsu0mQsp6oJ8DrBu9KV1NlhCyjqBTLB1TaaMtDqU0xYKoUrge6i+SHgyVQ==} peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 dependencies: - eslint: 8.54.0 + eslint: 8.55.0 find-up: 5.0.0 fs-extra: 10.1.0 micromatch: 4.0.5 @@ -884,7 +884,7 @@ packages: '@babel/runtime': 7.23.5 dev: false - /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} peerDependencies: '@types/react': '*' @@ -898,14 +898,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==} peerDependencies: '@types/react': '*' @@ -920,20 +920,20 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} peerDependencies: '@types/react': '*' @@ -947,11 +947,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -966,7 +966,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: '@types/react': '*' @@ -976,7 +976,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -989,7 +989,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-context@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-context@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} peerDependencies: '@types/react': '*' @@ -999,11 +999,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-dialog@1.0.0(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dialog@1.0.0(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==} peerDependencies: react: ^16.8 || ^17.0 || ^18.0 @@ -1025,12 +1025,12 @@ packages: aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.4(@types/react@18.2.39)(react@18.2.0) + react-remove-scroll: 2.5.4(@types/react@18.2.42)(react@18.2.0) transitivePeerDependencies: - '@types/react' dev: false - /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: '@types/react': '*' @@ -1045,26 +1045,26 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.39)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.42)(react@18.2.0) dev: false - /@radix-ui/react-direction@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-direction@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} peerDependencies: '@types/react': '*' @@ -1074,7 +1074,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -1094,7 +1094,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} peerDependencies: '@types/react': '*' @@ -1109,11 +1109,11 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1128,7 +1128,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} peerDependencies: '@types/react': '*' @@ -1138,7 +1138,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -1156,7 +1156,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: '@types/react': '*' @@ -1170,16 +1170,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-hover-card@1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-hover-card@1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==} peerDependencies: '@types/react': '*' @@ -1194,15 +1194,15 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1218,7 +1218,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-id@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-id@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: '@types/react': '*' @@ -1228,12 +1228,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} peerDependencies: '@types/react': '*' @@ -1247,14 +1247,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} peerDependencies: '@types/react': '*' @@ -1269,27 +1269,27 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.39)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.42)(react@18.2.0) dev: false - /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} peerDependencies: '@types/react': '*' @@ -1304,16 +1304,16 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@floating-ui/react-dom': 2.0.4(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.39)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.42)(react@18.2.0) '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1331,7 +1331,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} peerDependencies: '@types/react': '*' @@ -1345,8 +1345,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1365,7 +1365,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: '@types/react': '*' @@ -1379,9 +1379,9 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1399,7 +1399,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: '@types/react': '*' @@ -1413,14 +1413,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} peerDependencies: '@types/react': '*' @@ -1435,21 +1435,21 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} peerDependencies: '@types/react': '*' @@ -1465,29 +1465,29 @@ packages: '@babel/runtime': 7.23.5 '@radix-ui/number': 1.0.1 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.5(@types/react@18.2.39)(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.42)(react@18.2.0) dev: false /@radix-ui/react-slot@1.0.0(react@18.2.0): @@ -1500,7 +1500,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-slot@1.0.2(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-slot@1.0.2(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: '@types/react': '*' @@ -1510,12 +1510,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==} peerDependencies: '@types/react': '*' @@ -1530,19 +1530,19 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==} peerDependencies: '@types/react': '*' @@ -1557,20 +1557,20 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-direction': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} peerDependencies: '@types/react': '*' @@ -1585,18 +1585,18 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-context': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-id': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-slot': 1.0.2(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1611,7 +1611,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: '@types/react': '*' @@ -1621,7 +1621,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -1635,7 +1635,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} peerDependencies: '@types/react': '*' @@ -1645,8 +1645,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -1660,7 +1660,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} peerDependencies: '@types/react': '*' @@ -1670,8 +1670,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -1684,7 +1684,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} peerDependencies: '@types/react': '*' @@ -1694,11 +1694,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} peerDependencies: '@types/react': '*' @@ -1708,11 +1708,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: '@types/react': '*' @@ -1723,11 +1723,11 @@ packages: dependencies: '@babel/runtime': 7.23.5 '@radix-ui/rect': 1.0.1 - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-use-size@1.0.1(@types/react@18.2.39)(react@18.2.0): + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} peerDependencies: '@types/react': '*' @@ -1737,12 +1737,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.39)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.42)(react@18.2.0) + '@types/react': 18.2.42 react: 18.2.0 dev: false - /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} peerDependencies: '@types/react': '*' @@ -1756,8 +1756,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.5 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.39 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.17)(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.42 '@types/react-dom': 18.2.17 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1769,8 +1769,8 @@ packages: '@babel/runtime': 7.23.5 dev: false - /@remix-run/router@1.13.0: - resolution: {integrity: sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA==} + /@remix-run/router@1.13.1: + resolution: {integrity: sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q==} engines: {node: '>=14.0.0'} dev: false @@ -1870,52 +1870,52 @@ packages: dev: true optional: true - /@tailwindcss/forms@0.5.7(tailwindcss@3.3.5): + /@tailwindcss/forms@0.5.7(tailwindcss@3.3.6): resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.3.5 + tailwindcss: 3.3.6 dev: true - /@tanstack/eslint-plugin-query@5.10.0(eslint@8.54.0)(typescript@5.3.2): - resolution: {integrity: sha512-gbvdw5qGfk3/eNUPKq+akR/JUqI6rfEILulUWx2utiMHXmPSRmExCbK7YLGy9yrfK4Mi5njT7UshVX3awlrQbw==} + /@tanstack/eslint-plugin-query@5.12.1(eslint@8.55.0)(typescript@5.3.2): + resolution: {integrity: sha512-FuG/mN9cUO8KlT7KJzl8Yiw55uyXz1vzxXfoMnBbgiH8vk5WtUbEMdFeDF4ujgO+VSKR10uDdZ1+TIOpHhDUfQ==} peerDependencies: eslint: ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.54.0)(typescript@5.3.2) - eslint: 8.54.0 + '@typescript-eslint/utils': 5.62.0(eslint@8.55.0)(typescript@5.3.2) + eslint: 8.55.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@tanstack/query-core@5.10.0: - resolution: {integrity: sha512-wlw/l2E+U70iABaJnOtZIJN/5VMhuj4RPViafwUYiIGoqw1VqqqaxBnBL90qLhWswoOaK8RAj3+NiG0duk+cRg==} + /@tanstack/query-core@5.12.1: + resolution: {integrity: sha512-WbZztNmKq0t6QjdNmHzezbi/uifYo9j6e2GLJkodsYaYUlzMbAp91RDyeHkIZrm7EfO4wa6Sm5sxJZm5SPlh6w==} dev: false - /@tanstack/query-devtools@5.10.0: - resolution: {integrity: sha512-ZN17ZHiPFc8B1AZplueTLI6qxqNPuelV/8Q6gx2coNac2++AD1gq8NvCQxfq9HoaqFJM8xqS3oPYxa3HZZTo8w==} + /@tanstack/query-devtools@5.13.3: + resolution: {integrity: sha512-1acztPKZexvM9Ns2T0aq4rMVSDA3VGdB73KF7zT/KNVl6VfnBvs24wuIRVSPZKqyZznZTzT3/DzcpntYqg9hmw==} dev: false - /@tanstack/react-query-devtools@5.10.0(@tanstack/react-query@5.10.0)(react@18.2.0): - resolution: {integrity: sha512-amQN/6BdSMiYtILISk5j3IrZZiWz+HOHjJdcJNZHaTpzS7aIM1Z82bghCSoPdBtS7P1KbdoW35aD4glm9EkIuQ==} + /@tanstack/react-query-devtools@5.13.3(@tanstack/react-query@5.12.2)(react@18.2.0): + resolution: {integrity: sha512-ct58CMRrcjANRWCQ6cxzSUtme2jlX5au63+ckhMONob8bIk5VRfUEi4R49AWNJFL5haTBKe0InC0AV4bWi75VQ==} peerDependencies: - '@tanstack/react-query': ^5.10.0 + '@tanstack/react-query': ^5.12.2 react: ^18.0.0 dependencies: - '@tanstack/query-devtools': 5.10.0 - '@tanstack/react-query': 5.10.0(react@18.2.0) + '@tanstack/query-devtools': 5.13.3 + '@tanstack/react-query': 5.12.2(react@18.2.0) react: 18.2.0 dev: false - /@tanstack/react-query@5.10.0(react@18.2.0): - resolution: {integrity: sha512-LeJsyXUvhq1TBsEbt3SSEaxP2Att1sv/qW588GL/bvjxPxsLUBWKGuFJ5Z1YP+/nJqVmcXJE8AtvZaaxE9rsKQ==} + /@tanstack/react-query@5.12.2(react@18.2.0): + resolution: {integrity: sha512-BeWZu8zVFH20oRc+S/K9ADPgWjEzP/XQCGBNz5IbApUwPQAdwkQYbXODVL5AyAlWiSxhx+P2xlARPBApj2Yrog==} peerDependencies: react: ^18.0.0 dependencies: - '@tanstack/query-core': 5.10.0 + '@tanstack/query-core': 5.12.1 react: 18.2.0 dev: false @@ -2053,8 +2053,8 @@ packages: /@types/lodash@4.14.202: resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} - /@types/node@20.10.1: - resolution: {integrity: sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==} + /@types/node@20.10.3: + resolution: {integrity: sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==} dependencies: undici-types: 5.26.5 dev: true @@ -2065,10 +2065,10 @@ packages: /@types/react-dom@18.2.17: resolution: {integrity: sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==} dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 - /@types/react@18.2.39: - resolution: {integrity: sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==} + /@types/react@18.2.42: + resolution: {integrity: sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==} dependencies: '@types/prop-types': 15.7.11 '@types/scheduler': 0.16.8 @@ -2085,8 +2085,8 @@ packages: resolution: {integrity: sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==} dev: true - /@typescript-eslint/eslint-plugin@6.13.1(@typescript-eslint/parser@6.13.1)(eslint@8.54.0)(typescript@5.3.2): - resolution: {integrity: sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==} + /@typescript-eslint/eslint-plugin@6.13.2(@typescript-eslint/parser@6.13.2)(eslint@8.55.0)(typescript@5.3.2): + resolution: {integrity: sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -2097,13 +2097,13 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.13.1(eslint@8.54.0)(typescript@5.3.2) - '@typescript-eslint/scope-manager': 6.13.1 - '@typescript-eslint/type-utils': 6.13.1(eslint@8.54.0)(typescript@5.3.2) - '@typescript-eslint/utils': 6.13.1(eslint@8.54.0)(typescript@5.3.2) - '@typescript-eslint/visitor-keys': 6.13.1 + '@typescript-eslint/parser': 6.13.2(eslint@8.55.0)(typescript@5.3.2) + '@typescript-eslint/scope-manager': 6.13.2 + '@typescript-eslint/type-utils': 6.13.2(eslint@8.55.0)(typescript@5.3.2) + '@typescript-eslint/utils': 6.13.2(eslint@8.55.0)(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.13.2 debug: 4.3.4 - eslint: 8.54.0 + eslint: 8.55.0 graphemer: 1.4.0 ignore: 5.3.0 natural-compare: 1.4.0 @@ -2114,8 +2114,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.13.1(eslint@8.54.0)(typescript@5.3.2): - resolution: {integrity: sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ==} + /@typescript-eslint/parser@6.13.2(eslint@8.55.0)(typescript@5.3.2): + resolution: {integrity: sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -2124,12 +2124,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.13.1 - '@typescript-eslint/types': 6.13.1 - '@typescript-eslint/typescript-estree': 6.13.1(typescript@5.3.2) - '@typescript-eslint/visitor-keys': 6.13.1 + '@typescript-eslint/scope-manager': 6.13.2 + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.13.2 debug: 4.3.4 - eslint: 8.54.0 + eslint: 8.55.0 typescript: 5.3.2 transitivePeerDependencies: - supports-color @@ -2143,16 +2143,16 @@ packages: '@typescript-eslint/visitor-keys': 5.62.0 dev: true - /@typescript-eslint/scope-manager@6.13.1: - resolution: {integrity: sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==} + /@typescript-eslint/scope-manager@6.13.2: + resolution: {integrity: sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.13.1 - '@typescript-eslint/visitor-keys': 6.13.1 + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/visitor-keys': 6.13.2 dev: true - /@typescript-eslint/type-utils@6.13.1(eslint@8.54.0)(typescript@5.3.2): - resolution: {integrity: sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==} + /@typescript-eslint/type-utils@6.13.2(eslint@8.55.0)(typescript@5.3.2): + resolution: {integrity: sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -2161,10 +2161,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.13.1(typescript@5.3.2) - '@typescript-eslint/utils': 6.13.1(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.3.2) + '@typescript-eslint/utils': 6.13.2(eslint@8.55.0)(typescript@5.3.2) debug: 4.3.4 - eslint: 8.54.0 + eslint: 8.55.0 ts-api-utils: 1.0.3(typescript@5.3.2) typescript: 5.3.2 transitivePeerDependencies: @@ -2176,8 +2176,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/types@6.13.1: - resolution: {integrity: sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==} + /@typescript-eslint/types@6.13.2: + resolution: {integrity: sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==} engines: {node: ^16.0.0 || >=18.0.0} dev: true @@ -2202,8 +2202,8 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.13.1(typescript@5.3.2): - resolution: {integrity: sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==} + /@typescript-eslint/typescript-estree@6.13.2(typescript@5.3.2): + resolution: {integrity: sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -2211,8 +2211,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.13.1 - '@typescript-eslint/visitor-keys': 6.13.1 + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/visitor-keys': 6.13.2 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -2223,19 +2223,19 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.54.0)(typescript@5.3.2): + /@typescript-eslint/utils@5.62.0(eslint@8.55.0)(typescript@5.3.2): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.2) - eslint: 8.54.0 + eslint: 8.55.0 eslint-scope: 5.1.1 semver: 7.5.4 transitivePeerDependencies: @@ -2243,19 +2243,19 @@ packages: - typescript dev: true - /@typescript-eslint/utils@6.13.1(eslint@8.54.0)(typescript@5.3.2): - resolution: {integrity: sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==} + /@typescript-eslint/utils@6.13.2(eslint@8.55.0)(typescript@5.3.2): + resolution: {integrity: sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.13.1 - '@typescript-eslint/types': 6.13.1 - '@typescript-eslint/typescript-estree': 6.13.1(typescript@5.3.2) - eslint: 8.54.0 + '@typescript-eslint/scope-manager': 6.13.2 + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.3.2) + eslint: 8.55.0 semver: 7.5.4 transitivePeerDependencies: - supports-color @@ -2270,11 +2270,11 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@6.13.1: - resolution: {integrity: sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==} + /@typescript-eslint/visitor-keys@6.13.2: + resolution: {integrity: sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.13.1 + '@typescript-eslint/types': 6.13.2 eslint-visitor-keys: 3.4.3 dev: true @@ -2300,7 +2300,7 @@ packages: peerDependencies: react: ^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/group': 3.3.0(react@18.2.0) '@visx/point': 3.3.0 '@visx/scale': 3.5.0 @@ -2316,7 +2316,7 @@ packages: peerDependencies: react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -2331,7 +2331,7 @@ packages: /@visx/event@3.3.0: resolution: {integrity: sha512-fKalbNgNz2ooVOTXhvcOx5IlEQDgVfX66rI7bgZhBxI2/scy+5rWcXJXpwkheRF68SMx9R93SjKW6tmiD0h+jA==} dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/point': 3.3.0 dev: false @@ -2340,7 +2340,7 @@ packages: peerDependencies: react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/curve': 3.3.0 '@visx/group': 3.3.0(react@18.2.0) '@visx/point': 3.3.0 @@ -2356,7 +2356,7 @@ packages: peerDependencies: react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 classnames: 2.3.2 prop-types: 15.8.1 react: 18.2.0 @@ -2368,7 +2368,7 @@ packages: react: ^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: '@types/d3-hierarchy': 1.1.11 - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/group': 3.3.0(react@18.2.0) classnames: 2.3.2 d3-hierarchy: 1.1.9 @@ -2381,7 +2381,7 @@ packages: peerDependencies: react: ^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/group': 3.3.0(react@18.2.0) '@visx/scale': 3.5.0 classnames: 2.3.2 @@ -2399,7 +2399,7 @@ packages: react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: '@types/lodash': 4.14.202 - '@types/react': 18.2.39 + '@types/react': 18.2.42 lodash: 4.17.21 prop-types: 15.8.1 react: 18.2.0 @@ -2419,7 +2419,7 @@ packages: '@types/d3-path': 1.0.11 '@types/d3-shape': 1.3.12 '@types/lodash': 4.14.202 - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/curve': 3.3.0 '@visx/group': 3.3.0(react@18.2.0) '@visx/scale': 3.5.0 @@ -2437,7 +2437,7 @@ packages: react: ^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: '@types/d3-shape': 1.3.12 - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@visx/group': 3.3.0(react@18.2.0) '@visx/scale': 3.5.0 classnames: 2.3.2 @@ -2452,7 +2452,7 @@ packages: react: ^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: '@types/lodash': 4.14.202 - '@types/react': 18.2.39 + '@types/react': 18.2.42 classnames: 2.3.2 lodash: 4.17.21 prop-types: 15.8.1 @@ -2489,15 +2489,15 @@ packages: peerDependencies: react: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 '@use-gesture/react': 10.3.0(react@18.2.0) '@visx/event': 3.3.0 prop-types: 15.8.1 react: 18.2.0 dev: false - /@vitejs/plugin-react@4.2.0(vite@5.0.4): - resolution: {integrity: sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==} + /@vitejs/plugin-react@4.2.1(vite@5.0.6): + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 @@ -2507,7 +2507,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.5) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.0.4(@types/node@20.10.1) + vite: 5.0.6(@types/node@20.10.3) transitivePeerDependencies: - supports-color dev: true @@ -2650,19 +2650,19 @@ packages: has-symbols: 1.0.3 dev: true - /autoprefixer@10.4.16(postcss@8.4.31): + /autoprefixer@10.4.16(postcss@8.4.32): resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.22.1 - caniuse-lite: 1.0.30001565 + browserslist: 4.22.2 + caniuse-lite: 1.0.30001566 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.31 + postcss: 8.4.32 postcss-value-parser: 4.2.0 dev: true @@ -2694,15 +2694,15 @@ packages: dependencies: fill-range: 7.0.1 - /browserslist@4.22.1: - resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001565 - electron-to-chromium: 1.4.597 - node-releases: 2.0.13 - update-browserslist-db: 1.0.13(browserslist@4.22.1) + caniuse-lite: 1.0.30001566 + electron-to-chromium: 1.4.605 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) dev: true /call-bind@1.0.5: @@ -2722,8 +2722,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - /caniuse-lite@1.0.30001565: - resolution: {integrity: sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==} + /caniuse-lite@1.0.30001566: + resolution: {integrity: sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==} dev: true /chalk@2.4.2: @@ -2776,13 +2776,13 @@ packages: engines: {node: '>=6'} dev: false - /cmdk@0.2.0(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0): + /cmdk@0.2.0(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-JQpKvEOb86SnvMZbYaFKYhvzFntWBeSZdyii0rZPhKJj9uwJBxu4DaVYDrRN7r3mPop56oPhRw+JYWTKs66TYw==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 dependencies: - '@radix-ui/react-dialog': 1.0.0(@types/react@18.2.39)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dialog': 1.0.0(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0) command-score: 0.1.2 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -3022,8 +3022,8 @@ packages: tslib: 2.6.2 dev: false - /electron-to-chromium@1.4.597: - resolution: {integrity: sha512-0XOQNqHhg2YgRVRUrS4M4vWjFCFIP2ETXcXe/0KIQBjXE9Cpy+tgzzYfuq6HGai3hWq0YywtG+5XK8fyG08EjA==} + /electron-to-chromium@1.4.605: + resolution: {integrity: sha512-V52j+P5z6cdRqTjPR/bYNxx7ETCHIkm5VIGuyCy3CMrfSnbEpIlLnk5oHmZo7gYvDfh2TfHeanB6rawyQ23ktg==} dev: true /es-abstract@1.22.3: @@ -3056,7 +3056,7 @@ packages: is-weakref: 1.0.2 object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 + object.assign: 4.1.5 regexp.prototype.flags: 1.5.1 safe-array-concat: 1.0.1 safe-regex-test: 1.0.0 @@ -3159,25 +3159,25 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-prettier@9.0.0(eslint@8.54.0): - resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} + /eslint-config-prettier@9.1.0(eslint@8.55.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.54.0 + eslint: 8.55.0 dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.54.0): + /eslint-plugin-react-hooks@4.6.0(eslint@8.55.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.54.0 + eslint: 8.55.0 dev: true - /eslint-plugin-react@7.33.2(eslint@8.54.0): + /eslint-plugin-react@7.33.2(eslint@8.55.0): resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} engines: {node: '>=4'} peerDependencies: @@ -3188,7 +3188,7 @@ packages: array.prototype.tosorted: 1.1.2 doctrine: 2.1.0 es-iterator-helpers: 1.0.15 - eslint: 8.54.0 + eslint: 8.55.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 @@ -3223,15 +3223,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.54.0: - resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} + /eslint@8.55.0: + resolution: {integrity: sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.3 - '@eslint/js': 8.54.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.55.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -3798,11 +3798,11 @@ packages: jotai: '>=1.11.0' optics-ts: '*' dependencies: - jotai: 2.6.0(@types/react@18.2.39)(react@18.2.0) + jotai: 2.6.0(@types/react@18.2.42)(react@18.2.0) optics-ts: 2.4.1 dev: false - /jotai@2.6.0(@types/react@18.2.39)(react@18.2.0): + /jotai@2.6.0(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-Vt6hsc04Km4j03l+Ax+Sc+FVft5cRJhqgxt6GTz6GM2eM3DyX3CdBdzcG0z2FrlZToL1/0OAkqDghIyARWnSuQ==} engines: {node: '>=12.20.0'} peerDependencies: @@ -3814,7 +3814,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 dev: false @@ -3873,7 +3873,7 @@ packages: dependencies: array-includes: 3.1.7 array.prototype.flat: 1.3.2 - object.assign: 4.1.4 + object.assign: 4.1.5 object.values: 1.1.7 dev: true @@ -3996,8 +3996,8 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true /normalize-path@3.0.0: @@ -4026,8 +4026,8 @@ packages: engines: {node: '>= 0.4'} dev: true - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 @@ -4149,27 +4149,27 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - /postcss-import@15.1.0(postcss@8.4.31): + /postcss-import@15.1.0(postcss@8.4.32): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.31 + postcss: 8.4.32 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - /postcss-js@4.0.1(postcss@8.4.31): + /postcss-js@4.0.1(postcss@8.4.32): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.31 + postcss: 8.4.32 - /postcss-load-config@4.0.2(postcss@8.4.31): + /postcss-load-config@4.0.2(postcss@8.4.32): resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: @@ -4182,16 +4182,16 @@ packages: optional: true dependencies: lilconfig: 3.0.0 - postcss: 8.4.31 + postcss: 8.4.32 yaml: 2.3.4 - /postcss-nested@6.0.1(postcss@8.4.31): + /postcss-nested@6.0.1(postcss@8.4.32): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.31 + postcss: 8.4.32 postcss-selector-parser: 6.0.13 /postcss-selector-parser@6.0.13: @@ -4204,8 +4204,8 @@ packages: /postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + /postcss@8.4.32: + resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -4217,14 +4217,13 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /prettier-plugin-tailwindcss@0.5.7(@trivago/prettier-plugin-sort-imports@4.3.0)(prettier@3.1.0): - resolution: {integrity: sha512-4v6uESAgwCni6YF6DwJlRaDjg9Z+al5zM4JfngcazMy4WEf/XkPS5TEQjbD+DZ5iNuG6RrKQLa/HuX2SYzC3kQ==} + /prettier-plugin-tailwindcss@0.5.9(@trivago/prettier-plugin-sort-imports@4.3.0)(prettier@3.1.0): + resolution: {integrity: sha512-9x3t1s2Cjbut2QiP+O0mDqV3gLXTe2CgRlQDgucopVkUdw26sQi53p/q4qvGxMLBDfk/dcTV57Aa/zYwz9l8Ew==} engines: {node: '>=14.21.3'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' '@prettier/plugin-pug': '*' '@shopify/prettier-plugin-liquid': '*' - '@shufo/prettier-plugin-blade': '*' '@trivago/prettier-plugin-sort-imports': '*' prettier: ^3.0 prettier-plugin-astro: '*' @@ -4244,8 +4243,6 @@ packages: optional: true '@shopify/prettier-plugin-liquid': optional: true - '@shufo/prettier-plugin-blade': - optional: true '@trivago/prettier-plugin-sort-imports': optional: true prettier-plugin-astro: @@ -4325,7 +4322,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-remove-scroll-bar@2.3.4(@types/react@18.2.39)(react@18.2.0): + /react-remove-scroll-bar@2.3.4(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} peerDependencies: @@ -4335,13 +4332,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 - react-style-singleton: 2.2.1(@types/react@18.2.39)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.42)(react@18.2.0) tslib: 2.6.2 dev: false - /react-remove-scroll@2.5.4(@types/react@18.2.39)(react@18.2.0): + /react-remove-scroll@2.5.4(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==} engines: {node: '>=10'} peerDependencies: @@ -4351,16 +4348,16 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 - react-remove-scroll-bar: 2.3.4(@types/react@18.2.39)(react@18.2.0) - react-style-singleton: 2.2.1(@types/react@18.2.39)(react@18.2.0) + react-remove-scroll-bar: 2.3.4(@types/react@18.2.42)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.42)(react@18.2.0) tslib: 2.6.2 - use-callback-ref: 1.3.0(@types/react@18.2.39)(react@18.2.0) - use-sidecar: 1.1.2(@types/react@18.2.39)(react@18.2.0) + use-callback-ref: 1.3.0(@types/react@18.2.42)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.42)(react@18.2.0) dev: false - /react-remove-scroll@2.5.5(@types/react@18.2.39)(react@18.2.0): + /react-remove-scroll@2.5.5(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} engines: {node: '>=10'} peerDependencies: @@ -4370,39 +4367,39 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 - react-remove-scroll-bar: 2.3.4(@types/react@18.2.39)(react@18.2.0) - react-style-singleton: 2.2.1(@types/react@18.2.39)(react@18.2.0) + react-remove-scroll-bar: 2.3.4(@types/react@18.2.42)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.42)(react@18.2.0) tslib: 2.6.2 - use-callback-ref: 1.3.0(@types/react@18.2.39)(react@18.2.0) - use-sidecar: 1.1.2(@types/react@18.2.39)(react@18.2.0) + use-callback-ref: 1.3.0(@types/react@18.2.42)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.42)(react@18.2.0) dev: false - /react-router-dom@6.20.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ==} + /react-router-dom@6.20.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.13.0 + '@remix-run/router': 1.13.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.20.0(react@18.2.0) + react-router: 6.20.1(react@18.2.0) dev: false - /react-router@6.20.0(react@18.2.0): - resolution: {integrity: sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w==} + /react-router@6.20.1(react@18.2.0): + resolution: {integrity: sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.13.0 + '@remix-run/router': 1.13.1 react: 18.2.0 dev: false - /react-style-singleton@2.2.1(@types/react@18.2.39)(react@18.2.0): + /react-style-singleton@2.2.1(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} peerDependencies: @@ -4412,7 +4409,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 @@ -4726,22 +4723,22 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /tailwind-merge@2.0.0: - resolution: {integrity: sha512-WO8qghn9yhsldLSg80au+3/gY9E4hFxIvQ3qOmlpXnqpDKoMruKfi/56BbbMg6fHTQJ9QD3cc79PoWqlaQE4rw==} + /tailwind-merge@2.1.0: + resolution: {integrity: sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ==} dependencies: '@babel/runtime': 7.23.5 dev: false - /tailwindcss-animate@1.0.7(tailwindcss@3.3.5): + /tailwindcss-animate@1.0.7(tailwindcss@3.3.6): resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} peerDependencies: tailwindcss: '>=3.0.0 || insiders' dependencies: - tailwindcss: 3.3.5 + tailwindcss: 3.3.6 dev: false - /tailwindcss@3.3.5: - resolution: {integrity: sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==} + /tailwindcss@3.3.6: + resolution: {integrity: sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -4759,11 +4756,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.31 - postcss-import: 15.1.0(postcss@8.4.31) - postcss-js: 4.0.1(postcss@8.4.31) - postcss-load-config: 4.0.2(postcss@8.4.31) - postcss-nested: 6.0.1(postcss@8.4.31) + postcss: 8.4.32 + postcss-import: 15.1.0(postcss@8.4.32) + postcss-js: 4.0.1(postcss@8.4.32) + postcss-load-config: 4.0.2(postcss@8.4.32) + postcss-nested: 6.0.1(postcss@8.4.32) postcss-selector-parser: 6.0.13 resolve: 1.22.8 sucrase: 3.34.0 @@ -4909,13 +4906,13 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /update-browserslist-db@1.0.13(browserslist@4.22.1): + /update-browserslist-db@1.0.13(browserslist@4.22.2): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.22.1 + browserslist: 4.22.2 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -4926,7 +4923,7 @@ packages: punycode: 2.3.1 dev: true - /use-callback-ref@1.3.0(@types/react@18.2.39)(react@18.2.0): + /use-callback-ref@1.3.0(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} engines: {node: '>=10'} peerDependencies: @@ -4936,12 +4933,12 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 react: 18.2.0 tslib: 2.6.2 dev: false - /use-sidecar@1.1.2(@types/react@18.2.39)(react@18.2.0): + /use-sidecar@1.1.2(@types/react@18.2.42)(react@18.2.0): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} peerDependencies: @@ -4951,7 +4948,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.39 + '@types/react': 18.2.42 detect-node-es: 1.1.0 react: 18.2.0 tslib: 2.6.2 @@ -4965,8 +4962,8 @@ packages: hasBin: true dev: false - /vite@5.0.4(@types/node@20.10.1): - resolution: {integrity: sha512-RzAr8LSvM8lmhB4tQ5OPcBhpjOZRZjuxv9zO5UcxeoY2bd3kP3Ticd40Qma9/BqZ8JS96Ll/jeBX9u+LJZrhVg==} + /vite@5.0.6(@types/node@20.10.3): + resolution: {integrity: sha512-MD3joyAEBtV7QZPl2JVVUai6zHms3YOmLR+BpMzLlX2Yzjfcc4gTgNi09d/Rua3F4EtC8zdwPU8eQYyib4vVMQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4993,9 +4990,9 @@ packages: terser: optional: true dependencies: - '@types/node': 20.10.1 + '@types/node': 20.10.3 esbuild: 0.19.8 - postcss: 8.4.31 + postcss: 8.4.32 rollup: 4.6.1 optionalDependencies: fsevents: 2.3.3 diff --git a/ui/rsl/src/api/protocol/motis/ris.ts b/ui/rsl/src/api/protocol/motis/ris.ts index b1b34ed9b6..2f41661719 100644 --- a/ui/rsl/src/api/protocol/motis/ris.ts +++ b/ui/rsl/src/api/protocol/motis/ris.ts @@ -31,4 +31,7 @@ export interface RISStatusResponse { upload_status: RISSourceStatus; read_status: RISSourceStatus; init_status: RISSourceStatus; + delayed_init: boolean; + init_forward_started: boolean; + init_forward_done: boolean; } diff --git a/ui/rsl/src/components/groups/GroupDetails.tsx b/ui/rsl/src/components/groups/GroupDetails.tsx index 992cabad36..6dd9480668 100644 --- a/ui/rsl/src/components/groups/GroupDetails.tsx +++ b/ui/rsl/src/components/groups/GroupDetails.tsx @@ -1,55 +1,30 @@ -import { - ArrowPathIcon, - ArrowUturnUpIcon, - CheckCircleIcon, - ClockIcon, - CpuChipIcon, - ExclamationTriangleIcon, - TicketIcon, - UsersIcon, - WrenchIcon, - XCircleIcon, -} from "@heroicons/react/24/outline"; +import { UsersIcon } from "@heroicons/react/24/outline"; import { useAtom, useSetAtom } from "jotai"; -import { ExternalLink } from "lucide-react"; import React, { ReactNode, useEffect } from "react"; import { useParams } from "react-router-dom"; -import { - PaxMonAtStation, - PaxMonCompactJourney, - PaxMonCompactJourneyLeg, - PaxMonGroup, - PaxMonGroupRoute, - PaxMonInTrip, - PaxMonRerouteLogEntry, - PaxMonRerouteLogRoute, - PaxMonRerouteReason, - PaxMonTransferInfo, -} from "@/api/protocol/motis/paxmon"; - import { usePaxMonGetGroupsRequest } from "@/api/paxmon"; -import { formatShortDuration } from "@/data/durationFormat"; import { universeAtom } from "@/data/multiverse"; -import { formatPercent } from "@/data/numberFormat"; import { mostRecentlySelectedGroupAtom } from "@/data/selectedGroup"; -import { getBahnSucheUrl } from "@/util/bahnDe"; -import { formatDateTime, formatTime } from "@/util/dateFormat"; +import { formatDateTime } from "@/util/dateFormat"; -import TripServiceInfoView from "@/components/TripServiceInfoView"; import GroupRouteTree from "@/components/groups/GroupRouteTree"; -import { Button } from "@/components/ui/button"; -import Delay from "@/components/util/Delay"; - -import { cn } from "@/lib/utils"; +import { GroupRoutes } from "@/components/groups/GroupRoutes.tsx"; +import { RerouteLog } from "@/components/groups/RerouteLog.tsx"; +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@/components/ui/tabs.tsx"; interface GroupDetailsProps { groupId: number; } -function GroupDetails({ groupId }: GroupDetailsProps): JSX.Element { +function GroupDetails({ groupId }: GroupDetailsProps): ReactNode { const [universe] = useAtom(universeAtom); const { data, isPending, error } = usePaxMonGetGroupsRequest({ universe, @@ -87,8 +62,6 @@ function GroupDetails({ groupId }: GroupDetailsProps): JSX.Element { return
Gruppe {groupId} ist ungültig (keine Routen).
; } - const plannedJourney = group.routes[0].journey; - return (
@@ -112,481 +85,34 @@ function GroupDetails({ groupId }: GroupDetailsProps): JSX.Element { Planmäßige Ankunftszeit:{" "} {formatDateTime(group.routes[0].planned_arrival_time)}
- -
-
-
- {group.routes.length === 1 - ? "1 Route" - : `${group.routes.length} Routen`} -
-
- {group.routes.map((route) => ( - - ))} -
-
-
-
Änderungsprotokoll
-
-
- {group.reroute_log.map((log, idx) => ( - - ))} -
- -
-
-
- {group.routes.length <= 10 && group.reroute_log.length <= 10 ? ( - - ) : ( -
Der Verbindungsbaum ist zu groß, um angezeigt zu werden.
- )} -
-
- ); -} - -interface GroupRouteProps { - route: PaxMonGroupRoute; -} - -function GroupRoute({ route }: GroupRouteProps): JSX.Element { - return ( -
-
-
- #{route.index} - {route.planned && ( - - )} -
-
- {formatPercent(route.probability)} -
-
- - -
-
-
0 - ? "bg-green-50" - : "bg-amber-50", - )} - > - - - - - - - - - - - - {route.journey.legs.map((leg, idx) => ( - - ))} - - -
AbschnittZug - Umstieg - - Planmäßige Abfahrt - - Planmäßige Ankunft -
-
-
- ); -} - -interface JourneyLegProps { - leg: PaxMonCompactJourneyLeg; - index: number; -} - -function JourneyLeg({ leg, index }: JourneyLegProps): JSX.Element { - return ( - - {index + 1}. - - - - - {requiresTransfer(leg.enter_transfer) - ? formatShortDuration(leg.enter_transfer.duration) - : "—"} - - {formatDateTime(leg.enter_time)} - - {leg.enter_station.name} - - {formatDateTime(leg.exit_time)} - - {leg.exit_station.name} - - - ); -} - -interface FinalFootpathProps { - journey: PaxMonCompactJourney; -} - -function FinalFootpath({ journey }: FinalFootpathProps) { - if (journey.final_footpath.length === 1 && journey.legs.length > 0) { - const fp = journey.final_footpath[0]; - const lastLeg = journey.legs[journey.legs.length - 1]; - return ( - - {journey.legs.length + 1}. - Fußweg - {formatShortDuration(fp.duration)} - {formatDateTime(lastLeg.exit_time)} - - {fp.from_station.name} - - - {formatDateTime(lastLeg.exit_time + 60 * fp.duration)} - - - {fp.to_station.name} - - - ); - } else { - return null; - } -} - -function requiresTransfer(ti: PaxMonTransferInfo) { - return ti.type === "SAME_STATION" || ti.type === "FOOTPATH"; -} - -function transferTypeText(ti: PaxMonTransferInfo) { - switch (ti.type) { - case "NONE": - return "Kein Umstieg"; - case "SAME_STATION": - return "Umstieg an einer Station"; - case "FOOTPATH": - return "Umstieg mit Fußweg zwischen zwei Stationen"; - case "MERGE": - return "Vereinigung"; - case "THROUGH": - return "Durchbindung"; - } -} - -function rerouteReasonText(reason: PaxMonRerouteReason): string { - switch (reason) { - case "Manual": - return "Manuelle Umleitung"; - case "BrokenTransfer": - return "Gebrochener Umstieg"; - case "MajorDelayExpected": - return "Hohe erwartete Zielverspätung"; - case "RevertForecast": - return "Rücknahme einer Vorhersage"; - case "Simulation": - return "Simulation"; - case "UpdateForecast": - return "Neuberechnung der Vorhersage"; - case "DestinationUnreachable": - return "Ziel nicht mehr erreichbar"; - case "DestinationReachable": - return "Ziel wieder erreichbar"; - } -} - -interface RerouteLogEntryProps { - log: PaxMonRerouteLogEntry; - logIndex: number; - group: PaxMonGroup; -} - -function RerouteLogEntry({ log, logIndex }: RerouteLogEntryProps): ReactNode { - const broken_transfer = - log.broken_transfer.length === 1 ? log.broken_transfer[0] : undefined; - const show_reroutes = log.new_routes.length > 0; - const { icon, bgColor } = getRerouteReasonIcon(log.reason); - - return ( -
-
- {icon} -
-
-
- - V{logIndex + 1}: {rerouteReasonText(log.reason)} - - Update {log.update_number} - - {formatDateTime(log.system_time)} - -
- - {show_reroutes ? ( - <> -
- Umleitung von Route #{log.old_route.index} ( - {formatPercent(log.old_route.previous_probability)} →{" "} - {formatPercent(log.old_route.new_probability)}) auf: -
-
- {log.new_routes.map((route) => ( -
- Route #{route.index}:{" "} - {formatPercent(route.previous_probability)} →{" "} - {formatPercent(route.new_probability)} -
- ))} -
- - ) : ( -
- Route #{log.old_route.index} ( - {formatPercent(log.old_route.previous_probability)}) -
- )} - {broken_transfer && ( -
-
- - Gebrochener Umstieg: Fahrtabschnitt{" "} - {broken_transfer.leg_index + 1} - - - ( - {broken_transfer.direction === "Enter" - ? "Einstieg" - : "Ausstieg"} - ) - - - Benötigte Umstiegszeit:{" "} - {formatShortDuration(broken_transfer.required_transfer_time)} - -
-
- Ankunft:{" "} - {broken_transfer.current_arrival_time !== 0 - ? formatDateTime(broken_transfer.current_arrival_time) - : "—"} - {broken_transfer.arrival_canceled && " (ausgefallen)"} -
-
- {" "} - Abfahrt:{" "} - {broken_transfer.current_departure_time !== 0 - ? formatDateTime(broken_transfer.current_departure_time) - : "—"} - {broken_transfer.departure_canceled && " (ausgefallen)"} -
- )} -
+ +
); } -interface RerouteLogEntryLocalizationProps { - logRoute: PaxMonRerouteLogRoute; -} - -function RerouteLogEntryLocalization({ - logRoute, -}: RerouteLogEntryLocalizationProps): ReactNode { - switch (logRoute.localization_type) { - case "PaxMonAtStation": { - const loc = logRoute.localization as PaxMonAtStation; - return ( -
- Reisende an Station {loc.station.name} um{" "} - {formatTime(loc.current_arrival_time)} - {loc.first_station ? " (Reisebeginn)" : ""} -
- ); - } - case "PaxMonInTrip": { - const loc = logRoute.localization as PaxMonInTrip; - return ( -
- Reisende in Zug {loc.trip.train_nr}, nächster Halt:{" "} - {loc.next_station.name} um {formatTime(loc.current_arrival_time)} -
- ); - } - } -} - -interface RerouteReasonIcon { - icon: JSX.Element; - bgColor: string; -} - -function getRerouteReasonIcon(reason: PaxMonRerouteReason): RerouteReasonIcon { - const style = "w-6 h-6"; - switch (reason) { - case "Manual": - return { - icon: , - bgColor: "bg-blue-500", - }; - case "BrokenTransfer": - return { - icon: , - bgColor: "bg-red-500", - }; - case "MajorDelayExpected": - return { - icon: , - bgColor: "bg-amber-500", - }; - case "RevertForecast": - return { - icon: , - bgColor: "bg-teal-500", - }; - case "Simulation": - return { - icon: , - bgColor: "bg-cyan-500", - }; - case "UpdateForecast": - return { - icon: , - bgColor: "bg-violet-500", - }; - case "DestinationUnreachable": - return { - icon: , - bgColor: "bg-fuchsia-500", - }; - case "DestinationReachable": - return { - icon: , - bgColor: "bg-lime-500", - }; - } -} - -interface RerouteLogTableProps { - group: PaxMonGroup; -} - -function RerouteLogTable({ group }: RerouteLogTableProps) { - const probs: number[][] = [group.routes.map((r) => (r.index === 0 ? 1 : 0))]; - const diffs: number[][] = [group.routes.map(() => 0)]; - - for (const le of group.reroute_log) { - const new_probs = [...probs[probs.length - 1]]; - const diff = group.routes.map(() => 0); - - new_probs[le.old_route.index] = le.old_route.new_probability; - diff[le.old_route.index] = - le.old_route.new_probability - le.old_route.previous_probability; - for (const nr of le.new_routes) { - new_probs[nr.index] = nr.new_probability; - diff[nr.index] = nr.new_probability - nr.previous_probability; - } - - probs.push(new_probs); - diffs.push(diff); - } - - return ( - - - - - {group.routes.map((r) => ( - - ))} - - - - - {probs.map((row, rowIdx) => ( - - - {row.map((p, colIdx) => ( - - ))} - - - ))} - -
V - R #{r.index} - Summe
V{rowIdx} 0 - ? "text-green-600" - : diffs[rowIdx][colIdx] < 0 - ? "text-yellow-500" - : "text-black", - )} - title={`Exakter Wert: ${p}, Änderung: ${formatPercent( - diffs[rowIdx][colIdx], - )} (${diffs[rowIdx][colIdx]})`} - > - {formatPercent(p)} - - {formatPercent(row.reduce((acc, p) => acc + p, 0))} -
- ); -} - export function GroupDetailsFromRoute() { const params = useParams(); const groupId = Number.parseInt(params.groupId ?? ""); diff --git a/ui/rsl/src/components/groups/GroupRouteTree.tsx b/ui/rsl/src/components/groups/GroupRouteTree.tsx index 3cfc7acbbb..3a1f37a54c 100644 --- a/ui/rsl/src/components/groups/GroupRouteTree.tsx +++ b/ui/rsl/src/components/groups/GroupRouteTree.tsx @@ -62,6 +62,8 @@ const NodeColors = { DestinationReachable: "#bef264", // lime-300 }; +const DEBUG = false; + function setNodeColor(node: TreeNode, reason: PaxMonRerouteReason) { switch (reason) { case "Manual": @@ -130,6 +132,11 @@ export function buildRouteTree(group: PaxMonGroup): TreeNode { PaxMonLocalizationWrapper >(); + if (DEBUG) { + console.log("processReverts: %d reverts: %o", reverts.length, reverts); + console.log("reactivated routes: %o", reactivatedRoutes); + } + for (const lev of reverts) { reactivatedRouteLogEntry.set(lev.le.old_route.index, lev); localizations.set(lev.le.old_route.index, lev.le.old_route); @@ -141,8 +148,19 @@ export function buildRouteTree(group: PaxMonGroup): TreeNode { } } + if (DEBUG) { + console.log("reverted routes: %o", revertedRoutes); + } + for (const revertedRoute of revertedRoutes) { const leafLocalization = localizations.get(revertedRoute); + if (DEBUG) { + console.log( + "reverted route %d: leaf localization: %o", + revertedRoute, + leafLocalization, + ); + } if (!leafLocalization) { throw new Error( `leaf localization not found for route ${revertedRoute}`, @@ -150,7 +168,13 @@ export function buildRouteTree(group: PaxMonGroup): TreeNode { } const oldLeaves = leaves[revertedRoute]; leaves[revertedRoute] = []; + if (DEBUG) { + console.log("old leaves: %o", oldLeaves); + } for (const oldLeaf of oldLeaves) { + if (DEBUG) { + console.log("old leaf: %o", oldLeaf); + } let candidate: TreeNode | null = null; for ( let node = parents.get(oldLeaf); @@ -167,12 +191,28 @@ export function buildRouteTree(group: PaxMonGroup): TreeNode { if ( canSwitchLocalization(leafLocalization, candidateLocalization) ) { + if (DEBUG) { + console.log( + "candidate: %o, localization: %o", + node, + candidateLocalization, + ); + } candidate = node; + } else if (DEBUG) { + console.log( + "ignoring candidate because of localization: %o, localization: %o", + node, + candidateLocalization, + ); } } } if (candidate) { const lev = reactivatedRouteLogEntry.get(candidate.route); + if (DEBUG) { + console.log("candidate found: %o, lev: %o", candidate, lev); + } if (!lev) { throw new Error("no reactivated route log entry found"); } @@ -189,6 +229,9 @@ export function buildRouteTree(group: PaxMonGroup): TreeNode { leaves[newNode.route].push(newNode); parents.set(newNode, oldLeaf); } else { + if (DEBUG) { + console.log("no candidate found, keeping old leaf: %o", oldLeaf); + } leaves[revertedRoute].push(oldLeaf); } } @@ -198,6 +241,9 @@ export function buildRouteTree(group: PaxMonGroup): TreeNode { }; for (const [version, le] of group.reroute_log.entries()) { + if (DEBUG) { + console.log("log entry version %i (%s): %o", version + 1, le.reason, le); + } if (le.reason === "RevertForecast") { if ( reverts.length > 0 && diff --git a/ui/rsl/src/components/groups/GroupRoutes.tsx b/ui/rsl/src/components/groups/GroupRoutes.tsx new file mode 100644 index 0000000000..f2eed00955 --- /dev/null +++ b/ui/rsl/src/components/groups/GroupRoutes.tsx @@ -0,0 +1,236 @@ +import { ClockIcon, TicketIcon } from "@heroicons/react/24/outline"; +import { AlertTriangle, ExternalLink } from "lucide-react"; +import React, { ReactElement } from "react"; + +import { + PaxMonCompactJourney, + PaxMonCompactJourneyLeg, + PaxMonGroup, + PaxMonGroupRoute, + PaxMonTransferInfo, +} from "@/api/protocol/motis/paxmon.ts"; + +import { formatShortDuration } from "@/data/durationFormat.ts"; +import { formatPercent } from "@/data/numberFormat.ts"; + +import { getBahnSucheUrl } from "@/util/bahnDe.ts"; +import { formatDateTime } from "@/util/dateFormat.ts"; + +import TripServiceInfoView from "@/components/TripServiceInfoView.tsx"; +import { Button } from "@/components/ui/button.tsx"; +import Delay from "@/components/util/Delay.tsx"; + +import { cn } from "@/lib/utils.ts"; + +interface GroupRoutesProps { + group: PaxMonGroup; +} + +export function GroupRoutes({ group }: GroupRoutesProps) { + const plannedJourney = group.routes[0].journey; + + return ( +
+
+
+ {group.routes.length === 1 + ? "1 Route" + : `${group.routes.length} Routen`} +
+ +
+
+ {group.routes.map((route) => ( + + ))} +
+
+ ); +} + +const MATCH_INEXACT_TIME = 1; +const MATCH_JOURNEY_SUBSET = 2; +const MATCH_REROUTED = 4; + +interface GroupRouteProps { + route: PaxMonGroupRoute; +} + +function GroupRoute({ route }: GroupRouteProps): ReactElement { + const showWarning = route.planned && route.source_flags != 0; + const warnings: string[] = []; + if ((route.source_flags & MATCH_INEXACT_TIME) == MATCH_INEXACT_TIME) { + warnings.push( + "Zeitstempel der Original-Reisekette weichen vom Fahrplan ab und wurden an den geladenen Fahrplan angepasst.", + ); + } + if ((route.source_flags & MATCH_JOURNEY_SUBSET) == MATCH_JOURNEY_SUBSET) { + warnings.push( + "Teil-Reisekette, da die komplette Original-Reisekette nicht dem Fahrplan zugeordnet werden konnte.", + ); + } + if ((route.source_flags & MATCH_REROUTED) == MATCH_REROUTED) { + warnings.push( + "Reisekette wurde neu berechnet, da die Original-Reisekette nicht dem Fahrplan zugeordnet werden konnte.", + ); + } + + return ( +
+
+
+ #{route.index} + {route.planned && ( + + )} + {showWarning && ( +
+ +
+ )} +
+
+ {formatPercent(route.probability)} +
+
+ + +
+
+
0 + ? "bg-green-50" + : "bg-amber-50", + )} + > + + + + + + + + + + + + {route.journey.legs.map((leg, idx) => ( + + ))} + + +
AbschnittZug + Umstieg + + Planmäßige Abfahrt + + Planmäßige Ankunft +
+
+
+ ); +} + +interface JourneyLegProps { + leg: PaxMonCompactJourneyLeg; + index: number; +} + +function JourneyLeg({ leg, index }: JourneyLegProps): JSX.Element { + return ( + + {index + 1}. + + + + + {requiresTransfer(leg.enter_transfer) + ? formatShortDuration(leg.enter_transfer.duration) + : "—"} + + {formatDateTime(leg.enter_time)} + + {leg.enter_station.name} + + {formatDateTime(leg.exit_time)} + + {leg.exit_station.name} + + + ); +} + +interface FinalFootpathProps { + journey: PaxMonCompactJourney; +} + +function FinalFootpath({ journey }: FinalFootpathProps) { + if (journey.final_footpath.length === 1 && journey.legs.length > 0) { + const fp = journey.final_footpath[0]; + const lastLeg = journey.legs[journey.legs.length - 1]; + return ( + + {journey.legs.length + 1}. + Fußweg + {formatShortDuration(fp.duration)} + {formatDateTime(lastLeg.exit_time)} + + {fp.from_station.name} + + + {formatDateTime(lastLeg.exit_time + 60 * fp.duration)} + + + {fp.to_station.name} + + + ); + } else { + return null; + } +} + +function requiresTransfer(ti: PaxMonTransferInfo) { + return ti.type === "SAME_STATION" || ti.type === "FOOTPATH"; +} + +function transferTypeText(ti: PaxMonTransferInfo) { + switch (ti.type) { + case "NONE": + return "Kein Umstieg"; + case "SAME_STATION": + return "Umstieg an einer Station"; + case "FOOTPATH": + return "Umstieg mit Fußweg zwischen zwei Stationen"; + case "MERGE": + return "Vereinigung"; + case "THROUGH": + return "Durchbindung"; + } +} diff --git a/ui/rsl/src/components/groups/RerouteLog.tsx b/ui/rsl/src/components/groups/RerouteLog.tsx new file mode 100644 index 0000000000..42138ab8c7 --- /dev/null +++ b/ui/rsl/src/components/groups/RerouteLog.tsx @@ -0,0 +1,324 @@ +import { + ArrowPathIcon, + ArrowUturnUpIcon, + CheckCircleIcon, + ClockIcon, + CpuChipIcon, + ExclamationTriangleIcon, + WrenchIcon, + XCircleIcon, +} from "@heroicons/react/24/outline"; +import React, { ReactElement, ReactNode } from "react"; + +import { + PaxMonAtStation, + PaxMonGroup, + PaxMonInTrip, + PaxMonRerouteLogEntry, + PaxMonRerouteLogRoute, + PaxMonRerouteReason, +} from "@/api/protocol/motis/paxmon.ts"; + +import { formatShortDuration } from "@/data/durationFormat.ts"; +import { formatPercent } from "@/data/numberFormat.ts"; + +import { formatDateTime, formatTime } from "@/util/dateFormat.ts"; + +import { cn } from "@/lib/utils.ts"; + +function rerouteReasonText(reason: PaxMonRerouteReason): string { + switch (reason) { + case "Manual": + return "Manuelle Umleitung"; + case "BrokenTransfer": + return "Gebrochener Umstieg"; + case "MajorDelayExpected": + return "Hohe erwartete Zielverspätung"; + case "RevertForecast": + return "Rücknahme einer Vorhersage"; + case "Simulation": + return "Simulation"; + case "UpdateForecast": + return "Neuberechnung der Vorhersage"; + case "DestinationUnreachable": + return "Ziel nicht mehr erreichbar"; + case "DestinationReachable": + return "Ziel wieder erreichbar"; + } +} + +interface RerouteLogEntryProps { + log: PaxMonRerouteLogEntry; + logIndex: number; + group: PaxMonGroup; +} + +export function RerouteLogEntry({ + log, + logIndex, +}: RerouteLogEntryProps): ReactNode { + const broken_transfer = + log.broken_transfer.length === 1 ? log.broken_transfer[0] : undefined; + const show_reroutes = log.new_routes.length > 0; + const { icon, bgColor } = getRerouteReasonIcon(log.reason); + + return ( +
+
+ {icon} +
+
+
+ + V{logIndex + 1}: {rerouteReasonText(log.reason)} + + Update {log.update_number} + + {formatDateTime(log.system_time)} + +
+ + {show_reroutes ? ( + <> +
+ Umleitung von Route #{log.old_route.index} ( + {formatPercent(log.old_route.previous_probability)} →{" "} + {formatPercent(log.old_route.new_probability)}) auf: +
+
+ {log.new_routes.map((route) => ( +
+ Route #{route.index}:{" "} + {formatPercent(route.previous_probability)} →{" "} + {formatPercent(route.new_probability)} +
+ ))} +
+ + ) : ( +
+ Route #{log.old_route.index} ( + {formatPercent(log.old_route.previous_probability)}) +
+ )} + {broken_transfer && ( +
+
+ + Gebrochener Umstieg: Fahrtabschnitt{" "} + {broken_transfer.leg_index + 1} + + + ( + {broken_transfer.direction === "Enter" + ? "Einstieg" + : "Ausstieg"} + ) + + + Benötigte Umstiegszeit:{" "} + {formatShortDuration(broken_transfer.required_transfer_time)} + +
+
+ Ankunft:{" "} + {broken_transfer.current_arrival_time !== 0 + ? formatDateTime(broken_transfer.current_arrival_time) + : "—"} + {broken_transfer.arrival_canceled && " (ausgefallen)"} +
+
+ {" "} + Abfahrt:{" "} + {broken_transfer.current_departure_time !== 0 + ? formatDateTime(broken_transfer.current_departure_time) + : "—"} + {broken_transfer.departure_canceled && " (ausgefallen)"} +
+
+ )} +
+
+ ); +} + +interface RerouteLogEntryLocalizationProps { + logRoute: PaxMonRerouteLogRoute; +} + +function RerouteLogEntryLocalization({ + logRoute, +}: RerouteLogEntryLocalizationProps): ReactNode { + switch (logRoute.localization_type) { + case "PaxMonAtStation": { + const loc = logRoute.localization as PaxMonAtStation; + return ( +
+ Reisende an Station {loc.station.name} um{" "} + {formatTime(loc.current_arrival_time)} + {loc.first_station ? " (Reisebeginn)" : ""} +
+ ); + } + case "PaxMonInTrip": { + const loc = logRoute.localization as PaxMonInTrip; + return ( +
+ Reisende in Zug {loc.trip.train_nr}, nächster Halt:{" "} + {loc.next_station.name} um {formatTime(loc.current_arrival_time)} +
+ ); + } + } +} + +interface RerouteReasonIcon { + icon: ReactElement; + bgColor: string; +} + +function getRerouteReasonIcon(reason: PaxMonRerouteReason): RerouteReasonIcon { + const style = "w-6 h-6"; + switch (reason) { + case "Manual": + return { + icon: , + bgColor: "bg-blue-500", + }; + case "BrokenTransfer": + return { + icon: , + bgColor: "bg-red-500", + }; + case "MajorDelayExpected": + return { + icon: , + bgColor: "bg-amber-500", + }; + case "RevertForecast": + return { + icon: , + bgColor: "bg-teal-500", + }; + case "Simulation": + return { + icon: , + bgColor: "bg-cyan-500", + }; + case "UpdateForecast": + return { + icon: , + bgColor: "bg-violet-500", + }; + case "DestinationUnreachable": + return { + icon: , + bgColor: "bg-fuchsia-500", + }; + case "DestinationReachable": + return { + icon: , + bgColor: "bg-lime-500", + }; + } +} + +interface RerouteLogTableProps { + group: PaxMonGroup; +} + +export function RerouteLogTable({ group }: RerouteLogTableProps) { + const probs: number[][] = [group.routes.map((r) => (r.index === 0 ? 1 : 0))]; + const diffs: number[][] = [group.routes.map(() => 0)]; + + for (const le of group.reroute_log) { + const new_probs = [...probs[probs.length - 1]]; + const diff = group.routes.map(() => 0); + + new_probs[le.old_route.index] = le.old_route.new_probability; + diff[le.old_route.index] = + le.old_route.new_probability - le.old_route.previous_probability; + for (const nr of le.new_routes) { + new_probs[nr.index] = nr.new_probability; + diff[nr.index] = nr.new_probability - nr.previous_probability; + } + + probs.push(new_probs); + diffs.push(diff); + } + + return ( + + + + + {group.routes.map((r) => ( + + ))} + + + + + {probs.map((row, rowIdx) => ( + + + {row.map((p, colIdx) => ( + + ))} + + + ))} + +
V + R #{r.index} + Summe
V{rowIdx} 0 + ? "text-green-600" + : diffs[rowIdx][colIdx] < 0 + ? "text-yellow-500" + : "text-black", + )} + title={`Exakter Wert: ${p}, Änderung: ${formatPercent( + diffs[rowIdx][colIdx], + )} (${diffs[rowIdx][colIdx]})`} + > + {formatPercent(p)} + + {formatPercent(row.reduce((acc, p) => acc + p, 0))} +
+ ); +} + +export interface RerouteLogProps { + group: PaxMonGroup; +} + +export function RerouteLog({ group }: RerouteLogProps) { + return ( +
+
Änderungsprotokoll
+
+
+ {group.reroute_log.map((log, idx) => ( + + ))} +
+
+ Routenwahrscheinlichkeiten im Zeitverlauf +
+ +
+ ); +} diff --git a/ui/rsl/src/components/header/TimeControl.tsx b/ui/rsl/src/components/header/TimeControl.tsx index 7f88bc445b..19856cc73d 100644 --- a/ui/rsl/src/components/header/TimeControl.tsx +++ b/ui/rsl/src/components/header/TimeControl.tsx @@ -74,8 +74,8 @@ function TimeControl({ allowForwarding }: TimeControlProps): JSX.Element { ); const { data: status, - isPending, error, + isError, } = useQuery({ queryKey: queryKeys.status(universe), queryFn: () => sendPaxMonStatusRequest({ universe }), @@ -142,7 +142,9 @@ function TimeControl({ allowForwarding }: TimeControlProps): JSX.Element { return (
- {status ? ( + {isError ? ( + + ) : status ? ( <> @@ -152,6 +154,14 @@ function TimeControl({ allowForwarding }: TimeControlProps): JSX.Element {
{formatTime(status.system_time)}
+ {isError && ( +
+ + + Keine Verbindung zu MOTIS + +
+ )}
@@ -160,20 +170,28 @@ function TimeControl({ allowForwarding }: TimeControlProps): JSX.Element { {buttons} - ) : isPending ? ( -
Verbindung zu MOTIS wird aufgebaut...
) : ( -
- Fehler:{" "} - {error instanceof Error - ? error.message - : `Verbindung zu MOTIS fehlgeschlagen.`} -
+
Verbindung zu MOTIS wird aufgebaut...
)} ); } +interface ConnectionErrorProps { + error: Error; +} + +function ConnectionError({ error }: ConnectionErrorProps) { + return ( +
+ + + Keine Verbindung zu MOTIS + +
+ ); +} + interface StatusProps { status: PaxMonStatusResponse; } diff --git a/ui/rsl/src/components/status/DatasetStatus.tsx b/ui/rsl/src/components/status/DatasetStatus.tsx index 9d34202a01..da028f655c 100644 --- a/ui/rsl/src/components/status/DatasetStatus.tsx +++ b/ui/rsl/src/components/status/DatasetStatus.tsx @@ -85,13 +85,13 @@ function JourneyFilesInfo({ - + Reiseketten - + Reisendengruppen - + Reisende @@ -99,45 +99,19 @@ function JourneyFilesInfo({ Datei Änderungsdatum Geladen - Nicht geladen + Neu berechnet + Ignoriert Geladen - Nicht geladen + Neu berechnet + Ignoriert Geladen - Nicht geladen + Neu berechnet + Ignoriert {journey_files.map((file) => ( - - {file.name} - {formatDateTime(file.last_modified)} - {formatNumber(file.matched_journeys)} - - {formatNumber(file.unmatched_journeys)} ( - {formatPercent( - file.unmatched_journeys / - (file.matched_journeys + file.unmatched_journeys), - )} - ) - - {formatNumber(file.matched_groups)} - - {formatNumber(file.unmatched_groups)} ( - {formatPercent( - file.unmatched_groups / - (file.matched_groups + file.unmatched_groups), - )} - ) - - {formatNumber(file.matched_pax)} - - {formatNumber(file.unmatched_pax)} ( - {formatPercent( - file.unmatched_pax / (file.matched_pax + file.unmatched_pax), - )} - ) - - + ))} @@ -145,6 +119,55 @@ function JourneyFilesInfo({ ); } +function JourneyFileRow({ file }: { file: PaxMonJourneyFileInfo }) { + const totalJourneys = file.matched_journeys + file.unmatched_journeys; + const loadedJourneys = + file.matched_journeys + file.unmatched_journeys_rerouted; + const skippedJourneys = + file.unmatched_journeys - file.unmatched_journeys_rerouted; + + const totalGroups = file.matched_groups + file.unmatched_groups; + const loadedGroups = file.matched_groups + file.unmatched_groups_rerouted; + const skippedGroups = file.unmatched_groups - file.unmatched_groups_rerouted; + + const totalPax = file.matched_pax + file.unmatched_pax; + const loadedPax = file.matched_pax + file.unmatched_pax_rerouted; + const skippedPax = file.unmatched_pax - file.unmatched_pax_rerouted; + + return ( + + {file.name} + {formatDateTime(file.last_modified)} + {formatNumber(loadedJourneys)} + + {formatNumber(file.unmatched_journeys_rerouted)} ( + {formatPercent(file.unmatched_journeys_rerouted / totalJourneys)}) + + + {formatNumber(skippedJourneys)} ( + {formatPercent(skippedJourneys / totalJourneys)}) + + {formatNumber(loadedGroups)} + + {formatNumber(file.unmatched_groups_rerouted)} ( + {formatPercent(file.unmatched_groups_rerouted / totalGroups)}) + + + {formatNumber(skippedGroups)} ( + {formatPercent(skippedGroups / totalGroups)}) + + {formatNumber(loadedPax)} + + {formatNumber(file.unmatched_pax_rerouted)} ( + {formatPercent(file.unmatched_pax_rerouted / totalPax)}) + + + {formatNumber(skippedPax)} ({formatPercent(skippedPax / totalPax)}) + + + ); +} + function getCapacityFormatName(format: PaxMonCapacityFileFormat): string { switch (format) { case "TRIP":