From 0f32a6f09080216770f82adb2bf2c70f052881ce Mon Sep 17 00:00:00 2001 From: "Begerad, Stefan" Date: Mon, 19 Sep 2022 15:06:31 +0200 Subject: [PATCH] feat: display messages using marker --- app/assets/Logo_SIB_electricindigo.svg | 35 ++ app/components/map/map.jsx | 15 +- app/components/map/marker-msg.jsx | 32 ++ app/pages/map-page.jsx | 20 +- app/utils/gtfs-rt-utils.js | 80 +++ app/utils/gtfs-rt.js | 688 +++++++++++++++++++++++++ app/utils/string.js | 4 + config/webpack.common.js | 12 + package-lock.json | 133 ++++- package.json | 2 + 10 files changed, 1010 insertions(+), 11 deletions(-) create mode 100644 app/assets/Logo_SIB_electricindigo.svg create mode 100644 app/components/map/marker-msg.jsx create mode 100644 app/utils/gtfs-rt-utils.js create mode 100644 app/utils/gtfs-rt.js create mode 100644 app/utils/string.js diff --git a/app/assets/Logo_SIB_electricindigo.svg b/app/assets/Logo_SIB_electricindigo.svg new file mode 100644 index 0000000..458e73e --- /dev/null +++ b/app/assets/Logo_SIB_electricindigo.svg @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/app/components/map/map.jsx b/app/components/map/map.jsx index ae789c9..b558162 100644 --- a/app/components/map/map.jsx +++ b/app/components/map/map.jsx @@ -1,9 +1,13 @@ import React from 'react'; +import PropTypes from 'prop-types'; import {MapContainer,TileLayer} from 'react-leaflet'; /*JS module import (vs cdn or style link)*/ import 'leaflet/dist/leaflet.css' import './map.css'; -export default function Map() { + +import MsgMarker from './marker-msg'; + +export default function Map({messages}) { const position = [53.2206976, 7.7585528] return ( <> @@ -14,7 +18,16 @@ export default function Map() { attribution='© OpenStreetMap contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> + { + messages.map(function(value,key) { + //console.log(`key: ${key}, value: ${value}`); + return ; + }) + } ); } +Map.propTypes = { + messages: PropTypes.array +}; diff --git a/app/components/map/marker-msg.jsx b/app/components/map/marker-msg.jsx new file mode 100644 index 0000000..4915ab2 --- /dev/null +++ b/app/components/map/marker-msg.jsx @@ -0,0 +1,32 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {Marker,Popup} from 'react-leaflet'; +import bfly from '../../assets/Logo_SIB_electricindigo.svg'; +const MarkerMsg = ({ index,location }) => { + const iconBfly = new L.Icon({ + iconUrl: bfly, + iconRetinaUrl: bfly, + popupAnchor: [-0, -0], + iconSize: [32,45], + }); + return( + <> + + + Popup + + + + ); +} +export default MarkerMsg; + + +MarkerMsg.propTypes = { + index: PropTypes.number, + location: PropTypes.object +}; diff --git a/app/pages/map-page.jsx b/app/pages/map-page.jsx index b47f6c1..67cd689 100644 --- a/app/pages/map-page.jsx +++ b/app/pages/map-page.jsx @@ -1,9 +1,11 @@ -import React, {useEffect} from 'react'; +import React, {useEffect,useState} from 'react'; import axios from 'axios'; import Map from '../components/map/map'; - +import parseMessages from '../utils/gtfs-rt-utils'; export default function MapPage() { + /*storage*/ + const [vehPos, setVehPos] = useState([]); const getData= async ()=>{ console.log('getData() start...'); try { @@ -17,18 +19,22 @@ export default function MapPage() { }); //TODO remove debugging if(res.data){ - console.log('getVehPos() res available'); + //console.log('getVehPos() res available'); + /*parse messages*/ + const messages = parseMessages(res.data); + console.log('getVehPos() messages.length: '+messages.length); + /*set state*/ + setVehPos(messages); }else{ - console.log('getVehPos() res NOT available'); + console.error('getVehPos() res NOT available'); } } catch (err) { console.error('err.message: ' + err.message); } - console.log('getData() done.'); + //console.log('getData() done.'); }; useEffect(()=>{ const intervalCall=setInterval(()=>{ - console.log('Map: get data'); getData(); }, 5000); return ()=>{ @@ -40,7 +46,7 @@ export default function MapPage() { <> {/*TODO remove debugging*/}

MapPage

- + ); } diff --git a/app/utils/gtfs-rt-utils.js b/app/utils/gtfs-rt-utils.js new file mode 100644 index 0000000..baaa213 --- /dev/null +++ b/app/utils/gtfs-rt-utils.js @@ -0,0 +1,80 @@ +import Pbf from 'pbf'; + +import { FeedMessage } from './gtfs-rt.js'; +import charIntoString from './string'; + +export default function parseMessages(buffer){ + console.log('parseMessages() start...'); + const messages = []; + const pbf = new Pbf(buffer); + const feed = FeedMessage.read(pbf); + let gtfs_realtime_version, incrementality, timestamp = null; + if (feed.header) { + //console.log('getVehPos() header available'); + gtfs_realtime_version=feed.header.gtfs_realtime_version; + incrementality=feed.header.incrementality; + timestamp=feed.header.timestamp; + if(gtfs_realtime_version && incrementality, timestamp){ + //console.log(`getVehPos() gtfs_realtime_version: ${gtfs_realtime_version}, incrementaltiy: ${incrementality}, timestamp: ${timestamp} available`); + } + }else{ + console.error('getVehPos() header NOT available'); + } + feed.entity.forEach(entity => { + const vehiclePos = entity.vehicle; + if (vehiclePos) { + //console.log('getVehPos() vehiclePos available'); + const { trip, position, vehicle } = vehiclePos; + if (trip && position && vehicle) { + const {trip_id, route_id, direction_id, start_time, start_date, schedule_relationship}=trip; + if(trip_id){ + //console.log(`getVehPos() trip_id:${trip_id} available`); + }else{ + console.log(`getVehPos() trip_id NOT available`); + } + if(route_id){ + //console.log(`getVehPos() route_id:${route_id} available`); + }else{ + console.log(`getVehPos() route_id NOT available`); + } + if(direction_id){ + //console.log(`getVehPos() direction_id:${direction_id} available`); + }else{ + console.log(`getVehPos() direction_id NOT available`); + } + const {latitude, longitude, bearing, odometer, speed}=position; + if(latitude){ + //console.log(`getVehPos() latitude:${latitude} available`); + } + if(longitude){ + //console.log(`getVehPos() longitude:${longitude} available`); + } + //remove tailing dot + //match a dot when it is followed by a whitespace or the end of the string + /*TODO Is this precaution required?*/ + let latFormed = latitude.toString().replace(/\.+$/, ""); + //console.log(`getVehPos() latFormed:${latFormed}`); + latFormed=charIntoString(latFormed,latFormed.length - 7,'.'); + //console.log(`getVehPos() latFormed:${latFormed}`); + let lonFormed = longitude.toString().replace(/\.+$/, ""); + lonFormed=charIntoString(lonFormed,lonFormed.length - 7,'.'); + //console.log(`getVehPos() lonFormed:${lonFormed}`); + const message={ + headerGtfsRealtimeVersion: gtfs_realtime_version === undefined ? -1 : parseInt(gtfs_realtime_version,10) || -2, + headerIncrementality: incrementality === undefined ? -1 : parseInt(incrementality,10) || -2, + headerTimestamp : timestamp === undefined ? -1 : parseInt(timestamp,10) || -2, + routeId: route_id === undefined ? -1 : parseInt(route_id,10) || -2, + lat: latFormed === undefined ? -360 : latFormed, + lon: lonFormed === undefined ? -720 : lonFormed, + }; + messages.push(message); + } else { + console.error('getVehPos() trip, position & vehicle NOT unavailable '); + } + } else { + console.error('getVehPos() vehiclePos NOT available'); + } + }); + console.log('parseMessages() done.'); + return messages; +}; diff --git a/app/utils/gtfs-rt.js b/app/utils/gtfs-rt.js new file mode 100644 index 0000000..c57c38c --- /dev/null +++ b/app/utils/gtfs-rt.js @@ -0,0 +1,688 @@ +'use strict'; // code generated by pbf v3.2.1 + +// FeedMessage ======================================== + +var FeedMessage = exports.FeedMessage = {}; + +FeedMessage.read = function (pbf, end) { + return pbf.readFields(FeedMessage._readField, {header: null, entity: []}, end); +}; +FeedMessage._readField = function (tag, obj, pbf) { + if (tag === 1) obj.header = FeedHeader.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 2) obj.entity.push(FeedEntity.read(pbf, pbf.readVarint() + pbf.pos)); +}; +FeedMessage.write = function (obj, pbf) { + if (obj.header) pbf.writeMessage(1, FeedHeader.write, obj.header); + if (obj.entity) for (var i = 0; i < obj.entity.length; i++) pbf.writeMessage(2, FeedEntity.write, obj.entity[i]); +}; + +// FeedHeader ======================================== + +var FeedHeader = exports.FeedHeader = {}; + +FeedHeader.read = function (pbf, end) { + return pbf.readFields(FeedHeader._readField, {gtfs_realtime_version: "", incrementality: {"value":0,"options":{}}, timestamp: 0}, end); +}; +FeedHeader._readField = function (tag, obj, pbf) { + if (tag === 1) obj.gtfs_realtime_version = pbf.readString(); + else if (tag === 2) obj.incrementality = pbf.readVarint(); + else if (tag === 3) obj.timestamp = pbf.readVarint(); +}; +FeedHeader.write = function (obj, pbf) { + if (obj.gtfs_realtime_version) pbf.writeStringField(1, obj.gtfs_realtime_version); + if (obj.incrementality != undefined && obj.incrementality !== {"value":0,"options":{}}) pbf.writeVarintField(2, obj.incrementality); + if (obj.timestamp) pbf.writeVarintField(3, obj.timestamp); +}; + +FeedHeader.Incrementality = { + "FULL_DATASET": { + "value": 0, + "options": {} + }, + "DIFFERENTIAL": { + "value": 1, + "options": {} + } +}; + +// FeedEntity ======================================== + +var FeedEntity = exports.FeedEntity = {}; + +FeedEntity.read = function (pbf, end) { + return pbf.readFields(FeedEntity._readField, {id: "", is_deleted: false, trip_update: null, vehicle: null, alert: null, shape: null}, end); +}; +FeedEntity._readField = function (tag, obj, pbf) { + if (tag === 1) obj.id = pbf.readString(); + else if (tag === 2) obj.is_deleted = pbf.readBoolean(); + else if (tag === 3) obj.trip_update = TripUpdate.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 4) obj.vehicle = VehiclePosition.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 5) obj.alert = Alert.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 6) obj.shape = Shape.read(pbf, pbf.readVarint() + pbf.pos); +}; +FeedEntity.write = function (obj, pbf) { + if (obj.id) pbf.writeStringField(1, obj.id); + if (obj.is_deleted) pbf.writeBooleanField(2, obj.is_deleted); + if (obj.trip_update) pbf.writeMessage(3, TripUpdate.write, obj.trip_update); + if (obj.vehicle) pbf.writeMessage(4, VehiclePosition.write, obj.vehicle); + if (obj.alert) pbf.writeMessage(5, Alert.write, obj.alert); + if (obj.shape) pbf.writeMessage(6, Shape.write, obj.shape); +}; + +// TripUpdate ======================================== + +var TripUpdate = exports.TripUpdate = {}; + +TripUpdate.read = function (pbf, end) { + return pbf.readFields(TripUpdate._readField, {trip: null, vehicle: null, stop_time_update: [], timestamp: 0, delay: 0, trip_properties: null}, end); +}; +TripUpdate._readField = function (tag, obj, pbf) { + if (tag === 1) obj.trip = TripDescriptor.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 3) obj.vehicle = VehicleDescriptor.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 2) obj.stop_time_update.push(TripUpdate.StopTimeUpdate.read(pbf, pbf.readVarint() + pbf.pos)); + else if (tag === 4) obj.timestamp = pbf.readVarint(); + else if (tag === 5) obj.delay = pbf.readVarint(true); + else if (tag === 6) obj.trip_properties = TripUpdate.TripProperties.read(pbf, pbf.readVarint() + pbf.pos); +}; +TripUpdate.write = function (obj, pbf) { + if (obj.trip) pbf.writeMessage(1, TripDescriptor.write, obj.trip); + if (obj.vehicle) pbf.writeMessage(3, VehicleDescriptor.write, obj.vehicle); + if (obj.stop_time_update) for (var i = 0; i < obj.stop_time_update.length; i++) pbf.writeMessage(2, TripUpdate.StopTimeUpdate.write, obj.stop_time_update[i]); + if (obj.timestamp) pbf.writeVarintField(4, obj.timestamp); + if (obj.delay) pbf.writeVarintField(5, obj.delay); + if (obj.trip_properties) pbf.writeMessage(6, TripUpdate.TripProperties.write, obj.trip_properties); +}; + +// TripUpdate.StopTimeEvent ======================================== + +TripUpdate.StopTimeEvent = {}; + +TripUpdate.StopTimeEvent.read = function (pbf, end) { + return pbf.readFields(TripUpdate.StopTimeEvent._readField, {delay: 0, time: 0, uncertainty: 0}, end); +}; +TripUpdate.StopTimeEvent._readField = function (tag, obj, pbf) { + if (tag === 1) obj.delay = pbf.readVarint(true); + else if (tag === 2) obj.time = pbf.readVarint(true); + else if (tag === 3) obj.uncertainty = pbf.readVarint(true); +}; +TripUpdate.StopTimeEvent.write = function (obj, pbf) { + if (obj.delay) pbf.writeVarintField(1, obj.delay); + if (obj.time) pbf.writeVarintField(2, obj.time); + if (obj.uncertainty) pbf.writeVarintField(3, obj.uncertainty); +}; + +// TripUpdate.StopTimeUpdate ======================================== + +TripUpdate.StopTimeUpdate = {}; + +TripUpdate.StopTimeUpdate.read = function (pbf, end) { + return pbf.readFields(TripUpdate.StopTimeUpdate._readField, {stop_sequence: 0, stop_id: "", arrival: null, departure: null, departure_occupancy_status: 0, schedule_relationship: {"value":0,"options":{}}, stop_time_properties: null}, end); +}; +TripUpdate.StopTimeUpdate._readField = function (tag, obj, pbf) { + if (tag === 1) obj.stop_sequence = pbf.readVarint(); + else if (tag === 4) obj.stop_id = pbf.readString(); + else if (tag === 2) obj.arrival = TripUpdate.StopTimeEvent.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 3) obj.departure = TripUpdate.StopTimeEvent.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 7) obj.departure_occupancy_status = pbf.readVarint(); + else if (tag === 5) obj.schedule_relationship = pbf.readVarint(); + else if (tag === 6) obj.stop_time_properties = TripUpdate.StopTimeUpdate.StopTimeProperties.read(pbf, pbf.readVarint() + pbf.pos); +}; +TripUpdate.StopTimeUpdate.write = function (obj, pbf) { + if (obj.stop_sequence) pbf.writeVarintField(1, obj.stop_sequence); + if (obj.stop_id) pbf.writeStringField(4, obj.stop_id); + if (obj.arrival) pbf.writeMessage(2, TripUpdate.StopTimeEvent.write, obj.arrival); + if (obj.departure) pbf.writeMessage(3, TripUpdate.StopTimeEvent.write, obj.departure); + if (obj.departure_occupancy_status) pbf.writeVarintField(7, obj.departure_occupancy_status); + if (obj.schedule_relationship != undefined && obj.schedule_relationship !== {"value":0,"options":{}}) pbf.writeVarintField(5, obj.schedule_relationship); + if (obj.stop_time_properties) pbf.writeMessage(6, TripUpdate.StopTimeUpdate.StopTimeProperties.write, obj.stop_time_properties); +}; + +TripUpdate.StopTimeUpdate.ScheduleRelationship = { + "SCHEDULED": { + "value": 0, + "options": {} + }, + "SKIPPED": { + "value": 1, + "options": {} + }, + "NO_DATA": { + "value": 2, + "options": {} + }, + "UNSCHEDULED": { + "value": 3, + "options": {} + } +}; + +// TripUpdate.StopTimeUpdate.StopTimeProperties ======================================== + +TripUpdate.StopTimeUpdate.StopTimeProperties = {}; + +TripUpdate.StopTimeUpdate.StopTimeProperties.read = function (pbf, end) { + return pbf.readFields(TripUpdate.StopTimeUpdate.StopTimeProperties._readField, {assigned_stop_id: ""}, end); +}; +TripUpdate.StopTimeUpdate.StopTimeProperties._readField = function (tag, obj, pbf) { + if (tag === 1) obj.assigned_stop_id = pbf.readString(); +}; +TripUpdate.StopTimeUpdate.StopTimeProperties.write = function (obj, pbf) { + if (obj.assigned_stop_id) pbf.writeStringField(1, obj.assigned_stop_id); +}; + +// TripUpdate.TripProperties ======================================== + +TripUpdate.TripProperties = {}; + +TripUpdate.TripProperties.read = function (pbf, end) { + return pbf.readFields(TripUpdate.TripProperties._readField, {trip_id: "", start_date: "", start_time: "", shape_id: ""}, end); +}; +TripUpdate.TripProperties._readField = function (tag, obj, pbf) { + if (tag === 1) obj.trip_id = pbf.readString(); + else if (tag === 2) obj.start_date = pbf.readString(); + else if (tag === 3) obj.start_time = pbf.readString(); + else if (tag === 4) obj.shape_id = pbf.readString(); +}; +TripUpdate.TripProperties.write = function (obj, pbf) { + if (obj.trip_id) pbf.writeStringField(1, obj.trip_id); + if (obj.start_date) pbf.writeStringField(2, obj.start_date); + if (obj.start_time) pbf.writeStringField(3, obj.start_time); + if (obj.shape_id) pbf.writeStringField(4, obj.shape_id); +}; + +// VehiclePosition ======================================== + +var VehiclePosition = exports.VehiclePosition = {}; + +VehiclePosition.read = function (pbf, end) { + return pbf.readFields(VehiclePosition._readField, {trip: null, vehicle: null, position: null, current_stop_sequence: 0, stop_id: "", current_status: {"value":2,"options":{}}, timestamp: 0, congestion_level: 0, occupancy_status: 0, occupancy_percentage: 0, multi_carriage_details: []}, end); +}; +VehiclePosition._readField = function (tag, obj, pbf) { + if (tag === 1) obj.trip = TripDescriptor.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 8) obj.vehicle = VehicleDescriptor.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 2) obj.position = Position.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 3) obj.current_stop_sequence = pbf.readVarint(); + else if (tag === 7) obj.stop_id = pbf.readString(); + else if (tag === 4) obj.current_status = pbf.readVarint(); + else if (tag === 5) obj.timestamp = pbf.readVarint(); + else if (tag === 6) obj.congestion_level = pbf.readVarint(); + else if (tag === 9) obj.occupancy_status = pbf.readVarint(); + else if (tag === 10) obj.occupancy_percentage = pbf.readVarint(); + else if (tag === 11) obj.multi_carriage_details.push(VehiclePosition.CarriageDetails.read(pbf, pbf.readVarint() + pbf.pos)); +}; +VehiclePosition.write = function (obj, pbf) { + if (obj.trip) pbf.writeMessage(1, TripDescriptor.write, obj.trip); + if (obj.vehicle) pbf.writeMessage(8, VehicleDescriptor.write, obj.vehicle); + if (obj.position) pbf.writeMessage(2, Position.write, obj.position); + if (obj.current_stop_sequence) pbf.writeVarintField(3, obj.current_stop_sequence); + if (obj.stop_id) pbf.writeStringField(7, obj.stop_id); + if (obj.current_status != undefined && obj.current_status !== {"value":2,"options":{}}) pbf.writeVarintField(4, obj.current_status); + if (obj.timestamp) pbf.writeVarintField(5, obj.timestamp); + if (obj.congestion_level) pbf.writeVarintField(6, obj.congestion_level); + if (obj.occupancy_status) pbf.writeVarintField(9, obj.occupancy_status); + if (obj.occupancy_percentage) pbf.writeVarintField(10, obj.occupancy_percentage); + if (obj.multi_carriage_details) for (var i = 0; i < obj.multi_carriage_details.length; i++) pbf.writeMessage(11, VehiclePosition.CarriageDetails.write, obj.multi_carriage_details[i]); +}; + +VehiclePosition.VehicleStopStatus = { + "INCOMING_AT": { + "value": 0, + "options": {} + }, + "STOPPED_AT": { + "value": 1, + "options": {} + }, + "IN_TRANSIT_TO": { + "value": 2, + "options": {} + } +}; + +VehiclePosition.CongestionLevel = { + "UNKNOWN_CONGESTION_LEVEL": { + "value": 0, + "options": {} + }, + "RUNNING_SMOOTHLY": { + "value": 1, + "options": {} + }, + "STOP_AND_GO": { + "value": 2, + "options": {} + }, + "CONGESTION": { + "value": 3, + "options": {} + }, + "SEVERE_CONGESTION": { + "value": 4, + "options": {} + } +}; + +VehiclePosition.OccupancyStatus = { + "EMPTY": { + "value": 0, + "options": {} + }, + "MANY_SEATS_AVAILABLE": { + "value": 1, + "options": {} + }, + "FEW_SEATS_AVAILABLE": { + "value": 2, + "options": {} + }, + "STANDING_ROOM_ONLY": { + "value": 3, + "options": {} + }, + "CRUSHED_STANDING_ROOM_ONLY": { + "value": 4, + "options": {} + }, + "FULL": { + "value": 5, + "options": {} + }, + "NOT_ACCEPTING_PASSENGERS": { + "value": 6, + "options": {} + }, + "NO_DATA_AVAILABLE": { + "value": 7, + "options": {} + }, + "NOT_BOARDABLE": { + "value": 8, + "options": {} + } +}; + +// VehiclePosition.CarriageDetails ======================================== + +VehiclePosition.CarriageDetails = {}; + +VehiclePosition.CarriageDetails.read = function (pbf, end) { + return pbf.readFields(VehiclePosition.CarriageDetails._readField, {id: "", label: "", occupancy_status: {"value":7,"options":{}}, occupancy_percentage: -1, carriage_sequence: 0}, end); +}; +VehiclePosition.CarriageDetails._readField = function (tag, obj, pbf) { + if (tag === 1) obj.id = pbf.readString(); + else if (tag === 2) obj.label = pbf.readString(); + else if (tag === 3) obj.occupancy_status = pbf.readVarint(); + else if (tag === 4) obj.occupancy_percentage = pbf.readVarint(true); + else if (tag === 5) obj.carriage_sequence = pbf.readVarint(); +}; +VehiclePosition.CarriageDetails.write = function (obj, pbf) { + if (obj.id) pbf.writeStringField(1, obj.id); + if (obj.label) pbf.writeStringField(2, obj.label); + if (obj.occupancy_status != undefined && obj.occupancy_status !== {"value":7,"options":{}}) pbf.writeVarintField(3, obj.occupancy_status); + if (obj.occupancy_percentage != undefined && obj.occupancy_percentage !== -1) pbf.writeVarintField(4, obj.occupancy_percentage); + if (obj.carriage_sequence) pbf.writeVarintField(5, obj.carriage_sequence); +}; + +// Alert ======================================== + +var Alert = exports.Alert = {}; + +Alert.read = function (pbf, end) { + return pbf.readFields(Alert._readField, {active_period: [], informed_entity: [], cause: {"value":1,"options":{}}, effect: {"value":8,"options":{}}, url: null, header_text: null, description_text: null, tts_header_text: null, tts_description_text: null, severity_level: {"value":1,"options":{}}, image: null, image_alternative_text: null}, end); +}; +Alert._readField = function (tag, obj, pbf) { + if (tag === 1) obj.active_period.push(TimeRange.read(pbf, pbf.readVarint() + pbf.pos)); + else if (tag === 5) obj.informed_entity.push(EntitySelector.read(pbf, pbf.readVarint() + pbf.pos)); + else if (tag === 6) obj.cause = pbf.readVarint(); + else if (tag === 7) obj.effect = pbf.readVarint(); + else if (tag === 8) obj.url = TranslatedString.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 10) obj.header_text = TranslatedString.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 11) obj.description_text = TranslatedString.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 12) obj.tts_header_text = TranslatedString.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 13) obj.tts_description_text = TranslatedString.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 14) obj.severity_level = pbf.readVarint(); + else if (tag === 15) obj.image = TranslatedImage.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 16) obj.image_alternative_text = TranslatedString.read(pbf, pbf.readVarint() + pbf.pos); +}; +Alert.write = function (obj, pbf) { + if (obj.active_period) for (var i = 0; i < obj.active_period.length; i++) pbf.writeMessage(1, TimeRange.write, obj.active_period[i]); + if (obj.informed_entity) for (i = 0; i < obj.informed_entity.length; i++) pbf.writeMessage(5, EntitySelector.write, obj.informed_entity[i]); + if (obj.cause != undefined && obj.cause !== {"value":1,"options":{}}) pbf.writeVarintField(6, obj.cause); + if (obj.effect != undefined && obj.effect !== {"value":8,"options":{}}) pbf.writeVarintField(7, obj.effect); + if (obj.url) pbf.writeMessage(8, TranslatedString.write, obj.url); + if (obj.header_text) pbf.writeMessage(10, TranslatedString.write, obj.header_text); + if (obj.description_text) pbf.writeMessage(11, TranslatedString.write, obj.description_text); + if (obj.tts_header_text) pbf.writeMessage(12, TranslatedString.write, obj.tts_header_text); + if (obj.tts_description_text) pbf.writeMessage(13, TranslatedString.write, obj.tts_description_text); + if (obj.severity_level != undefined && obj.severity_level !== {"value":1,"options":{}}) pbf.writeVarintField(14, obj.severity_level); + if (obj.image) pbf.writeMessage(15, TranslatedImage.write, obj.image); + if (obj.image_alternative_text) pbf.writeMessage(16, TranslatedString.write, obj.image_alternative_text); +}; + +Alert.Cause = { + "UNKNOWN_CAUSE": { + "value": 1, + "options": {} + }, + "OTHER_CAUSE": { + "value": 2, + "options": {} + }, + "TECHNICAL_PROBLEM": { + "value": 3, + "options": {} + }, + "STRIKE": { + "value": 4, + "options": {} + }, + "DEMONSTRATION": { + "value": 5, + "options": {} + }, + "ACCIDENT": { + "value": 6, + "options": {} + }, + "HOLIDAY": { + "value": 7, + "options": {} + }, + "WEATHER": { + "value": 8, + "options": {} + }, + "MAINTENANCE": { + "value": 9, + "options": {} + }, + "CONSTRUCTION": { + "value": 10, + "options": {} + }, + "POLICE_ACTIVITY": { + "value": 11, + "options": {} + }, + "MEDICAL_EMERGENCY": { + "value": 12, + "options": {} + } +}; + +Alert.Effect = { + "NO_SERVICE": { + "value": 1, + "options": {} + }, + "REDUCED_SERVICE": { + "value": 2, + "options": {} + }, + "SIGNIFICANT_DELAYS": { + "value": 3, + "options": {} + }, + "DETOUR": { + "value": 4, + "options": {} + }, + "ADDITIONAL_SERVICE": { + "value": 5, + "options": {} + }, + "MODIFIED_SERVICE": { + "value": 6, + "options": {} + }, + "OTHER_EFFECT": { + "value": 7, + "options": {} + }, + "UNKNOWN_EFFECT": { + "value": 8, + "options": {} + }, + "STOP_MOVED": { + "value": 9, + "options": {} + }, + "NO_EFFECT": { + "value": 10, + "options": {} + }, + "ACCESSIBILITY_ISSUE": { + "value": 11, + "options": {} + } +}; + +Alert.SeverityLevel = { + "UNKNOWN_SEVERITY": { + "value": 1, + "options": {} + }, + "INFO": { + "value": 2, + "options": {} + }, + "WARNING": { + "value": 3, + "options": {} + }, + "SEVERE": { + "value": 4, + "options": {} + } +}; + +// TimeRange ======================================== + +var TimeRange = exports.TimeRange = {}; + +TimeRange.read = function (pbf, end) { + return pbf.readFields(TimeRange._readField, {start: 0, end: 0}, end); +}; +TimeRange._readField = function (tag, obj, pbf) { + if (tag === 1) obj.start = pbf.readVarint(); + else if (tag === 2) obj.end = pbf.readVarint(); +}; +TimeRange.write = function (obj, pbf) { + if (obj.start) pbf.writeVarintField(1, obj.start); + if (obj.end) pbf.writeVarintField(2, obj.end); +}; + +// Position ======================================== + +var Position = exports.Position = {}; + +Position.read = function (pbf, end) { + return pbf.readFields(Position._readField, {latitude: 0, longitude: 0, bearing: 0, odometer: 0, speed: 0}, end); +}; +Position._readField = function (tag, obj, pbf) { + if (tag === 1) obj.latitude = pbf.readFloat(); + else if (tag === 2) obj.longitude = pbf.readFloat(); + else if (tag === 3) obj.bearing = pbf.readFloat(); + else if (tag === 4) obj.odometer = pbf.readDouble(); + else if (tag === 5) obj.speed = pbf.readFloat(); +}; +Position.write = function (obj, pbf) { + if (obj.latitude) pbf.writeFloatField(1, obj.latitude); + if (obj.longitude) pbf.writeFloatField(2, obj.longitude); + if (obj.bearing) pbf.writeFloatField(3, obj.bearing); + if (obj.odometer) pbf.writeDoubleField(4, obj.odometer); + if (obj.speed) pbf.writeFloatField(5, obj.speed); +}; + +// TripDescriptor ======================================== + +var TripDescriptor = exports.TripDescriptor = {}; + +TripDescriptor.read = function (pbf, end) { + return pbf.readFields(TripDescriptor._readField, {trip_id: "", route_id: "", direction_id: 0, start_time: "", start_date: "", schedule_relationship: 0}, end); +}; +TripDescriptor._readField = function (tag, obj, pbf) { + if (tag === 1) obj.trip_id = pbf.readString(); + else if (tag === 5) obj.route_id = pbf.readString(); + else if (tag === 6) obj.direction_id = pbf.readVarint(); + else if (tag === 2) obj.start_time = pbf.readString(); + else if (tag === 3) obj.start_date = pbf.readString(); + else if (tag === 4) obj.schedule_relationship = pbf.readVarint(); +}; +TripDescriptor.write = function (obj, pbf) { + if (obj.trip_id) pbf.writeStringField(1, obj.trip_id); + if (obj.route_id) pbf.writeStringField(5, obj.route_id); + if (obj.direction_id) pbf.writeVarintField(6, obj.direction_id); + if (obj.start_time) pbf.writeStringField(2, obj.start_time); + if (obj.start_date) pbf.writeStringField(3, obj.start_date); + if (obj.schedule_relationship) pbf.writeVarintField(4, obj.schedule_relationship); +}; + +TripDescriptor.ScheduleRelationship = { + "SCHEDULED": { + "value": 0, + "options": {} + }, + "ADDED": { + "value": 1, + "options": {} + }, + "UNSCHEDULED": { + "value": 2, + "options": {} + }, + "CANCELED": { + "value": 3, + "options": {} + }, + "REPLACEMENT": { + "value": 5, + "options": { + "deprecated": "true" + } + }, + "DUPLICATED": { + "value": 6, + "options": {} + } +}; + +// VehicleDescriptor ======================================== + +var VehicleDescriptor = exports.VehicleDescriptor = {}; + +VehicleDescriptor.read = function (pbf, end) { + return pbf.readFields(VehicleDescriptor._readField, {id: "", label: "", license_plate: ""}, end); +}; +VehicleDescriptor._readField = function (tag, obj, pbf) { + if (tag === 1) obj.id = pbf.readString(); + else if (tag === 2) obj.label = pbf.readString(); + else if (tag === 3) obj.license_plate = pbf.readString(); +}; +VehicleDescriptor.write = function (obj, pbf) { + if (obj.id) pbf.writeStringField(1, obj.id); + if (obj.label) pbf.writeStringField(2, obj.label); + if (obj.license_plate) pbf.writeStringField(3, obj.license_plate); +}; + +// EntitySelector ======================================== + +var EntitySelector = exports.EntitySelector = {}; + +EntitySelector.read = function (pbf, end) { + return pbf.readFields(EntitySelector._readField, {agency_id: "", route_id: "", route_type: 0, trip: null, stop_id: "", direction_id: 0}, end); +}; +EntitySelector._readField = function (tag, obj, pbf) { + if (tag === 1) obj.agency_id = pbf.readString(); + else if (tag === 2) obj.route_id = pbf.readString(); + else if (tag === 3) obj.route_type = pbf.readVarint(true); + else if (tag === 4) obj.trip = TripDescriptor.read(pbf, pbf.readVarint() + pbf.pos); + else if (tag === 5) obj.stop_id = pbf.readString(); + else if (tag === 6) obj.direction_id = pbf.readVarint(); +}; +EntitySelector.write = function (obj, pbf) { + if (obj.agency_id) pbf.writeStringField(1, obj.agency_id); + if (obj.route_id) pbf.writeStringField(2, obj.route_id); + if (obj.route_type) pbf.writeVarintField(3, obj.route_type); + if (obj.trip) pbf.writeMessage(4, TripDescriptor.write, obj.trip); + if (obj.stop_id) pbf.writeStringField(5, obj.stop_id); + if (obj.direction_id) pbf.writeVarintField(6, obj.direction_id); +}; + +// TranslatedString ======================================== + +var TranslatedString = exports.TranslatedString = {}; + +TranslatedString.read = function (pbf, end) { + return pbf.readFields(TranslatedString._readField, {translation: []}, end); +}; +TranslatedString._readField = function (tag, obj, pbf) { + if (tag === 1) obj.translation.push(TranslatedString.Translation.read(pbf, pbf.readVarint() + pbf.pos)); +}; +TranslatedString.write = function (obj, pbf) { + if (obj.translation) for (var i = 0; i < obj.translation.length; i++) pbf.writeMessage(1, TranslatedString.Translation.write, obj.translation[i]); +}; + +// TranslatedString.Translation ======================================== + +TranslatedString.Translation = {}; + +TranslatedString.Translation.read = function (pbf, end) { + return pbf.readFields(TranslatedString.Translation._readField, {text: "", language: ""}, end); +}; +TranslatedString.Translation._readField = function (tag, obj, pbf) { + if (tag === 1) obj.text = pbf.readString(); + else if (tag === 2) obj.language = pbf.readString(); +}; +TranslatedString.Translation.write = function (obj, pbf) { + if (obj.text) pbf.writeStringField(1, obj.text); + if (obj.language) pbf.writeStringField(2, obj.language); +}; + +// TranslatedImage ======================================== + +var TranslatedImage = exports.TranslatedImage = {}; + +TranslatedImage.read = function (pbf, end) { + return pbf.readFields(TranslatedImage._readField, {localized_image: []}, end); +}; +TranslatedImage._readField = function (tag, obj, pbf) { + if (tag === 1) obj.localized_image.push(TranslatedImage.LocalizedImage.read(pbf, pbf.readVarint() + pbf.pos)); +}; +TranslatedImage.write = function (obj, pbf) { + if (obj.localized_image) for (var i = 0; i < obj.localized_image.length; i++) pbf.writeMessage(1, TranslatedImage.LocalizedImage.write, obj.localized_image[i]); +}; + +// TranslatedImage.LocalizedImage ======================================== + +TranslatedImage.LocalizedImage = {}; + +TranslatedImage.LocalizedImage.read = function (pbf, end) { + return pbf.readFields(TranslatedImage.LocalizedImage._readField, {url: "", media_type: "", language: ""}, end); +}; +TranslatedImage.LocalizedImage._readField = function (tag, obj, pbf) { + if (tag === 1) obj.url = pbf.readString(); + else if (tag === 2) obj.media_type = pbf.readString(); + else if (tag === 3) obj.language = pbf.readString(); +}; +TranslatedImage.LocalizedImage.write = function (obj, pbf) { + if (obj.url) pbf.writeStringField(1, obj.url); + if (obj.media_type) pbf.writeStringField(2, obj.media_type); + if (obj.language) pbf.writeStringField(3, obj.language); +}; + +// Shape ======================================== + +var Shape = exports.Shape = {}; + +Shape.read = function (pbf, end) { + return pbf.readFields(Shape._readField, {shape_id: "", encoded_polyline: ""}, end); +}; +Shape._readField = function (tag, obj, pbf) { + if (tag === 1) obj.shape_id = pbf.readString(); + else if (tag === 2) obj.encoded_polyline = pbf.readString(); +}; +Shape.write = function (obj, pbf) { + if (obj.shape_id) pbf.writeStringField(1, obj.shape_id); + if (obj.encoded_polyline) pbf.writeStringField(2, obj.encoded_polyline); +}; diff --git a/app/utils/string.js b/app/utils/string.js new file mode 100644 index 0000000..42b7c7a --- /dev/null +++ b/app/utils/string.js @@ -0,0 +1,4 @@ +/*TODO add description*/ +export default function insertCharIntoString(str,indexPos,char){ + return str.substring(0, indexPos) + char + str.substring(indexPos); +}; diff --git a/config/webpack.common.js b/config/webpack.common.js index 5038060..0337ff7 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -26,6 +26,18 @@ module.exports = { test: /\.css$/i, use: ["style-loader", "css-loader"], }, + { + //test all *.svg using svg-loader + test: /\.svg$/, + use: [ + { + loader: 'svg-url-loader', + options: { + limit: 10000, + }, + }, + ], + }, ] }, resolve: { diff --git a/package-lock.json b/package-lock.json index 067d223..346a776 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,14 @@ "version": "0.1.0", "license": "GPL-3.0-or-later", "dependencies": { - "axios": "^0.27.2", + "axios": "0.27.2", "bootstrap": "5.2.1", - "leaflet": "^1.8.0", + "leaflet": "1.8.0", + "pbf": "^3.2.1", "react": "18.2.0", "react-bootstrap": "2.5.0", "react-dom": "18.2.0", - "react-leaflet": "^4.0.2", + "react-leaflet": "4.0.2", "react-router-bootstrap": "0.26.2" }, "devDependencies": { @@ -26,6 +27,7 @@ "css-loader": "6.7.1", "html-webpack-plugin": "5.5.0", "style-loader": "3.3.1", + "svg-url-loader": "^8.0.0", "webpack": "5.74.0", "webpack-cli": "4.10.0", "webpack-dev-server": "4.11.0", @@ -3627,6 +3629,26 @@ "node": ">=0.8.0" } }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4136,6 +4158,25 @@ "postcss": "^8.1.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -4944,6 +4985,18 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "node_modules/pbf": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", + "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -5114,6 +5167,11 @@ "react": ">=0.14.0" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -5524,6 +5582,14 @@ "node": ">=8" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -6000,6 +6066,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-url-loader": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-8.0.0.tgz", + "integrity": "sha512-5doSXvl18hY1fGsRLdhWAU5jgzgxJ06/gc/26cpuDnN0xOz1HmmfhkpL29SSrdIvhtxQ1UwGzmk7wTT/l48mKw==", + "dev": true, + "dependencies": { + "file-loader": "~6.2.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -9372,6 +9453,16 @@ "websocket-driver": ">=0.5.1" } }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -9744,6 +9835,11 @@ "dev": true, "requires": {} }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -10339,6 +10435,15 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "pbf": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", + "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "requires": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + } + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -10458,6 +10563,11 @@ "warning": "^4.0.0" } }, + "protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -10769,6 +10879,14 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "requires": { + "protocol-buffers-schema": "^3.3.1" + } + }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -11132,6 +11250,15 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "svg-url-loader": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-8.0.0.tgz", + "integrity": "sha512-5doSXvl18hY1fGsRLdhWAU5jgzgxJ06/gc/26cpuDnN0xOz1HmmfhkpL29SSrdIvhtxQ1UwGzmk7wTT/l48mKw==", + "dev": true, + "requires": { + "file-loader": "~6.2.0" + } + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", diff --git a/package.json b/package.json index 6d1d160..8a2671b 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "css-loader": "6.7.1", "html-webpack-plugin": "5.5.0", "style-loader": "3.3.1", + "svg-url-loader": "8.0.0", "webpack": "5.74.0", "webpack-cli": "4.10.0", "webpack-dev-server": "4.11.0", @@ -41,6 +42,7 @@ "axios": "0.27.2", "bootstrap": "5.2.1", "leaflet": "1.8.0", + "pbf": "^3.2.1", "react": "18.2.0", "react-bootstrap": "2.5.0", "react-dom": "18.2.0",