From 961666e5593e51f07805eeafd4cfea062c2f3cd1 Mon Sep 17 00:00:00 2001 From: Edward Zhang Date: Thu, 16 Jul 2026 22:51:32 -0700 Subject: [PATCH 1/4] feat(ci): check compilation and run test suite --- .github/workflows/ci.yml | 48 ++++++++++++++++++++++++++++++++++++++++ src/services/mbus.ts | 2 +- src/services/ride.ts | 2 +- tsconfig.json | 6 ++--- 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1fa0b5d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +name: CI +run-name: CI for ${{ github.ref }} +on: + push: + branches-ignore: + - "tools/*" + pull_request: +jobs: + Tests: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v6 + - name: NPM Install + run: npm i + working-directory: ${{ github.workspace }} + - name: Test Suite + run: | + export MBUS_URL=https://mbus.bustime.mock.mb.thething.fyi/ + export RIDE_URL=https://ride.bustime.mock.mb.thething.fyi/ + npm start & + until curl localhost:3000 > /dev/null 2>&1 + do + sleep 1 # waits for initial startup + done + sleep 10 + until curl localhost:3000 > /dev/null 2>&1 + do + sleep 1 # waits for the walking cache to populate + done + sleep 10 # waits for the graph/predictions to be built + npx vitest run test + # npm test + working-directory: ${{ github.workspace }} + Typecheck: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v6 + # - name: Placeholder + # run: echo hi + # working-directory: ${{ github.workspace }} + - name: NPM Install + run: npm i + working-directory: ${{ github.workspace }} + - name: Typecheck + run: tsc --noEmit + working-directory: ${{ github.workspace }} diff --git a/src/services/mbus.ts b/src/services/mbus.ts index 1c9eeeb..a479f5a 100644 --- a/src/services/mbus.ts +++ b/src/services/mbus.ts @@ -5,7 +5,7 @@ import dotenv from "dotenv"; dotenv.config(); const API_KEY = process.env.MBUS_API_KEY; -const BASE_URL = 'https://mbus.ltp.umich.edu/bustime/api/v3/'; +const BASE_URL = process.env.MBUS_URL || 'https://mbus.ltp.umich.edu/bustime/api/v3/'; const client = axios.create({ baseURL: BASE_URL, diff --git a/src/services/ride.ts b/src/services/ride.ts index 2a6455f..bd8fd31 100644 --- a/src/services/ride.ts +++ b/src/services/ride.ts @@ -7,7 +7,7 @@ import dotenv from "dotenv"; dotenv.config(); const RIDE_API_KEY = process.env.RIDE_API_KEY; -const BASE_URL = 'https://rt.theride.org/bustime/api/v3/'; +const BASE_URL = process.env.RIDE_URL || 'https://rt.theride.org/bustime/api/v3/'; const client = axios.create({ baseURL: BASE_URL, diff --git a/tsconfig.json b/tsconfig.json index 144c0e8..10ce3c8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,14 @@ { "compilerOptions": { - "target": "es6", + "target": "es2021", "module": "esnext", - "moduleResolution": "Node", + // "moduleResolution": "Node", "esModuleInterop": true, "resolveJsonModule": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, - "baseUrl": "./", + // "baseUrl": "./", "paths": { "@/*": [ "./src/*" From a0d3b2c29e412ac6d5f7cf2d4160daed610ded12 Mon Sep 17 00:00:00 2001 From: Edward Zhang Date: Sat, 18 Jul 2026 07:19:41 -0700 Subject: [PATCH 2/4] test(reminders): use bustime urls from env vars --- test/reminder.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/reminder.test.ts b/test/reminder.test.ts index 5a2a8f8..4086703 100644 --- a/test/reminder.test.ts +++ b/test/reminder.test.ts @@ -203,14 +203,17 @@ describe('Reminders', () => { it('should get unix timestamp from ride bus api', async () => { configDotenv(); const RIDE_API_KEY = process.env.RIDE_API_KEY; - const BASE_URL = 'https://rt.theride.org/bustime/api/v3/'; + expect(RIDE_API_KEY || process.env.RIDE_URL, 'unable to make requests to a theride bustime server') + .toBeTruthy(); + const BASE_URL = process.env.RIDE_URL || 'https://rt.theride.org/bustime/api/v3/'; const client = axios.create({ baseURL: BASE_URL, params: { key: RIDE_API_KEY, format: 'json' } }); const res = await client.get('/gettime', { params: { unixTime: true } }); - expect(Math.abs(parseInt(res.data["bustime-response"]["tm"]) - Date.now())).toBeLessThan(60 * 1000); + expect(Math.abs(parseInt(res.data["bustime-response"]["tm"]) - Date.now())) + .toBeLessThan(2 * 24 * 60 * 60 * 1000); }); it('should have cached preds in a good state', async () => { @@ -229,7 +232,7 @@ describe('Reminders', () => { for (const k in sample) { expect(k + ":" +typeof x[k]).toBe(k + ":" + typeof sample[k]); if (k == "prdtm") { - expect(x[k]).toBeGreaterThanOrEqual(Date.now() - 15 * 1000); + expect(x[k]).toBeGreaterThanOrEqual(Date.now() - 2 * 24 * 60 * 60 * 1000); } } }; From c4719630f8dd6b853ae7cf46ef97f85963764e8b Mon Sep 17 00:00:00 2001 From: Edward Zhang Date: Sat, 18 Jul 2026 21:01:41 -0700 Subject: [PATCH 3/4] feat(ci): build and upload typedoc documentation --- .github/workflows/ci.yml | 22 + .gitignore | 3 +- docs/.nojekyll | 1 - docs/assets/hierarchy.js | 1 - docs/assets/highlight.css | 43 - docs/assets/icons.js | 18 - docs/assets/icons.svg | 1 - docs/assets/main.js | 60 - docs/assets/navigation.js | 1 - docs/assets/search.js | 1 - docs/assets/style.css | 1633 ----------------- ...r_McRaptorAlgorithm.McRaptorAlgorithm.html | 30 - docs/classes/raptor_McStructs.Bag.html | 13 - docs/classes/raptor_McStructs.Label.html | 36 - docs/functions/jobs.startBackgroundJobs.html | 2 - .../routes_api.activeRemindersForToken.html | 3 - .../routes_api.getAllPredictions.html | 5 - .../routes_api.getAllRideRoutes.html | 5 - .../functions/routes_api.getAllRideStops.html | 5 - docs/functions/routes_api.getAllRoutes.html | 5 - docs/functions/routes_api.getAllStops.html | 5 - .../routes_api.getBuildingLocations.html | 5 - .../functions/routes_api.getBusPositions.html | 5 - .../routes_api.getBusPredictions.html | 5 - .../routes_api.getBusPredictionsLegacy.html | 4 - .../functions/routes_api.getFrontendData.html | 5 - docs/functions/routes_api.getKeyStops.html | 5 - .../functions/routes_api.getNearestStops.html | 5 - .../routes_api.getRidePositions.html | 5 - .../routes_api.getRidePredictions.html | 5 - .../routes_api.getRideStopPredictions.html | 5 - docs/functions/routes_api.getRouteCache.html | 5 - docs/functions/routes_api.getRouteColor.html | 5 - docs/functions/routes_api.getRouteColors.html | 5 - .../routes_api.getRouteInfoVersion.html | 5 - .../routes_api.getRouteInformation.html | 5 - .../routes_api.getSelectableRoutes.html | 5 - docs/functions/routes_api.getStartupInfo.html | 5 - .../routes_api.getStartupMessages.html | 5 - .../routes_api.getStopPredictions.html | 5 - .../functions/routes_api.getVehicleImage.html | 5 - .../routes_api.getVehiclePositions.html | 5 - .../functions/routes_api.modifyReminders.html | 4 - docs/functions/routes_api.notifyMeLater.html | 1 - docs/functions/routes_api.planJourney.html | 5 - docs/functions/routes_api.saveGraph.html | 5 - docs/functions/routes_api.setReminder.html | 3 - docs/functions/routes_api.swapToken.html | 5 - docs/functions/routes_api.unsetReminder.html | 3 - ...ervices_graphBuilder.findNearestStops.html | 2 - ...ervices_graphBuilder.initializeRoutes.html | 2 - .../services_graphBuilder.rebuildGraph.html | 2 - .../services_graphBuilder.saveGraphState.html | 2 - .../services_graphBuilder.sortPreds.html | 2 - ...vices_graphBuilder.updateBusPositions.html | 2 - .../services_journey.planJourney.html | 8 - .../services_mbus.fetchPatterns.html | 2 - .../services_mbus.fetchPredictions.html | 2 - docs/functions/services_mbus.fetchRoutes.html | 2 - .../services_mbus.fetchVehicles.html | 2 - .../services_metadata.getAllRouteConfig.html | 2 - .../services_metadata.getRouteColor.html | 2 - .../services_metadata.getRouteImage.html | 2 - .../services_reminder.eventsEqual.html | 1 - .../services_reminder.infoToUseForRoute.html | 1 - ...ervices_reminder.processRideReminders.html | 1 - ...s_reminder.processUniversityReminders.html | 1 - .../services_reminder.sendNotifToAll.html | 1 - .../services_reminderTypes.baseEvent.html | 2 - .../services_reminderTypes.delayEvent.html | 2 - .../services_reminderTypes.eventsEqual.html | 1 - .../services_reminderTypes.fromKey.html | 1 - ...vices_reminderTypes.registrationToken.html | 1 - .../services_reminderTypes.sameBaseEvent.html | 1 - ...services_reminderTypes.thresholdEvent.html | 2 - .../services_reminderTypes.toKey.html | 2 - .../services_ride.fetchPatterns.html | 2 - .../services_ride.fetchPredictions.html | 2 - docs/functions/services_ride.fetchRoutes.html | 2 - .../services_ride.fetchVehicles.html | 2 - .../state_transitState.setCachedGraph.html | 2 - ...ansitState.setCachedRideStopLocations.html | 2 - ...e_transitState.setCachedStopLocations.html | 2 - docs/functions/walking_loadMap.haversine.html | 7 - docs/functions/walking_loadMap.loadMap.html | 16 - .../walking_walkingMap.buildStopNodeMap.html | 4 - ...alking_walkingMap.ensureCacheForStops.html | 5 - .../walking_walkingMap.getCachedWalk.html | 5 - ...ng_walkingMap.getWalkingDistancesFrom.html | 8 - ...walking_walkingMap.getWalkingResponse.html | 7 - docs/hierarchy.html | 1 - docs/index.html | 39 - .../raptor_McRaptorAlgorithm.Journey.html | 6 - .../raptor_McRaptorAlgorithm.JourneyLeg.html | 14 - docs/interfaces/raptor_types.Leg.html | 4 - docs/interfaces/raptor_types.StopTime.html | 16 - .../interfaces/raptor_types.TimetableLeg.html | 6 - docs/interfaces/raptor_types.Transfer.html | 9 - docs/interfaces/raptor_types.Trip.html | 7 - ...walking_walkingMap.BatchWalkingResult.html | 8 - .../walking_walkingMap.WalkingResponse.html | 8 - docs/media/logo.png | Bin 61262 -> 0 bytes docs/media/test_example.png | Bin 54791 -> 0 bytes docs/modules.html | 1 - docs/modules/app.html | 1 - docs/modules/jobs.html | 1 - docs/modules/raptor_McRaptorAlgorithm.html | 1 - docs/modules/raptor_McStructs.html | 1 - docs/modules/raptor_types.html | 1 - docs/modules/routes_api.html | 1 - docs/modules/services_graphBuilder.html | 1 - docs/modules/services_journey.html | 1 - docs/modules/services_mbus.html | 1 - docs/modules/services_metadata.html | 1 - docs/modules/services_reminder.html | 1 - docs/modules/services_reminderTypes.html | 1 - docs/modules/services_ride.html | 1 - docs/modules/state_transitState.html | 1 - docs/modules/types.html | 1 - docs/modules/walking_loadMap.html | 1 - docs/modules/walking_types.html | 1 - docs/modules/walking_walkingMap.html | 1 - docs/types/raptor_McStructs.Criteria.html | 5 - docs/types/raptor_types.Duration.html | 2 - docs/types/raptor_types.Interchange.html | 2 - docs/types/raptor_types.StopID.html | 2 - docs/types/raptor_types.Time.html | 3 - .../types/raptor_types.TransfersByOrigin.html | 2 - docs/types/raptor_types.TripID.html | 2 - .../services_reminder.PostThreshold.html | 7 - .../types/services_reminder.PreThreshold.html | 15 - .../services_reminderTypes.BaseEvent.html | 1 - .../services_reminderTypes.DelayEvent.html | 1 - docs/types/services_reminderTypes.Key.html | 1 - ...vices_reminderTypes.RegistrationToken.html | 1 - ...services_reminderTypes.ThresholdEvent.html | 1 - docs/types/state_transitState.Prediction.html | 2 - docs/types/types.Route.html | 2 - docs/types/walking_types.GraphMLEdge.html | 8 - docs/types/walking_types.GraphMLNode.html | 8 - docs/types/walking_types.LandmarkDef.html | 10 - docs/variables/routes_api.default.html | 3 - .../services_metadata.staticData.html | 2 - ...es_reminder.rideReminderSubscriptions.html | 1 - docs/variables/services_reminder.testing.html | 2 - ...inder.universityReminderSubscriptions.html | 1 - .../state_transitState.cachedGraph.html | 2 - ...tate_transitState.cachedPredsByStopId.html | 2 - .../state_transitState.cachedPredsByVid.html | 2 - ..._transitState.cachedRidePredsByStopId.html | 2 - ...ate_transitState.cachedRidePredsByVid.html | 2 - .../state_transitState.cachedRideRoutes.html | 2 - ..._transitState.cachedRideStopLocations.html | 1 - .../state_transitState.cachedRoutes.html | 2 - ...tate_transitState.cachedStopLocations.html | 2 - .../state_transitState.curBusPositions.html | 2 - .../state_transitState.curRidePositions.html | 2 - .../state_transitState.rideStopIdToName.html | 2 - .../state_transitState.routeTimingCache.html | 2 - .../state_transitState.stopIdToName.html | 2 - .../state_transitState.tatripidToRt.html | 2 - .../state_transitState.validRideRoutes.html | 2 - .../state_transitState.validRoutes.html | 2 - tsconfig.json | 2 +- 164 files changed, 25 insertions(+), 2371 deletions(-) delete mode 100644 docs/.nojekyll delete mode 100644 docs/assets/hierarchy.js delete mode 100644 docs/assets/highlight.css delete mode 100644 docs/assets/icons.js delete mode 100644 docs/assets/icons.svg delete mode 100644 docs/assets/main.js delete mode 100644 docs/assets/navigation.js delete mode 100644 docs/assets/search.js delete mode 100644 docs/assets/style.css delete mode 100644 docs/classes/raptor_McRaptorAlgorithm.McRaptorAlgorithm.html delete mode 100644 docs/classes/raptor_McStructs.Bag.html delete mode 100644 docs/classes/raptor_McStructs.Label.html delete mode 100644 docs/functions/jobs.startBackgroundJobs.html delete mode 100644 docs/functions/routes_api.activeRemindersForToken.html delete mode 100644 docs/functions/routes_api.getAllPredictions.html delete mode 100644 docs/functions/routes_api.getAllRideRoutes.html delete mode 100644 docs/functions/routes_api.getAllRideStops.html delete mode 100644 docs/functions/routes_api.getAllRoutes.html delete mode 100644 docs/functions/routes_api.getAllStops.html delete mode 100644 docs/functions/routes_api.getBuildingLocations.html delete mode 100644 docs/functions/routes_api.getBusPositions.html delete mode 100644 docs/functions/routes_api.getBusPredictions.html delete mode 100644 docs/functions/routes_api.getBusPredictionsLegacy.html delete mode 100644 docs/functions/routes_api.getFrontendData.html delete mode 100644 docs/functions/routes_api.getKeyStops.html delete mode 100644 docs/functions/routes_api.getNearestStops.html delete mode 100644 docs/functions/routes_api.getRidePositions.html delete mode 100644 docs/functions/routes_api.getRidePredictions.html delete mode 100644 docs/functions/routes_api.getRideStopPredictions.html delete mode 100644 docs/functions/routes_api.getRouteCache.html delete mode 100644 docs/functions/routes_api.getRouteColor.html delete mode 100644 docs/functions/routes_api.getRouteColors.html delete mode 100644 docs/functions/routes_api.getRouteInfoVersion.html delete mode 100644 docs/functions/routes_api.getRouteInformation.html delete mode 100644 docs/functions/routes_api.getSelectableRoutes.html delete mode 100644 docs/functions/routes_api.getStartupInfo.html delete mode 100644 docs/functions/routes_api.getStartupMessages.html delete mode 100644 docs/functions/routes_api.getStopPredictions.html delete mode 100644 docs/functions/routes_api.getVehicleImage.html delete mode 100644 docs/functions/routes_api.getVehiclePositions.html delete mode 100644 docs/functions/routes_api.modifyReminders.html delete mode 100644 docs/functions/routes_api.notifyMeLater.html delete mode 100644 docs/functions/routes_api.planJourney.html delete mode 100644 docs/functions/routes_api.saveGraph.html delete mode 100644 docs/functions/routes_api.setReminder.html delete mode 100644 docs/functions/routes_api.swapToken.html delete mode 100644 docs/functions/routes_api.unsetReminder.html delete mode 100644 docs/functions/services_graphBuilder.findNearestStops.html delete mode 100644 docs/functions/services_graphBuilder.initializeRoutes.html delete mode 100644 docs/functions/services_graphBuilder.rebuildGraph.html delete mode 100644 docs/functions/services_graphBuilder.saveGraphState.html delete mode 100644 docs/functions/services_graphBuilder.sortPreds.html delete mode 100644 docs/functions/services_graphBuilder.updateBusPositions.html delete mode 100644 docs/functions/services_journey.planJourney.html delete mode 100644 docs/functions/services_mbus.fetchPatterns.html delete mode 100644 docs/functions/services_mbus.fetchPredictions.html delete mode 100644 docs/functions/services_mbus.fetchRoutes.html delete mode 100644 docs/functions/services_mbus.fetchVehicles.html delete mode 100644 docs/functions/services_metadata.getAllRouteConfig.html delete mode 100644 docs/functions/services_metadata.getRouteColor.html delete mode 100644 docs/functions/services_metadata.getRouteImage.html delete mode 100644 docs/functions/services_reminder.eventsEqual.html delete mode 100644 docs/functions/services_reminder.infoToUseForRoute.html delete mode 100644 docs/functions/services_reminder.processRideReminders.html delete mode 100644 docs/functions/services_reminder.processUniversityReminders.html delete mode 100644 docs/functions/services_reminder.sendNotifToAll.html delete mode 100644 docs/functions/services_reminderTypes.baseEvent.html delete mode 100644 docs/functions/services_reminderTypes.delayEvent.html delete mode 100644 docs/functions/services_reminderTypes.eventsEqual.html delete mode 100644 docs/functions/services_reminderTypes.fromKey.html delete mode 100644 docs/functions/services_reminderTypes.registrationToken.html delete mode 100644 docs/functions/services_reminderTypes.sameBaseEvent.html delete mode 100644 docs/functions/services_reminderTypes.thresholdEvent.html delete mode 100644 docs/functions/services_reminderTypes.toKey.html delete mode 100644 docs/functions/services_ride.fetchPatterns.html delete mode 100644 docs/functions/services_ride.fetchPredictions.html delete mode 100644 docs/functions/services_ride.fetchRoutes.html delete mode 100644 docs/functions/services_ride.fetchVehicles.html delete mode 100644 docs/functions/state_transitState.setCachedGraph.html delete mode 100644 docs/functions/state_transitState.setCachedRideStopLocations.html delete mode 100644 docs/functions/state_transitState.setCachedStopLocations.html delete mode 100644 docs/functions/walking_loadMap.haversine.html delete mode 100644 docs/functions/walking_loadMap.loadMap.html delete mode 100644 docs/functions/walking_walkingMap.buildStopNodeMap.html delete mode 100644 docs/functions/walking_walkingMap.ensureCacheForStops.html delete mode 100644 docs/functions/walking_walkingMap.getCachedWalk.html delete mode 100644 docs/functions/walking_walkingMap.getWalkingDistancesFrom.html delete mode 100644 docs/functions/walking_walkingMap.getWalkingResponse.html delete mode 100644 docs/hierarchy.html delete mode 100644 docs/index.html delete mode 100644 docs/interfaces/raptor_McRaptorAlgorithm.Journey.html delete mode 100644 docs/interfaces/raptor_McRaptorAlgorithm.JourneyLeg.html delete mode 100644 docs/interfaces/raptor_types.Leg.html delete mode 100644 docs/interfaces/raptor_types.StopTime.html delete mode 100644 docs/interfaces/raptor_types.TimetableLeg.html delete mode 100644 docs/interfaces/raptor_types.Transfer.html delete mode 100644 docs/interfaces/raptor_types.Trip.html delete mode 100644 docs/interfaces/walking_walkingMap.BatchWalkingResult.html delete mode 100644 docs/interfaces/walking_walkingMap.WalkingResponse.html delete mode 100644 docs/media/logo.png delete mode 100644 docs/media/test_example.png delete mode 100644 docs/modules.html delete mode 100644 docs/modules/app.html delete mode 100644 docs/modules/jobs.html delete mode 100644 docs/modules/raptor_McRaptorAlgorithm.html delete mode 100644 docs/modules/raptor_McStructs.html delete mode 100644 docs/modules/raptor_types.html delete mode 100644 docs/modules/routes_api.html delete mode 100644 docs/modules/services_graphBuilder.html delete mode 100644 docs/modules/services_journey.html delete mode 100644 docs/modules/services_mbus.html delete mode 100644 docs/modules/services_metadata.html delete mode 100644 docs/modules/services_reminder.html delete mode 100644 docs/modules/services_reminderTypes.html delete mode 100644 docs/modules/services_ride.html delete mode 100644 docs/modules/state_transitState.html delete mode 100644 docs/modules/types.html delete mode 100644 docs/modules/walking_loadMap.html delete mode 100644 docs/modules/walking_types.html delete mode 100644 docs/modules/walking_walkingMap.html delete mode 100644 docs/types/raptor_McStructs.Criteria.html delete mode 100644 docs/types/raptor_types.Duration.html delete mode 100644 docs/types/raptor_types.Interchange.html delete mode 100644 docs/types/raptor_types.StopID.html delete mode 100644 docs/types/raptor_types.Time.html delete mode 100644 docs/types/raptor_types.TransfersByOrigin.html delete mode 100644 docs/types/raptor_types.TripID.html delete mode 100644 docs/types/services_reminder.PostThreshold.html delete mode 100644 docs/types/services_reminder.PreThreshold.html delete mode 100644 docs/types/services_reminderTypes.BaseEvent.html delete mode 100644 docs/types/services_reminderTypes.DelayEvent.html delete mode 100644 docs/types/services_reminderTypes.Key.html delete mode 100644 docs/types/services_reminderTypes.RegistrationToken.html delete mode 100644 docs/types/services_reminderTypes.ThresholdEvent.html delete mode 100644 docs/types/state_transitState.Prediction.html delete mode 100644 docs/types/types.Route.html delete mode 100644 docs/types/walking_types.GraphMLEdge.html delete mode 100644 docs/types/walking_types.GraphMLNode.html delete mode 100644 docs/types/walking_types.LandmarkDef.html delete mode 100644 docs/variables/routes_api.default.html delete mode 100644 docs/variables/services_metadata.staticData.html delete mode 100644 docs/variables/services_reminder.rideReminderSubscriptions.html delete mode 100644 docs/variables/services_reminder.testing.html delete mode 100644 docs/variables/services_reminder.universityReminderSubscriptions.html delete mode 100644 docs/variables/state_transitState.cachedGraph.html delete mode 100644 docs/variables/state_transitState.cachedPredsByStopId.html delete mode 100644 docs/variables/state_transitState.cachedPredsByVid.html delete mode 100644 docs/variables/state_transitState.cachedRidePredsByStopId.html delete mode 100644 docs/variables/state_transitState.cachedRidePredsByVid.html delete mode 100644 docs/variables/state_transitState.cachedRideRoutes.html delete mode 100644 docs/variables/state_transitState.cachedRideStopLocations.html delete mode 100644 docs/variables/state_transitState.cachedRoutes.html delete mode 100644 docs/variables/state_transitState.cachedStopLocations.html delete mode 100644 docs/variables/state_transitState.curBusPositions.html delete mode 100644 docs/variables/state_transitState.curRidePositions.html delete mode 100644 docs/variables/state_transitState.rideStopIdToName.html delete mode 100644 docs/variables/state_transitState.routeTimingCache.html delete mode 100644 docs/variables/state_transitState.stopIdToName.html delete mode 100644 docs/variables/state_transitState.tatripidToRt.html delete mode 100644 docs/variables/state_transitState.validRideRoutes.html delete mode 100644 docs/variables/state_transitState.validRoutes.html diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1fa0b5d..f7647b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,7 @@ jobs: npx vitest run test # npm test working-directory: ${{ github.workspace }} + Typecheck: runs-on: ubuntu-latest steps: @@ -46,3 +47,24 @@ jobs: - name: Typecheck run: tsc --noEmit working-directory: ${{ github.workspace }} + + Typedoc: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v6 + - name: NPM Install + run: npm i + working-directory: ${{ github.workspace }} + - name: Build Docs + run: npx typedoc --entryPointStrategy expand ./src --exclude \"**/legacy/**\" --treatWarningsAsErrors + working-directory: ${{ github.workspace }} + - name: Sync files + uses: SamKirkland/FTP-Deploy-Action@v4.4.0 + with: + server: ${{ secrets.FTP_SERVER }} + port: ${{ secrets.FTP_PORT }} + username: ${{ secrets.FTP_USERNAME }} + password: ${{ secrets.FTP_PASSWORD }} + local-dir: ${{ github.workspace }}/docs/ + server-dir: ${{ github.ref }}/typedoc/ diff --git a/.gitignore b/.gitignore index 8586e4f..f4b55a4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules/ package-lock.json .env .vscode/ -src/assets/walkingCache.json \ No newline at end of file +src/assets/walkingCache.json +/docs/ \ No newline at end of file diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e2ac661..0000000 --- a/docs/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/assets/hierarchy.js b/docs/assets/hierarchy.js deleted file mode 100644 index c11396f..0000000 --- a/docs/assets/hierarchy.js +++ /dev/null @@ -1 +0,0 @@ -window.hierarchyData = "eJyVjjEOgzAMRe/iOVAFVAbO0LFbhVAKpkQNCXLcoULcvU5VVYwwWfr28/sLUAgcob7pomwUEA4OO7bBS7aAhGl4MyHUcMEHKHha30NdnCsFL3ISW89Ig+kwnsjMHKjl94wxl/N85MkJ0zkT5SFw7LPEZ38mLUfrekL/LVEpXepmVaKuNuqrnZDN3eHBDltuR5nkLfXWS8bHAemQ88fs8a3rB573gTo=" \ No newline at end of file diff --git a/docs/assets/highlight.css b/docs/assets/highlight.css deleted file mode 100644 index bc36a19..0000000 --- a/docs/assets/highlight.css +++ /dev/null @@ -1,43 +0,0 @@ -:root { - --light-hl-0: #795E26; - --dark-hl-0: #DCDCAA; - --light-hl-1: #000000; - --dark-hl-1: #D4D4D4; - --light-hl-2: #A31515; - --dark-hl-2: #CE9178; - --light-code-background: #FFFFFF; - --dark-code-background: #1E1E1E; -} - -@media (prefers-color-scheme: light) { :root { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --code-background: var(--light-code-background); -} } - -@media (prefers-color-scheme: dark) { :root { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --code-background: var(--dark-code-background); -} } - -:root[data-theme='light'] { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --code-background: var(--light-code-background); -} - -:root[data-theme='dark'] { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --code-background: var(--dark-code-background); -} - -.hl-0 { color: var(--hl-0); } -.hl-1 { color: var(--hl-1); } -.hl-2 { color: var(--hl-2); } -pre, code { background: var(--code-background); } diff --git a/docs/assets/icons.js b/docs/assets/icons.js deleted file mode 100644 index 58882d7..0000000 --- a/docs/assets/icons.js +++ /dev/null @@ -1,18 +0,0 @@ -(function() { - addIcons(); - function addIcons() { - if (document.readyState === "loading") return document.addEventListener("DOMContentLoaded", addIcons); - const svg = document.body.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); - svg.innerHTML = `MMNEPVFCICPMFPCPTTAAATR`; - svg.style.display = "none"; - if (location.protocol === "file:") updateUseElements(); - } - - function updateUseElements() { - document.querySelectorAll("use").forEach(el => { - if (el.getAttribute("href").includes("#icon-")) { - el.setAttribute("href", el.getAttribute("href").replace(/.*#/, "#")); - } - }); - } -})() \ No newline at end of file diff --git a/docs/assets/icons.svg b/docs/assets/icons.svg deleted file mode 100644 index 50ad579..0000000 --- a/docs/assets/icons.svg +++ /dev/null @@ -1 +0,0 @@ -MMNEPVFCICPMFPCPTTAAATR \ No newline at end of file diff --git a/docs/assets/main.js b/docs/assets/main.js deleted file mode 100644 index 64b80ab..0000000 --- a/docs/assets/main.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -window.translations={"copy":"Copy","copied":"Copied!","normally_hidden":"This member is normally hidden due to your filter settings.","hierarchy_expand":"Expand","hierarchy_collapse":"Collapse","folder":"Folder","search_index_not_available":"The search index is not available","search_no_results_found_for_0":"No results found for {0}","kind_1":"Project","kind_2":"Module","kind_4":"Namespace","kind_8":"Enumeration","kind_16":"Enumeration Member","kind_32":"Variable","kind_64":"Function","kind_128":"Class","kind_256":"Interface","kind_512":"Constructor","kind_1024":"Property","kind_2048":"Method","kind_4096":"Call Signature","kind_8192":"Index Signature","kind_16384":"Constructor Signature","kind_32768":"Parameter","kind_65536":"Type Literal","kind_131072":"Type Parameter","kind_262144":"Accessor","kind_524288":"Get Signature","kind_1048576":"Set Signature","kind_2097152":"Type Alias","kind_4194304":"Reference","kind_8388608":"Document"}; -"use strict";(()=>{var Ke=Object.create;var he=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Ye=Object.prototype.hasOwnProperty;var et=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var tt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ze(e))!Ye.call(t,i)&&i!==n&&he(t,i,{get:()=>e[i],enumerable:!(r=Ge(e,i))||r.enumerable});return t};var nt=(t,e,n)=>(n=t!=null?Ke(Xe(t)):{},tt(e||!t||!t.__esModule?he(n,"default",{value:t,enumerable:!0}):n,t));var ye=et((me,ge)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=(function(e){return function(n){e.console&&console.warn&&console.warn(n)}})(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,l],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(oc?d+=2:a==c&&(n+=r[l+1]*i[d+1],l+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}if(s.str.length==0&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),f=s.str.charAt(1),p;f in s.node.edges?p=s.node.edges[f]:(p=new t.TokenSet,s.node.edges[f]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),c=0;c1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},(function(e,n){typeof define=="function"&&define.amd?define(n):typeof me=="object"?ge.exports=n():e.lunr=n()})(this,function(){return t})})()});var M,G={getItem(){return null},setItem(){}},K;try{K=localStorage,M=K}catch{K=G,M=G}var S={getItem:t=>M.getItem(t),setItem:(t,e)=>M.setItem(t,e),disableWritingLocalStorage(){M=G},disable(){localStorage.clear(),M=G},enable(){M=K}};window.TypeDoc||={disableWritingLocalStorage(){S.disableWritingLocalStorage()},disableLocalStorage:()=>{S.disable()},enableLocalStorage:()=>{S.enable()}};window.translations||={copy:"Copy",copied:"Copied!",normally_hidden:"This member is normally hidden due to your filter settings.",hierarchy_expand:"Expand",hierarchy_collapse:"Collapse",search_index_not_available:"The search index is not available",search_no_results_found_for_0:"No results found for {0}",folder:"Folder",kind_1:"Project",kind_2:"Module",kind_4:"Namespace",kind_8:"Enumeration",kind_16:"Enumeration Member",kind_32:"Variable",kind_64:"Function",kind_128:"Class",kind_256:"Interface",kind_512:"Constructor",kind_1024:"Property",kind_2048:"Method",kind_4096:"Call Signature",kind_8192:"Index Signature",kind_16384:"Constructor Signature",kind_32768:"Parameter",kind_65536:"Type Literal",kind_131072:"Type Parameter",kind_262144:"Accessor",kind_524288:"Get Signature",kind_1048576:"Set Signature",kind_2097152:"Type Alias",kind_4194304:"Reference",kind_8388608:"Document"};var pe=[];function X(t,e){pe.push({selector:e,constructor:t})}var Z=class{alwaysVisibleMember=null;constructor(){this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){pe.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!rt(e)){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r,document.querySelector(".col-sidebar").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(!n)return;let r=n.offsetParent==null,i=n;for(;i!==document.body;)i instanceof HTMLDetailsElement&&(i.open=!0),i=i.parentElement;if(n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let s=document.createElement("p");s.classList.add("warning"),s.textContent=window.translations.normally_hidden,n.prepend(s)}r&&e.scrollIntoView()}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent=window.translations.copied,e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent=window.translations.copy},100)},1e3)})})}};function rt(t){let e=t.getBoundingClientRect(),n=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(e.bottom<0||e.top-n>=0)}var fe=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var Ie=nt(ye(),1);async function R(t){let e=Uint8Array.from(atob(t),s=>s.charCodeAt(0)),r=new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate")),i=await new Response(r).text();return JSON.parse(i)}var Y="closing",ae="tsd-overlay";function it(){let t=Math.abs(window.innerWidth-document.documentElement.clientWidth);document.body.style.overflow="hidden",document.body.style.paddingRight=`${t}px`}function st(){document.body.style.removeProperty("overflow"),document.body.style.removeProperty("padding-right")}function xe(t,e){t.addEventListener("animationend",()=>{t.classList.contains(Y)&&(t.classList.remove(Y),document.getElementById(ae)?.remove(),t.close(),st())}),t.addEventListener("cancel",n=>{n.preventDefault(),ve(t)}),e?.closeOnClick&&document.addEventListener("click",n=>{t.open&&!t.contains(n.target)&&ve(t)},!0)}function Ee(t){if(t.open)return;let e=document.createElement("div");e.id=ae,document.body.appendChild(e),t.showModal(),it()}function ve(t){if(!t.open)return;document.getElementById(ae)?.classList.add(Y),t.classList.add(Y)}var I=class{el;app;constructor(e){this.el=e.el,this.app=e.app}};var be=document.head.appendChild(document.createElement("style"));be.dataset.for="filters";var le={};function we(t){for(let e of t.split(/\s+/))if(le.hasOwnProperty(e)&&!le[e])return!0;return!1}var ee=class extends I{key;value;constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),be.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } -`,this.app.updateIndexVisibility()}fromLocalStorage(){let e=S.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){S.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),le[`tsd-is-${this.el.name}`]=this.value,this.app.filterChanged(),this.app.updateIndexVisibility()}};var Le=0;async function Se(t,e){if(!window.searchData)return;let n=await R(window.searchData);t.data=n,t.index=Ie.Index.load(n.index),e.innerHTML=""}function _e(){let t=document.getElementById("tsd-search-trigger"),e=document.getElementById("tsd-search"),n=document.getElementById("tsd-search-input"),r=document.getElementById("tsd-search-results"),i=document.getElementById("tsd-search-script"),s=document.getElementById("tsd-search-status");if(!(t&&e&&n&&r&&i&&s))throw new Error("Search controls missing");let o={base:document.documentElement.dataset.base};o.base.endsWith("/")||(o.base+="/"),i.addEventListener("error",()=>{let a=window.translations.search_index_not_available;Pe(s,a)}),i.addEventListener("load",()=>{Se(o,s)}),Se(o,s),ot({trigger:t,searchEl:e,results:r,field:n,status:s},o)}function ot(t,e){let{field:n,results:r,searchEl:i,status:s,trigger:o}=t;xe(i,{closeOnClick:!0});function a(){Ee(i),n.setSelectionRange(0,n.value.length)}o.addEventListener("click",a),n.addEventListener("input",fe(()=>{at(r,n,s,e)},200)),n.addEventListener("keydown",l=>{if(r.childElementCount===0||l.ctrlKey||l.metaKey||l.altKey)return;let d=n.getAttribute("aria-activedescendant"),f=d?document.getElementById(d):null;if(f){let p=!1,v=!1;switch(l.key){case"Home":case"End":case"ArrowLeft":case"ArrowRight":v=!0;break;case"ArrowDown":case"ArrowUp":p=l.shiftKey;break}(p||v)&&ke(n)}if(!l.shiftKey)switch(l.key){case"Enter":f?.querySelector("a")?.click();break;case"ArrowUp":Te(r,n,f,-1),l.preventDefault();break;case"ArrowDown":Te(r,n,f,1),l.preventDefault();break}});function c(){ke(n)}n.addEventListener("change",c),n.addEventListener("blur",c),n.addEventListener("click",c),document.body.addEventListener("keydown",l=>{if(l.altKey||l.metaKey||l.shiftKey)return;let d=l.ctrlKey&&l.key==="k",f=!l.ctrlKey&&!ut()&&l.key==="/";(d||f)&&(l.preventDefault(),a())})}function at(t,e,n,r){if(!r.index||!r.data)return;t.innerHTML="",n.innerHTML="",Le+=1;let i=e.value.trim(),s;if(i){let a=i.split(" ").map(c=>c.length?`*${c}*`:"").join(" ");s=r.index.search(a).filter(({ref:c})=>{let l=r.data.rows[Number(c)].classes;return!l||!we(l)})}else s=[];if(s.length===0&&i){let a=window.translations.search_no_results_found_for_0.replace("{0}",` "${te(i)}" `);Pe(n,a);return}for(let a=0;ac.score-a.score);let o=Math.min(10,s.length);for(let a=0;a`,f=Ce(c.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(f+=` (score: ${s[a].score.toFixed(2)})`),c.parent&&(f=` - ${Ce(c.parent,i)}.${f}`);let p=document.createElement("li");p.id=`tsd-search:${Le}-${a}`,p.role="option",p.ariaSelected="false",p.classList.value=c.classes??"";let v=document.createElement("a");v.tabIndex=-1,v.href=r.base+c.url,v.innerHTML=d+`${f}`,p.append(v),t.appendChild(p)}}function Te(t,e,n,r){let i;if(r===1?i=n?.nextElementSibling||t.firstElementChild:i=n?.previousElementSibling||t.lastElementChild,i!==n){if(!i||i.role!=="option"){console.error("Option missing");return}i.ariaSelected="true",i.scrollIntoView({behavior:"smooth",block:"nearest"}),e.setAttribute("aria-activedescendant",i.id),n?.setAttribute("aria-selected","false")}}function ke(t){let e=t.getAttribute("aria-activedescendant");(e?document.getElementById(e):null)?.setAttribute("aria-selected","false"),t.setAttribute("aria-activedescendant","")}function Ce(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(te(t.substring(s,o)),`${te(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(te(t.substring(s))),i.join("")}var lt={"&":"&","<":"<",">":">","'":"'",'"':"""};function te(t){return t.replace(/[&<>"'"]/g,e=>lt[e])}function Pe(t,e){t.innerHTML=e?`
${e}
`:""}var ct=["button","checkbox","file","hidden","image","radio","range","reset","submit"];function ut(){let t=document.activeElement;return t?t.isContentEditable||t.tagName==="TEXTAREA"||t.tagName==="SEARCH"?!0:t.tagName==="INPUT"&&!ct.includes(t.type):!1}var D="mousedown",Me="mousemove",$="mouseup",ne={x:0,y:0},Qe=!1,ce=!1,dt=!1,F=!1,Oe=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(Oe?"is-mobile":"not-mobile");Oe&&"ontouchstart"in document.documentElement&&(dt=!0,D="touchstart",Me="touchmove",$="touchend");document.addEventListener(D,t=>{ce=!0,F=!1;let e=D=="touchstart"?t.targetTouches[0]:t;ne.y=e.pageY||0,ne.x=e.pageX||0});document.addEventListener(Me,t=>{if(ce&&!F){let e=D=="touchstart"?t.targetTouches[0]:t,n=ne.x-(e.pageX||0),r=ne.y-(e.pageY||0);F=Math.sqrt(n*n+r*r)>10}});document.addEventListener($,()=>{ce=!1});document.addEventListener("click",t=>{Qe&&(t.preventDefault(),t.stopImmediatePropagation(),Qe=!1)});var re=class extends I{active;className;constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener($,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(D,n=>this.onDocumentPointerDown(n)),document.addEventListener($,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){F||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!F&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var ue=new Map,de=class{open;accordions=[];key;constructor(e,n){this.key=e,this.open=n}add(e){this.accordions.push(e),e.open=this.open,e.addEventListener("toggle",()=>{this.toggle(e.open)})}toggle(e){for(let n of this.accordions)n.open=e;S.setItem(this.key,e.toString())}},ie=class extends I{constructor(e){super(e);let n=this.el.querySelector("summary"),r=n.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)});let i=`tsd-accordion-${n.dataset.key??n.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`,s;if(ue.has(i))s=ue.get(i);else{let o=S.getItem(i),a=o?o==="true":this.el.open;s=new de(i,a),ue.set(i,s)}s.add(this.el)}};function He(t){let e=S.getItem("tsd-theme")||"os";t.value=e,Ae(e),t.addEventListener("change",()=>{S.setItem("tsd-theme",t.value),Ae(t.value)})}function Ae(t){document.documentElement.dataset.theme=t}var se;function Ne(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",Re),Re())}async function Re(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let e=await R(window.navigationData);se=document.documentElement.dataset.base,se.endsWith("/")||(se+="/"),t.innerHTML="";for(let n of e)Be(n,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function Be(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-accordion`:"tsd-accordion";let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.dataset.key=i.join("$"),o.innerHTML='',De(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let c=a.appendChild(document.createElement("ul"));c.className="tsd-nested-navigation";for(let l of t.children)Be(l,c,i)}else De(t,r,t.class)}function De(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));if(r.href=se+t.path,n&&(r.className=n),location.pathname===r.pathname&&!r.href.includes("#")&&(r.classList.add("current"),r.ariaCurrent="page"),t.kind){let i=window.translations[`kind_${t.kind}`].replaceAll('"',""");r.innerHTML=``}r.appendChild(Fe(t.text,document.createElement("span")))}else{let r=e.appendChild(document.createElement("span")),i=window.translations.folder.replaceAll('"',""");r.innerHTML=``,r.appendChild(Fe(t.text,document.createElement("span")))}}function Fe(t,e){let n=t.split(/(?<=[^A-Z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[_-])(?=[^_-])/);for(let r=0;r{let i=r.target;for(;i.parentElement&&i.parentElement.tagName!="LI";)i=i.parentElement;i.dataset.dropdown&&(i.dataset.dropdown=String(i.dataset.dropdown!=="true"))});let t=new Map,e=new Set;for(let r of document.querySelectorAll(".tsd-full-hierarchy [data-refl]")){let i=r.querySelector("ul");t.has(r.dataset.refl)?e.add(r.dataset.refl):i&&t.set(r.dataset.refl,i)}for(let r of e)n(r);function n(r){let i=t.get(r).cloneNode(!0);i.querySelectorAll("[id]").forEach(s=>{s.removeAttribute("id")}),i.querySelectorAll("[data-dropdown]").forEach(s=>{s.dataset.dropdown="false"});for(let s of document.querySelectorAll(`[data-refl="${r}"]`)){let o=gt(),a=s.querySelector("ul");s.insertBefore(o,a),o.dataset.dropdown=String(!!a),a||s.appendChild(i.cloneNode(!0))}}}function pt(){let t=document.getElementById("tsd-hierarchy-script");t&&(t.addEventListener("load",Ve),Ve())}async function Ve(){let t=document.querySelector(".tsd-panel.tsd-hierarchy:has(h4 a)");if(!t||!window.hierarchyData)return;let e=+t.dataset.refl,n=await R(window.hierarchyData),r=t.querySelector("ul"),i=document.createElement("ul");if(i.classList.add("tsd-hierarchy"),ft(i,n,e),r.querySelectorAll("li").length==i.querySelectorAll("li").length)return;let s=document.createElement("span");s.classList.add("tsd-hierarchy-toggle"),s.textContent=window.translations.hierarchy_expand,t.querySelector("h4 a")?.insertAdjacentElement("afterend",s),s.insertAdjacentText("beforebegin",", "),s.addEventListener("click",()=>{s.textContent===window.translations.hierarchy_expand?(r.insertAdjacentElement("afterend",i),r.remove(),s.textContent=window.translations.hierarchy_collapse):(i.insertAdjacentElement("afterend",r),i.remove(),s.textContent=window.translations.hierarchy_expand)})}function ft(t,e,n){let r=e.roots.filter(i=>mt(e,i,n));for(let i of r)t.appendChild(je(e,i,n))}function je(t,e,n,r=new Set){if(r.has(e))return;r.add(e);let i=t.reflections[e],s=document.createElement("li");if(s.classList.add("tsd-hierarchy-item"),e===n){let o=s.appendChild(document.createElement("span"));o.textContent=i.name,o.classList.add("tsd-hierarchy-target")}else{for(let a of i.uniqueNameParents||[]){let c=t.reflections[a],l=s.appendChild(document.createElement("a"));l.textContent=c.name,l.href=oe+c.url,l.className=c.class+" tsd-signature-type",s.append(document.createTextNode("."))}let o=s.appendChild(document.createElement("a"));o.textContent=t.reflections[e].name,o.href=oe+i.url,o.className=i.class+" tsd-signature-type"}if(i.children){let o=s.appendChild(document.createElement("ul"));o.classList.add("tsd-hierarchy");for(let a of i.children){let c=je(t,a,n,r);c&&o.appendChild(c)}}return r.delete(e),s}function mt(t,e,n){if(e===n)return!0;let r=new Set,i=[t.reflections[e]];for(;i.length;){let s=i.pop();if(!r.has(s)){r.add(s);for(let o of s.children||[]){if(o===n)return!0;i.push(t.reflections[o])}}}return!1}function gt(){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("width","20"),t.setAttribute("height","20"),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.innerHTML='',t}X(re,"a[data-toggle]");X(ie,".tsd-accordion");X(ee,".tsd-filter-item input[type=checkbox]");var qe=document.getElementById("tsd-theme");qe&&He(qe);var yt=new Z;Object.defineProperty(window,"app",{value:yt});_e();Ne();$e();"virtualKeyboard"in navigator&&(navigator.virtualKeyboard.overlaysContent=!0);})(); -/*! Bundled license information: - -lunr/lunr.js: - (** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - *) - (*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - *) - (*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - *) -*/ diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js deleted file mode 100644 index ee9438b..0000000 --- a/docs/assets/navigation.js +++ /dev/null @@ -1 +0,0 @@ -window.navigationData = "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" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js deleted file mode 100644 index 474edbc..0000000 --- a/docs/assets/search.js +++ /dev/null @@ -1 +0,0 @@ -window.searchData = "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"; \ No newline at end of file diff --git a/docs/assets/style.css b/docs/assets/style.css deleted file mode 100644 index 44328e9..0000000 --- a/docs/assets/style.css +++ /dev/null @@ -1,1633 +0,0 @@ -@layer typedoc { - :root { - --dim-toolbar-contents-height: 2.5rem; - --dim-toolbar-border-bottom-width: 1px; - --dim-header-height: calc( - var(--dim-toolbar-border-bottom-width) + - var(--dim-toolbar-contents-height) - ); - - /* 0rem For mobile; unit is required for calculation in `calc` */ - --dim-container-main-margin-y: 0rem; - - --dim-footer-height: 3.5rem; - - --modal-animation-duration: 0.2s; - } - - :root { - /* Light */ - --light-color-background: #f2f4f8; - --light-color-background-secondary: #eff0f1; - /* Not to be confused with [:active](https://developer.mozilla.org/en-US/docs/Web/CSS/:active) */ - --light-color-background-active: #d6d8da; - --light-color-background-warning: #e6e600; - --light-color-warning-text: #222; - --light-color-accent: #c5c7c9; - --light-color-active-menu-item: var(--light-color-background-active); - --light-color-text: #222; - --light-color-contrast-text: #000; - --light-color-text-aside: #5e5e5e; - - --light-color-icon-background: var(--light-color-background); - --light-color-icon-text: var(--light-color-text); - - --light-color-comment-tag-text: var(--light-color-text); - --light-color-comment-tag: var(--light-color-background); - - --light-color-link: #1f70c2; - --light-color-focus-outline: #3584e4; - - --light-color-ts-keyword: #056bd6; - --light-color-ts-project: #b111c9; - --light-color-ts-module: var(--light-color-ts-project); - --light-color-ts-namespace: var(--light-color-ts-project); - --light-color-ts-enum: #7e6f15; - --light-color-ts-enum-member: var(--light-color-ts-enum); - --light-color-ts-variable: #4760ec; - --light-color-ts-function: #572be7; - --light-color-ts-class: #1f70c2; - --light-color-ts-interface: #108024; - --light-color-ts-constructor: var(--light-color-ts-class); - --light-color-ts-property: #9f5f30; - --light-color-ts-method: #be3989; - --light-color-ts-reference: #ff4d82; - --light-color-ts-call-signature: var(--light-color-ts-method); - --light-color-ts-index-signature: var(--light-color-ts-property); - --light-color-ts-constructor-signature: var( - --light-color-ts-constructor - ); - --light-color-ts-parameter: var(--light-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --light-color-ts-type-parameter: #a55c0e; - --light-color-ts-accessor: #c73c3c; - --light-color-ts-get-signature: var(--light-color-ts-accessor); - --light-color-ts-set-signature: var(--light-color-ts-accessor); - --light-color-ts-type-alias: #d51270; - /* reference not included as links will be colored with the kind that it points to */ - --light-color-document: #000000; - - --light-color-alert-note: #0969d9; - --light-color-alert-tip: #1a7f37; - --light-color-alert-important: #8250df; - --light-color-alert-warning: #9a6700; - --light-color-alert-caution: #cf222e; - - --light-external-icon: url("data:image/svg+xml;utf8,"); - --light-color-scheme: light; - } - - :root { - /* Dark */ - --dark-color-background: #2b2e33; - --dark-color-background-secondary: #1e2024; - /* Not to be confused with [:active](https://developer.mozilla.org/en-US/docs/Web/CSS/:active) */ - --dark-color-background-active: #5d5d6a; - --dark-color-background-warning: #bebe00; - --dark-color-warning-text: #222; - --dark-color-accent: #9096a2; - --dark-color-active-menu-item: var(--dark-color-background-active); - --dark-color-text: #f5f5f5; - --dark-color-contrast-text: #ffffff; - --dark-color-text-aside: #dddddd; - - --dark-color-icon-background: var(--dark-color-background-secondary); - --dark-color-icon-text: var(--dark-color-text); - - --dark-color-comment-tag-text: var(--dark-color-text); - --dark-color-comment-tag: var(--dark-color-background); - - --dark-color-link: #00aff4; - --dark-color-focus-outline: #4c97f2; - - --dark-color-ts-keyword: #3399ff; - --dark-color-ts-project: #e358ff; - --dark-color-ts-module: var(--dark-color-ts-project); - --dark-color-ts-namespace: var(--dark-color-ts-project); - --dark-color-ts-enum: #f4d93e; - --dark-color-ts-enum-member: var(--dark-color-ts-enum); - --dark-color-ts-variable: #798dff; - --dark-color-ts-function: #a280ff; - --dark-color-ts-class: #8ac4ff; - --dark-color-ts-interface: #6cff87; - --dark-color-ts-constructor: var(--dark-color-ts-class); - --dark-color-ts-property: #ff984d; - --dark-color-ts-method: #ff4db8; - --dark-color-ts-reference: #ff4d82; - --dark-color-ts-call-signature: var(--dark-color-ts-method); - --dark-color-ts-index-signature: var(--dark-color-ts-property); - --dark-color-ts-constructor-signature: var(--dark-color-ts-constructor); - --dark-color-ts-parameter: var(--dark-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --dark-color-ts-type-parameter: #e07d13; - --dark-color-ts-accessor: #ff6060; - --dark-color-ts-get-signature: var(--dark-color-ts-accessor); - --dark-color-ts-set-signature: var(--dark-color-ts-accessor); - --dark-color-ts-type-alias: #ff6492; - /* reference not included as links will be colored with the kind that it points to */ - --dark-color-document: #ffffff; - - --dark-color-alert-note: #0969d9; - --dark-color-alert-tip: #1a7f37; - --dark-color-alert-important: #8250df; - --dark-color-alert-warning: #9a6700; - --dark-color-alert-caution: #cf222e; - - --dark-external-icon: url("data:image/svg+xml;utf8,"); - --dark-color-scheme: dark; - } - - @media (prefers-color-scheme: light) { - :root { - --color-background: var(--light-color-background); - --color-background-secondary: var( - --light-color-background-secondary - ); - --color-background-active: var(--light-color-background-active); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-contrast-text: var(--light-color-contrast-text); - --color-text-aside: var(--light-color-text-aside); - - --color-icon-background: var(--light-color-icon-background); - --color-icon-text: var(--light-color-icon-text); - - --color-comment-tag-text: var(--light-color-text); - --color-comment-tag: var(--light-color-background); - - --color-link: var(--light-color-link); - --color-focus-outline: var(--light-color-focus-outline); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-project: var(--light-color-ts-project); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-reference: var(--light-color-ts-reference); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - --color-document: var(--light-color-document); - - --color-alert-note: var(--light-color-alert-note); - --color-alert-tip: var(--light-color-alert-tip); - --color-alert-important: var(--light-color-alert-important); - --color-alert-warning: var(--light-color-alert-warning); - --color-alert-caution: var(--light-color-alert-caution); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); - } - } - - @media (prefers-color-scheme: dark) { - :root { - --color-background: var(--dark-color-background); - --color-background-secondary: var( - --dark-color-background-secondary - ); - --color-background-active: var(--dark-color-background-active); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-contrast-text: var(--dark-color-contrast-text); - --color-text-aside: var(--dark-color-text-aside); - - --color-icon-background: var(--dark-color-icon-background); - --color-icon-text: var(--dark-color-icon-text); - - --color-comment-tag-text: var(--dark-color-text); - --color-comment-tag: var(--dark-color-background); - - --color-link: var(--dark-color-link); - --color-focus-outline: var(--dark-color-focus-outline); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-project: var(--dark-color-ts-project); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-reference: var(--dark-color-ts-reference); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - --color-document: var(--dark-color-document); - - --color-alert-note: var(--dark-color-alert-note); - --color-alert-tip: var(--dark-color-alert-tip); - --color-alert-important: var(--dark-color-alert-important); - --color-alert-warning: var(--dark-color-alert-warning); - --color-alert-caution: var(--dark-color-alert-caution); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); - } - } - - :root[data-theme="light"] { - --color-background: var(--light-color-background); - --color-background-secondary: var(--light-color-background-secondary); - --color-background-active: var(--light-color-background-active); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-icon-background: var(--light-color-icon-background); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-contrast-text: var(--light-color-contrast-text); - --color-text-aside: var(--light-color-text-aside); - --color-icon-text: var(--light-color-icon-text); - - --color-comment-tag-text: var(--light-color-text); - --color-comment-tag: var(--light-color-background); - - --color-link: var(--light-color-link); - --color-focus-outline: var(--light-color-focus-outline); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-project: var(--light-color-ts-project); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-reference: var(--light-color-ts-reference); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - --color-document: var(--light-color-document); - - --color-note: var(--light-color-note); - --color-tip: var(--light-color-tip); - --color-important: var(--light-color-important); - --color-warning: var(--light-color-warning); - --color-caution: var(--light-color-caution); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); - } - - :root[data-theme="dark"] { - --color-background: var(--dark-color-background); - --color-background-secondary: var(--dark-color-background-secondary); - --color-background-active: var(--dark-color-background-active); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-icon-background: var(--dark-color-icon-background); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-contrast-text: var(--dark-color-contrast-text); - --color-text-aside: var(--dark-color-text-aside); - --color-icon-text: var(--dark-color-icon-text); - - --color-comment-tag-text: var(--dark-color-text); - --color-comment-tag: var(--dark-color-background); - - --color-link: var(--dark-color-link); - --color-focus-outline: var(--dark-color-focus-outline); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-project: var(--dark-color-ts-project); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-reference: var(--dark-color-ts-reference); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - --color-document: var(--dark-color-document); - - --color-note: var(--dark-color-note); - --color-tip: var(--dark-color-tip); - --color-important: var(--dark-color-important); - --color-warning: var(--dark-color-warning); - --color-caution: var(--dark-color-caution); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); - } - - html { - color-scheme: var(--color-scheme); - @media (prefers-reduced-motion: no-preference) { - scroll-behavior: smooth; - } - } - - *:focus-visible, - .tsd-accordion-summary:focus-visible svg { - outline: 2px solid var(--color-focus-outline); - } - - .always-visible, - .always-visible .tsd-signatures { - display: inherit !important; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - line-height: 1.2; - } - - h1 { - font-size: 1.875rem; - margin: 0.67rem 0; - } - - h2 { - font-size: 1.5rem; - margin: 0.83rem 0; - } - - h3 { - font-size: 1.25rem; - margin: 1rem 0; - } - - h4 { - font-size: 1.05rem; - margin: 1.33rem 0; - } - - h5 { - font-size: 1rem; - margin: 1.5rem 0; - } - - h6 { - font-size: 0.875rem; - margin: 2.33rem 0; - } - - dl, - menu, - ol, - ul { - margin: 1em 0; - } - - dd { - margin: 0 0 0 34px; - } - - .container { - max-width: 1700px; - padding: 0 2rem; - } - - /* Footer */ - footer { - border-top: 1px solid var(--color-accent); - padding-top: 1rem; - padding-bottom: 1rem; - max-height: var(--dim-footer-height); - } - footer > p { - margin: 0 1em; - } - - .container-main { - margin: var(--dim-container-main-margin-y) auto; - /* toolbar, footer, margin */ - min-height: calc( - 100svh - var(--dim-header-height) - var(--dim-footer-height) - - 2 * var(--dim-container-main-margin-y) - ); - } - - @keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } - } - @keyframes fade-out { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - } - } - @keyframes pop-in-from-right { - from { - transform: translate(100%, 0); - } - to { - transform: translate(0, 0); - } - } - @keyframes pop-out-to-right { - from { - transform: translate(0, 0); - visibility: visible; - } - to { - transform: translate(100%, 0); - } - } - body { - background: var(--color-background); - font-family: - -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", - Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; - font-size: 16px; - color: var(--color-text); - margin: 0; - } - - a { - color: var(--color-link); - text-decoration: none; - } - a:hover { - text-decoration: underline; - } - a.external[target="_blank"] { - background-image: var(--external-icon); - background-position: top 3px right; - background-repeat: no-repeat; - padding-right: 13px; - } - a.tsd-anchor-link { - color: var(--color-text); - } - :target { - scroll-margin-block: calc(var(--dim-header-height) + 0.5rem); - } - - code, - pre { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 0.2em; - margin: 0; - font-size: 0.875rem; - border-radius: 0.8em; - } - - pre { - position: relative; - white-space: pre-wrap; - word-wrap: break-word; - padding: 10px; - border: 1px solid var(--color-accent); - margin-bottom: 8px; - } - pre code { - padding: 0; - font-size: 100%; - } - pre > button { - position: absolute; - top: 10px; - right: 10px; - opacity: 0; - transition: opacity 0.1s; - box-sizing: border-box; - } - pre:hover > button, - pre > button.visible, - pre > button:focus-visible { - opacity: 1; - } - - blockquote { - margin: 1em 0; - padding-left: 1em; - border-left: 4px solid gray; - } - - img { - max-width: 100%; - } - - * { - scrollbar-width: thin; - scrollbar-color: var(--color-accent) var(--color-icon-background); - } - - *::-webkit-scrollbar { - width: 0.75rem; - } - - *::-webkit-scrollbar-track { - background: var(--color-icon-background); - } - - *::-webkit-scrollbar-thumb { - background-color: var(--color-accent); - border-radius: 999rem; - border: 0.25rem solid var(--color-icon-background); - } - - dialog { - border: none; - outline: none; - padding: 0; - background-color: var(--color-background); - } - dialog::backdrop { - display: none; - } - #tsd-overlay { - background-color: rgba(0, 0, 0, 0.5); - position: fixed; - z-index: 9999; - top: 0; - left: 0; - right: 0; - bottom: 0; - animation: fade-in var(--modal-animation-duration) forwards; - } - #tsd-overlay.closing { - animation-name: fade-out; - } - - .tsd-typography { - line-height: 1.333em; - } - .tsd-typography ul { - list-style: square; - padding: 0 0 0 20px; - margin: 0; - } - .tsd-typography .tsd-index-panel h3, - .tsd-index-panel .tsd-typography h3, - .tsd-typography h4, - .tsd-typography h5, - .tsd-typography h6 { - font-size: 1em; - } - .tsd-typography h5, - .tsd-typography h6 { - font-weight: normal; - } - .tsd-typography p, - .tsd-typography ul, - .tsd-typography ol { - margin: 1em 0; - } - .tsd-typography table { - border-collapse: collapse; - border: none; - } - .tsd-typography td, - .tsd-typography th { - padding: 6px 13px; - border: 1px solid var(--color-accent); - } - .tsd-typography thead, - .tsd-typography tr:nth-child(even) { - background-color: var(--color-background-secondary); - } - - .tsd-alert { - padding: 8px 16px; - margin-bottom: 16px; - border-left: 0.25em solid var(--alert-color); - } - .tsd-alert blockquote > :last-child, - .tsd-alert > :last-child { - margin-bottom: 0; - } - .tsd-alert-title { - color: var(--alert-color); - display: inline-flex; - align-items: center; - } - .tsd-alert-title span { - margin-left: 4px; - } - - .tsd-alert-note { - --alert-color: var(--color-alert-note); - } - .tsd-alert-tip { - --alert-color: var(--color-alert-tip); - } - .tsd-alert-important { - --alert-color: var(--color-alert-important); - } - .tsd-alert-warning { - --alert-color: var(--color-alert-warning); - } - .tsd-alert-caution { - --alert-color: var(--color-alert-caution); - } - - .tsd-breadcrumb { - margin: 0; - margin-top: 1rem; - padding: 0; - color: var(--color-text-aside); - } - .tsd-breadcrumb a { - color: var(--color-text-aside); - text-decoration: none; - } - .tsd-breadcrumb a:hover { - text-decoration: underline; - } - .tsd-breadcrumb li { - display: inline; - } - .tsd-breadcrumb li:after { - content: " / "; - } - - .tsd-comment-tags { - display: flex; - flex-direction: column; - } - dl.tsd-comment-tag-group { - display: flex; - align-items: center; - overflow: hidden; - margin: 0.5em 0; - } - dl.tsd-comment-tag-group dt { - display: flex; - margin-right: 0.5em; - font-size: 0.875em; - font-weight: normal; - } - dl.tsd-comment-tag-group dd { - margin: 0; - } - code.tsd-tag { - padding: 0.25em 0.4em; - border: 0.1em solid var(--color-accent); - margin-right: 0.25em; - font-size: 70%; - } - h1 code.tsd-tag:first-of-type { - margin-left: 0.25em; - } - - dl.tsd-comment-tag-group dd:before, - dl.tsd-comment-tag-group dd:after { - content: " "; - } - dl.tsd-comment-tag-group dd pre, - dl.tsd-comment-tag-group dd:after { - clear: both; - } - dl.tsd-comment-tag-group p { - margin: 0; - } - - .tsd-panel.tsd-comment .lead { - font-size: 1.1em; - line-height: 1.333em; - margin-bottom: 2em; - } - .tsd-panel.tsd-comment .lead:last-child { - margin-bottom: 0; - } - - .tsd-filter-visibility h4 { - font-size: 1rem; - padding-top: 0.75rem; - padding-bottom: 0.5rem; - margin: 0; - } - .tsd-filter-item:not(:last-child) { - margin-bottom: 0.5rem; - } - .tsd-filter-input { - display: flex; - width: -moz-fit-content; - width: fit-content; - align-items: center; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: pointer; - } - .tsd-filter-input input[type="checkbox"] { - cursor: pointer; - position: absolute; - width: 1.5em; - height: 1.5em; - opacity: 0; - } - .tsd-filter-input input[type="checkbox"]:disabled { - pointer-events: none; - } - .tsd-filter-input svg { - cursor: pointer; - width: 1.5em; - height: 1.5em; - margin-right: 0.5em; - border-radius: 0.33em; - /* Leaving this at full opacity breaks event listeners on Firefox. - Don't remove unless you know what you're doing. */ - opacity: 0.99; - } - .tsd-filter-input input[type="checkbox"]:focus-visible + svg { - outline: 2px solid var(--color-focus-outline); - } - .tsd-checkbox-background { - fill: var(--color-accent); - } - input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { - stroke: var(--color-text); - } - .tsd-filter-input input:disabled ~ svg > .tsd-checkbox-background { - fill: var(--color-background); - stroke: var(--color-accent); - stroke-width: 0.25rem; - } - .tsd-filter-input input:disabled ~ svg > .tsd-checkbox-checkmark { - stroke: var(--color-accent); - } - - .settings-label { - font-weight: bold; - text-transform: uppercase; - display: inline-block; - } - - .tsd-filter-visibility .settings-label { - margin: 0.75rem 0 0.5rem 0; - } - - .tsd-theme-toggle .settings-label { - margin: 0.75rem 0.75rem 0 0; - } - - .tsd-hierarchy h4 label:hover span { - text-decoration: underline; - } - - .tsd-hierarchy { - list-style: square; - margin: 0; - } - .tsd-hierarchy-target { - font-weight: bold; - } - .tsd-hierarchy-toggle { - color: var(--color-link); - cursor: pointer; - } - - .tsd-full-hierarchy:not(:last-child) { - margin-bottom: 1em; - padding-bottom: 1em; - border-bottom: 1px solid var(--color-accent); - } - .tsd-full-hierarchy, - .tsd-full-hierarchy ul { - list-style: none; - margin: 0; - padding: 0; - } - .tsd-full-hierarchy ul { - padding-left: 1.5rem; - } - .tsd-full-hierarchy a { - padding: 0.25rem 0 !important; - font-size: 1rem; - display: inline-flex; - align-items: center; - color: var(--color-text); - } - .tsd-full-hierarchy svg[data-dropdown] { - cursor: pointer; - } - .tsd-full-hierarchy svg[data-dropdown="false"] { - transform: rotate(-90deg); - } - .tsd-full-hierarchy svg[data-dropdown="false"] ~ ul { - display: none; - } - - .tsd-panel-group.tsd-index-group { - margin-bottom: 0; - } - .tsd-index-panel .tsd-index-list { - list-style: none; - line-height: 1.333em; - margin: 0; - padding: 0.25rem 0 0 0; - overflow: hidden; - display: grid; - grid-template-columns: repeat(3, 1fr); - column-gap: 1rem; - grid-template-rows: auto; - } - @media (max-width: 1024px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(2, 1fr); - } - } - @media (max-width: 768px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(1, 1fr); - } - } - .tsd-index-panel .tsd-index-list li { - -webkit-page-break-inside: avoid; - -moz-page-break-inside: avoid; - -ms-page-break-inside: avoid; - -o-page-break-inside: avoid; - page-break-inside: avoid; - } - - .tsd-flag { - display: inline-block; - padding: 0.25em 0.4em; - border-radius: 4px; - color: var(--color-comment-tag-text); - background-color: var(--color-comment-tag); - text-indent: 0; - font-size: 75%; - line-height: 1; - font-weight: normal; - } - - .tsd-anchor { - position: relative; - top: -100px; - } - - .tsd-member { - position: relative; - } - .tsd-member .tsd-anchor + h3 { - display: flex; - align-items: center; - margin-top: 0; - margin-bottom: 0; - border-bottom: none; - } - - .tsd-navigation.settings { - margin: 0; - margin-bottom: 1rem; - } - .tsd-navigation > a, - .tsd-navigation .tsd-accordion-summary { - width: calc(100% - 0.25rem); - display: flex; - align-items: center; - } - .tsd-navigation a, - .tsd-navigation summary > span, - .tsd-page-navigation a { - display: flex; - width: calc(100% - 0.25rem); - align-items: center; - padding: 0.25rem; - color: var(--color-text); - text-decoration: none; - box-sizing: border-box; - } - .tsd-navigation a.current, - .tsd-page-navigation a.current { - background: var(--color-active-menu-item); - color: var(--color-contrast-text); - } - .tsd-navigation a:hover, - .tsd-page-navigation a:hover { - text-decoration: underline; - } - .tsd-navigation ul, - .tsd-page-navigation ul { - margin-top: 0; - margin-bottom: 0; - padding: 0; - list-style: none; - } - .tsd-navigation li, - .tsd-page-navigation li { - padding: 0; - max-width: 100%; - } - .tsd-navigation .tsd-nav-link { - display: none; - } - .tsd-nested-navigation { - margin-left: 3rem; - } - .tsd-nested-navigation > li > details { - margin-left: -1.5rem; - } - .tsd-small-nested-navigation { - margin-left: 1.5rem; - } - .tsd-small-nested-navigation > li > details { - margin-left: -1.5rem; - } - - .tsd-page-navigation-section > summary { - padding: 0.25rem; - } - .tsd-page-navigation-section > summary > svg { - margin-right: 0.25rem; - } - .tsd-page-navigation-section > div { - margin-left: 30px; - } - .tsd-page-navigation ul { - padding-left: 1.75rem; - } - - #tsd-sidebar-links a { - margin-top: 0; - margin-bottom: 0.5rem; - line-height: 1.25rem; - } - #tsd-sidebar-links a:last-of-type { - margin-bottom: 0; - } - - a.tsd-index-link { - padding: 0.25rem 0 !important; - font-size: 1rem; - line-height: 1.25rem; - display: inline-flex; - align-items: center; - color: var(--color-text); - } - .tsd-accordion-summary { - list-style-type: none; /* hide marker on non-safari */ - outline: none; /* broken on safari, so just hide it */ - display: flex; - align-items: center; - gap: 0.25rem; - box-sizing: border-box; - } - .tsd-accordion-summary::-webkit-details-marker { - display: none; /* hide marker on safari */ - } - .tsd-accordion-summary, - .tsd-accordion-summary a { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - - cursor: pointer; - } - .tsd-accordion-summary a { - width: calc(100% - 1.5rem); - } - .tsd-accordion-summary > * { - margin-top: 0; - margin-bottom: 0; - padding-top: 0; - padding-bottom: 0; - } - /* - * We need to be careful to target the arrow indicating whether the accordion - * is open, but not any other SVGs included in the details element. - */ - .tsd-accordion:not([open]) > .tsd-accordion-summary > svg:first-child { - transform: rotate(-90deg); - } - .tsd-index-content > :not(:first-child) { - margin-top: 0.75rem; - } - .tsd-index-summary { - margin-top: 1.5rem; - margin-bottom: 0.75rem; - display: flex; - align-content: center; - } - - .tsd-no-select { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } - .tsd-kind-icon { - margin-right: 0.5rem; - width: 1.25rem; - height: 1.25rem; - min-width: 1.25rem; - min-height: 1.25rem; - } - .tsd-signature > .tsd-kind-icon { - margin-right: 0.8rem; - } - - .tsd-panel { - margin-bottom: 2.5rem; - } - .tsd-panel.tsd-member { - margin-bottom: 4rem; - } - .tsd-panel:empty { - display: none; - } - .tsd-panel > h1, - .tsd-panel > h2, - .tsd-panel > h3 { - margin: 1.5rem -1.5rem 0.75rem -1.5rem; - padding: 0 1.5rem 0.75rem 1.5rem; - } - .tsd-panel > h1.tsd-before-signature, - .tsd-panel > h2.tsd-before-signature, - .tsd-panel > h3.tsd-before-signature { - margin-bottom: 0; - border-bottom: none; - } - - .tsd-panel-group { - margin: 2rem 0; - } - .tsd-panel-group.tsd-index-group { - margin: 2rem 0; - } - .tsd-panel-group.tsd-index-group details { - margin: 2rem 0; - } - .tsd-panel-group > .tsd-accordion-summary { - margin-bottom: 1rem; - } - - #tsd-search[open] { - animation: fade-in var(--modal-animation-duration) ease-out forwards; - } - #tsd-search[open].closing { - animation-name: fade-out; - } - - /* Avoid setting `display` on closed dialog */ - #tsd-search[open] { - display: flex; - flex-direction: column; - padding: 1rem; - width: 32rem; - max-width: 90vw; - max-height: calc(100vh - env(keyboard-inset-height, 0px) - 25vh); - /* Anchor dialog to top */ - margin-top: 10vh; - border-radius: 6px; - will-change: max-height; - } - #tsd-search-input { - box-sizing: border-box; - width: 100%; - padding: 0 0.625rem; /* 10px */ - outline: 0; - border: 2px solid var(--color-accent); - background-color: transparent; - color: var(--color-text); - border-radius: 4px; - height: 2.5rem; - flex: 0 0 auto; - font-size: 0.875rem; - transition: border-color 0.2s, background-color 0.2s; - } - #tsd-search-input:focus-visible { - background-color: var(--color-background-active); - border-color: transparent; - color: var(--color-contrast-text); - } - #tsd-search-input::placeholder { - color: inherit; - opacity: 0.8; - } - #tsd-search-results { - margin: 0; - padding: 0; - list-style: none; - flex: 1 1 auto; - display: flex; - flex-direction: column; - overflow-y: auto; - } - #tsd-search-results:not(:empty) { - margin-top: 0.5rem; - } - #tsd-search-results > li { - background-color: var(--color-background); - line-height: 1.5; - box-sizing: border-box; - border-radius: 4px; - } - #tsd-search-results > li:nth-child(even) { - background-color: var(--color-background-secondary); - } - #tsd-search-results > li:is(:hover, [aria-selected="true"]) { - background-color: var(--color-background-active); - color: var(--color-contrast-text); - } - /* It's important that this takes full size of parent `li`, to capture a click on `li` */ - #tsd-search-results > li > a { - display: flex; - align-items: center; - padding: 0.5rem 0.25rem; - box-sizing: border-box; - width: 100%; - } - #tsd-search-results > li > a > .text { - flex: 1 1 auto; - min-width: 0; - overflow-wrap: anywhere; - } - #tsd-search-results > li > a .parent { - color: var(--color-text-aside); - } - #tsd-search-results > li > a mark { - color: inherit; - background-color: inherit; - font-weight: bold; - } - #tsd-search-status { - flex: 1; - display: grid; - place-content: center; - text-align: center; - overflow-wrap: anywhere; - } - #tsd-search-status:not(:empty) { - min-height: 6rem; - } - - .tsd-signature { - margin: 0 0 1rem 0; - padding: 1rem 0.5rem; - border: 1px solid var(--color-accent); - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - font-size: 14px; - overflow-x: auto; - } - - .tsd-signature-keyword { - color: var(--color-ts-keyword); - font-weight: normal; - } - - .tsd-signature-symbol { - color: var(--color-text-aside); - font-weight: normal; - } - - .tsd-signature-type { - font-style: italic; - font-weight: normal; - } - - .tsd-signatures { - padding: 0; - margin: 0 0 1em 0; - list-style-type: none; - } - .tsd-signatures .tsd-signature { - margin: 0; - border-color: var(--color-accent); - border-width: 1px 0; - transition: background-color 0.1s; - } - .tsd-signatures .tsd-index-signature:not(:last-child) { - margin-bottom: 1em; - } - .tsd-signatures .tsd-index-signature .tsd-signature { - border-width: 1px; - } - .tsd-description .tsd-signatures .tsd-signature { - border-width: 1px; - } - - ul.tsd-parameter-list, - ul.tsd-type-parameter-list { - list-style: square; - margin: 0; - padding-left: 20px; - } - ul.tsd-parameter-list > li.tsd-parameter-signature, - ul.tsd-type-parameter-list > li.tsd-parameter-signature { - list-style: none; - margin-left: -20px; - } - ul.tsd-parameter-list h5, - ul.tsd-type-parameter-list h5 { - font-size: 16px; - margin: 1em 0 0.5em 0; - } - .tsd-sources { - margin-top: 1rem; - font-size: 0.875em; - } - .tsd-sources a { - color: var(--color-text-aside); - text-decoration: underline; - } - .tsd-sources ul { - list-style: none; - padding: 0; - } - - .tsd-page-toolbar { - position: sticky; - z-index: 1; - top: 0; - left: 0; - width: 100%; - color: var(--color-text); - background: var(--color-background-secondary); - border-bottom: var(--dim-toolbar-border-bottom-width) - var(--color-accent) solid; - transition: transform 0.3s ease-in-out; - } - .tsd-page-toolbar a { - color: var(--color-text); - } - .tsd-toolbar-contents { - display: flex; - align-items: center; - height: var(--dim-toolbar-contents-height); - margin: 0 auto; - } - .tsd-toolbar-contents > .title { - font-weight: bold; - margin-right: auto; - } - #tsd-toolbar-links { - display: flex; - align-items: center; - gap: 1.5rem; - margin-right: 1rem; - } - - .tsd-widget { - box-sizing: border-box; - display: inline-block; - opacity: 0.8; - height: 2.5rem; - width: 2.5rem; - transition: opacity 0.1s, background-color 0.1s; - text-align: center; - cursor: pointer; - border: none; - background-color: transparent; - } - .tsd-widget:hover { - opacity: 0.9; - } - .tsd-widget:active { - opacity: 1; - background-color: var(--color-accent); - } - #tsd-toolbar-menu-trigger { - display: none; - } - - .tsd-member-summary-name { - display: inline-flex; - align-items: center; - padding: 0.25rem; - text-decoration: none; - } - - .tsd-anchor-icon { - display: inline-flex; - align-items: center; - margin-left: 0.5rem; - color: var(--color-text); - vertical-align: middle; - } - - .tsd-anchor-icon svg { - width: 1em; - height: 1em; - visibility: hidden; - } - - .tsd-member-summary-name:hover > .tsd-anchor-icon svg, - .tsd-anchor-link:hover > .tsd-anchor-icon svg, - .tsd-anchor-icon:focus-visible svg { - visibility: visible; - } - - .deprecated { - text-decoration: line-through !important; - } - - .warning { - padding: 1rem; - color: var(--color-warning-text); - background: var(--color-background-warning); - } - - .tsd-kind-project { - color: var(--color-ts-project); - } - .tsd-kind-module { - color: var(--color-ts-module); - } - .tsd-kind-namespace { - color: var(--color-ts-namespace); - } - .tsd-kind-enum { - color: var(--color-ts-enum); - } - .tsd-kind-enum-member { - color: var(--color-ts-enum-member); - } - .tsd-kind-variable { - color: var(--color-ts-variable); - } - .tsd-kind-function { - color: var(--color-ts-function); - } - .tsd-kind-class { - color: var(--color-ts-class); - } - .tsd-kind-interface { - color: var(--color-ts-interface); - } - .tsd-kind-constructor { - color: var(--color-ts-constructor); - } - .tsd-kind-property { - color: var(--color-ts-property); - } - .tsd-kind-method { - color: var(--color-ts-method); - } - .tsd-kind-reference { - color: var(--color-ts-reference); - } - .tsd-kind-call-signature { - color: var(--color-ts-call-signature); - } - .tsd-kind-index-signature { - color: var(--color-ts-index-signature); - } - .tsd-kind-constructor-signature { - color: var(--color-ts-constructor-signature); - } - .tsd-kind-parameter { - color: var(--color-ts-parameter); - } - .tsd-kind-type-parameter { - color: var(--color-ts-type-parameter); - } - .tsd-kind-accessor { - color: var(--color-ts-accessor); - } - .tsd-kind-get-signature { - color: var(--color-ts-get-signature); - } - .tsd-kind-set-signature { - color: var(--color-ts-set-signature); - } - .tsd-kind-type-alias { - color: var(--color-ts-type-alias); - } - - /* if we have a kind icon, don't color the text by kind */ - .tsd-kind-icon ~ span { - color: var(--color-text); - } - - /* mobile */ - @media (max-width: 769px) { - #tsd-toolbar-menu-trigger { - display: inline-block; - /* temporary fix to vertically align, for compatibility */ - line-height: 2.5; - } - #tsd-toolbar-links { - display: none; - } - - .container-main { - display: flex; - } - .col-content { - float: none; - max-width: 100%; - width: 100%; - } - .col-sidebar { - position: fixed !important; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - z-index: 1024; - top: 0 !important; - bottom: 0 !important; - left: auto !important; - right: 0 !important; - padding: 1.5rem 1.5rem 0 0; - width: 75vw; - visibility: hidden; - background-color: var(--color-background); - transform: translate(100%, 0); - } - .col-sidebar > *:last-child { - padding-bottom: 20px; - } - .overlay { - content: ""; - display: block; - position: fixed; - z-index: 1023; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.75); - visibility: hidden; - } - - .to-has-menu .overlay { - animation: fade-in 0.4s; - } - - .to-has-menu .col-sidebar { - animation: pop-in-from-right 0.4s; - } - - .from-has-menu .overlay { - animation: fade-out 0.4s; - } - - .from-has-menu .col-sidebar { - animation: pop-out-to-right 0.4s; - } - - .has-menu body { - overflow: hidden; - } - .has-menu .overlay { - visibility: visible; - } - .has-menu .col-sidebar { - visibility: visible; - transform: translate(0, 0); - display: flex; - flex-direction: column; - gap: 1.5rem; - max-height: 100vh; - padding: 1rem 2rem; - } - .has-menu .tsd-navigation { - max-height: 100%; - } - .tsd-navigation .tsd-nav-link { - display: flex; - } - } - - /* one sidebar */ - @media (min-width: 770px) { - .container-main { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); - grid-template-areas: "sidebar content"; - --dim-container-main-margin-y: 2rem; - } - - .tsd-breadcrumb { - margin-top: 0; - } - - .col-sidebar { - grid-area: sidebar; - } - .col-content { - grid-area: content; - padding: 0 1rem; - } - } - @media (min-width: 770px) and (max-width: 1399px) { - .col-sidebar { - max-height: calc( - 100vh - var(--dim-header-height) - var(--dim-footer-height) - - 2 * var(--dim-container-main-margin-y) - ); - overflow: auto; - position: sticky; - top: calc( - var(--dim-header-height) + var(--dim-container-main-margin-y) - ); - } - .site-menu { - margin-top: 1rem; - } - } - - /* two sidebars */ - @media (min-width: 1200px) { - .container-main { - grid-template-columns: - minmax(0, 1fr) minmax(0, 2.5fr) minmax( - 0, - 20rem - ); - grid-template-areas: "sidebar content toc"; - } - - .col-sidebar { - display: contents; - } - - .page-menu { - grid-area: toc; - padding-left: 1rem; - } - .site-menu { - grid-area: sidebar; - } - - .site-menu { - margin-top: 0rem; - } - - .page-menu, - .site-menu { - max-height: calc( - 100vh - var(--dim-header-height) - var(--dim-footer-height) - - 2 * var(--dim-container-main-margin-y) - ); - overflow: auto; - position: sticky; - top: calc( - var(--dim-header-height) + var(--dim-container-main-margin-y) - ); - } - } -} diff --git a/docs/classes/raptor_McRaptorAlgorithm.McRaptorAlgorithm.html b/docs/classes/raptor_McRaptorAlgorithm.McRaptorAlgorithm.html deleted file mode 100644 index 2ebb4a4..0000000 --- a/docs/classes/raptor_McRaptorAlgorithm.McRaptorAlgorithm.html +++ /dev/null @@ -1,30 +0,0 @@ -McRaptorAlgorithm | mbus-backend
mbus-backend
    Preparing search index...

    Implementation of the McRAPTOR (Multi-Criteria Round-Based Public Transit Routing) algorithm. -Optimizes for arrival time, walking distance, and number of transfers.

    -
    Index

    Constructors

    Methods

    • Calculates optimal journeys for a specific departure time.

      -

      Parameters

      • origin: string

        The starting Stop ID.

        -
      • destination: string

        The destination Stop ID.

        -
      • departureTime: number

        The exact departure time.

        -

      Returns Journey[]

      A list of optimal Journey objects.

      -
    • Finds the best journeys within a time window, filtering for Pareto optimality across all departures.

      -

      Parameters

      • origin: string

        The starting Stop ID.

        -
      • destination: string

        The destination Stop ID.

        -
      • startTime: number

        The start of the departure window.

        -
      • range: number

        The duration of the window to search (e.g. 3600s).

        -

      Returns Journey[]

      A deduplicated list of the best journeys found in the time range.

      -
    • Executes the McRAPTOR algorithm to find all non-dominated paths to the destination.

      -

      Parameters

      • origin: string

        The starting Stop ID.

        -
      • destination: string

        The destination Stop ID.

        -
      • departureTime: number

        The time of departure.

        -

      Returns Bag

      A Bag containing Pareto-optimal labels for the destination.

      -
    • Sets the penalty multiplier for walking (default is 1).

      -

      Parameters

      • penalty: number

        The multiplier for walking duration cost.

        -

      Returns void

    diff --git a/docs/classes/raptor_McStructs.Bag.html b/docs/classes/raptor_McStructs.Bag.html deleted file mode 100644 index 7463c61..0000000 --- a/docs/classes/raptor_McStructs.Bag.html +++ /dev/null @@ -1,13 +0,0 @@ -Bag | mbus-backend
    mbus-backend
      Preparing search index...

      A container for Labels at a specific stop that maintains a Pareto frontier. -Only keeps labels that are not dominated by any other label in the bag.

      -
      Index

      Constructors

      Properties

      Methods

      Constructors

      Properties

      labels: Label[] = []

      Methods

      • Attempts to add a label to the bag.

        -

        Parameters

        Returns boolean

        True if the label was added (it was non-dominated), False otherwise.

        -
      • Merges another bag's labels into this one.

        -

        Parameters

        Returns boolean

        True if the merge resulted in any changes to this bag.

        -
      diff --git a/docs/classes/raptor_McStructs.Label.html b/docs/classes/raptor_McStructs.Label.html deleted file mode 100644 index ca4ff9f..0000000 --- a/docs/classes/raptor_McStructs.Label.html +++ /dev/null @@ -1,36 +0,0 @@ -Label | mbus-backend
      mbus-backend
        Preparing search index...

        Represents a state or arrival at a specific stop in the routing graph. -Used to trace back the path and store performance metrics.

        -
        Index

        Constructors

        • Parameters

          • arrivalTime: number

            Time of arrival at this stop.

            -
          • walkingDistance: number

            Cumulative walking distance in meters.

            -
          • transferCount: number

            Number of transfers taken so far.

            -
          • parent: Label | null = null

            The previous label in the chain (used for backtracking).

            -
          • trip: Trip | null = null

            The trip taken to reach this state (if applicable).

            -
          • transfer: Transfer | null = null

            The transfer used to reach this state (if applicable).

            -
          • stop: string | null = null

            The ID of the current stop.

            -
          • enterTime: number = 0

            Time when the passenger boarded the vehicle.

            -
          • stopIndex: number = -1

            Index of the current stop in the trip's sequence.

            -

          Returns Label

        Properties

        arrivalTime: number

        Time of arrival at this stop.

        -
        enterTime: number = 0

        Time when the passenger boarded the vehicle.

        -
        parent: Label | null = null

        The previous label in the chain (used for backtracking).

        -
        stop: string | null = null

        The ID of the current stop.

        -
        stopIndex: number = -1

        Index of the current stop in the trip's sequence.

        -
        transfer: Transfer | null = null

        The transfer used to reach this state (if applicable).

        -
        transferCount: number

        Number of transfers taken so far.

        -
        trip: Trip | null = null

        The trip taken to reach this state (if applicable).

        -
        walkingDistance: number

        Cumulative walking distance in meters.

        -

        Methods

        • Determines if this label is strictly better than another label. -A label dominates if it is better or equal in all criteria and strictly better in at least one.

          -

          Parameters

          Returns boolean

        diff --git a/docs/functions/jobs.startBackgroundJobs.html b/docs/functions/jobs.startBackgroundJobs.html deleted file mode 100644 index 2eed3bd..0000000 --- a/docs/functions/jobs.startBackgroundJobs.html +++ /dev/null @@ -1,2 +0,0 @@ -startBackgroundJobs | mbus-backend
        mbus-backend
          Preparing search index...

          Function startBackgroundJobs

          • Starts background jobs for updating bus positions, initializing routes, and rebuilding the graph.

            -

            Returns void

          diff --git a/docs/functions/routes_api.activeRemindersForToken.html b/docs/functions/routes_api.activeRemindersForToken.html deleted file mode 100644 index af2db27..0000000 --- a/docs/functions/routes_api.activeRemindersForToken.html +++ /dev/null @@ -1,3 +0,0 @@ -activeRemindersForToken | mbus-backend
          mbus-backend
            Preparing search index...

            Function activeRemindersForToken

            • Parameters

              • req: Request

                Express request, token is path encoded

                -
              • res: Response<{ reminders: ActiveReminderInfo[] }>

                Express response

                -

              Returns void

            diff --git a/docs/functions/routes_api.getAllPredictions.html b/docs/functions/routes_api.getAllPredictions.html deleted file mode 100644 index 8b3990a..0000000 --- a/docs/functions/routes_api.getAllPredictions.html +++ /dev/null @@ -1,5 +0,0 @@ -getAllPredictions | mbus-backend
            mbus-backend
              Preparing search index...

              Function getAllPredictions

              • Returns all active bus predictions grouped by vehicle ID.

                -

                Parameters

                • req: Request

                  Express request

                  -
                • res: Response

                  Express response

                  -

                Returns void

                JSON array of objects, each with vid and stops (predictions).

                -
              diff --git a/docs/functions/routes_api.getAllRideRoutes.html b/docs/functions/routes_api.getAllRideRoutes.html deleted file mode 100644 index 23cfae4..0000000 --- a/docs/functions/routes_api.getAllRideRoutes.html +++ /dev/null @@ -1,5 +0,0 @@ -getAllRideRoutes | mbus-backend
              mbus-backend
                Preparing search index...

                Function getAllRideRoutes

                • Returns all cached ride route patterns.

                  -

                  Parameters

                  • req: Request

                    Express request

                    -
                  • res: Response

                    Express response

                    -

                  Returns void

                  JSON object with routes mapping route IDs to patterns.

                  -
                diff --git a/docs/functions/routes_api.getAllRideStops.html b/docs/functions/routes_api.getAllRideStops.html deleted file mode 100644 index ba9acd2..0000000 --- a/docs/functions/routes_api.getAllRideStops.html +++ /dev/null @@ -1,5 +0,0 @@ -getAllRideStops | mbus-backend
                mbus-backend
                  Preparing search index...

                  Function getAllRideStops

                  • Returns a list of all known stops with their locations.

                    -

                    Parameters

                    • req: Request

                      Express request

                      -
                    • res: Response

                      Express response

                      -

                    Returns void

                    JSON array of stop objects.

                    -
                  diff --git a/docs/functions/routes_api.getAllRoutes.html b/docs/functions/routes_api.getAllRoutes.html deleted file mode 100644 index f764bd9..0000000 --- a/docs/functions/routes_api.getAllRoutes.html +++ /dev/null @@ -1,5 +0,0 @@ -getAllRoutes | mbus-backend
                  mbus-backend
                    Preparing search index...

                    Function getAllRoutes

                    • Returns all cached route patterns.

                      -

                      Parameters

                      • req: Request

                        Express request

                        -
                      • res: Response

                        Express response

                        -

                      Returns void

                      JSON object with routes mapping route IDs to patterns.

                      -
                    diff --git a/docs/functions/routes_api.getAllStops.html b/docs/functions/routes_api.getAllStops.html deleted file mode 100644 index c997411..0000000 --- a/docs/functions/routes_api.getAllStops.html +++ /dev/null @@ -1,5 +0,0 @@ -getAllStops | mbus-backend
                    mbus-backend
                      Preparing search index...

                      Function getAllStops

                      • Returns a list of all known stops with their locations.

                        -

                        Parameters

                        • req: Request

                          Express request

                          -
                        • res: Response

                          Express response

                          -

                        Returns void

                        JSON array of stop objects.

                        -
                      diff --git a/docs/functions/routes_api.getBuildingLocations.html b/docs/functions/routes_api.getBuildingLocations.html deleted file mode 100644 index bd10bd4..0000000 --- a/docs/functions/routes_api.getBuildingLocations.html +++ /dev/null @@ -1,5 +0,0 @@ -getBuildingLocations | mbus-backend
                      mbus-backend
                        Preparing search index...

                        Function getBuildingLocations

                        • Serves the building locations JSON file.

                          -

                          Parameters

                          • req: Request

                            Express request

                            -
                          • res: Response

                            Express response

                            -

                          Returns void

                          JSON file containing building data.

                          -
                        diff --git a/docs/functions/routes_api.getBusPositions.html b/docs/functions/routes_api.getBusPositions.html deleted file mode 100644 index 4f304a7..0000000 --- a/docs/functions/routes_api.getBusPositions.html +++ /dev/null @@ -1,5 +0,0 @@ -getBusPositions | mbus-backend
                        mbus-backend
                          Preparing search index...

                          Function getBusPositions

                          • Returns current positions of all michgan buses.

                            -

                            Parameters

                            • req: Request

                              Express request

                              -
                            • res: Response

                              Express response

                              -

                            Returns void

                            JSON object with buses array.

                            -
                          diff --git a/docs/functions/routes_api.getBusPredictions.html b/docs/functions/routes_api.getBusPredictions.html deleted file mode 100644 index 8e85c0b..0000000 --- a/docs/functions/routes_api.getBusPredictions.html +++ /dev/null @@ -1,5 +0,0 @@ -getBusPredictions | mbus-backend
                          mbus-backend
                            Preparing search index...

                            Function getBusPredictions

                            • Returns predictions for a specific bus ID.

                              -

                              Parameters

                              • req: Request

                                Express request

                                -
                              • res: Response

                                Express response

                                -

                              Returns void

                              JSON object with bustime-response containing prd (predictions).

                              -
                            diff --git a/docs/functions/routes_api.getBusPredictionsLegacy.html b/docs/functions/routes_api.getBusPredictionsLegacy.html deleted file mode 100644 index bb8f4b8..0000000 --- a/docs/functions/routes_api.getBusPredictionsLegacy.html +++ /dev/null @@ -1,4 +0,0 @@ -getBusPredictionsLegacy | mbus-backend
                            mbus-backend
                              Preparing search index...

                              Function getBusPredictionsLegacy

                              • Legacy/test endpoint for bus predictions.

                                -

                                Parameters

                                • req: Request

                                  Express request

                                  -
                                • res: Response

                                  Express response

                                  -

                                Returns void

                              diff --git a/docs/functions/routes_api.getFrontendData.html b/docs/functions/routes_api.getFrontendData.html deleted file mode 100644 index cd99eab..0000000 --- a/docs/functions/routes_api.getFrontendData.html +++ /dev/null @@ -1,5 +0,0 @@ -getFrontendData | mbus-backend
                              mbus-backend
                                Preparing search index...

                                Function getFrontendData

                                • Returns aggregated data for the frontend, including route configs and metadata.

                                  -

                                  Parameters

                                  • req: Request

                                    Express request

                                    -
                                  • res: Response

                                    Express response

                                    -

                                  Returns void

                                  JSON object with routes (array of route details) and metadata.

                                  -
                                diff --git a/docs/functions/routes_api.getKeyStops.html b/docs/functions/routes_api.getKeyStops.html deleted file mode 100644 index 0aaba13..0000000 --- a/docs/functions/routes_api.getKeyStops.html +++ /dev/null @@ -1,5 +0,0 @@ -getKeyStops | mbus-backend
                                mbus-backend
                                  Preparing search index...

                                  Function getKeyStops

                                  • Returns key stops.

                                    -

                                    Parameters

                                    • req: Request

                                      Express request

                                      -
                                    • res: Response

                                      Express response

                                      -

                                    Returns void

                                    JSON object with message details.

                                    -
                                  diff --git a/docs/functions/routes_api.getNearestStops.html b/docs/functions/routes_api.getNearestStops.html deleted file mode 100644 index e360e8b..0000000 --- a/docs/functions/routes_api.getNearestStops.html +++ /dev/null @@ -1,5 +0,0 @@ -getNearestStops | mbus-backend
                                  mbus-backend
                                    Preparing search index...

                                    Function getNearestStops

                                    • Returns the nearest k stops to a given latitude and longitude.

                                      -

                                      Parameters

                                      • req: Request

                                        Express request

                                        -
                                      • res: Response

                                        Express response

                                        -

                                      Returns void

                                      JSON object with nearestStops array.

                                      -
                                    diff --git a/docs/functions/routes_api.getRidePositions.html b/docs/functions/routes_api.getRidePositions.html deleted file mode 100644 index 9c4abad..0000000 --- a/docs/functions/routes_api.getRidePositions.html +++ /dev/null @@ -1,5 +0,0 @@ -getRidePositions | mbus-backend
                                    mbus-backend
                                      Preparing search index...

                                      Function getRidePositions

                                      • returns positions of all ride busses

                                        -

                                        Parameters

                                        • req: Request

                                          Express request

                                          -
                                        • res: Response

                                          Express response

                                          -

                                        Returns void

                                        JSON object with buses array.

                                        -
                                      diff --git a/docs/functions/routes_api.getRidePredictions.html b/docs/functions/routes_api.getRidePredictions.html deleted file mode 100644 index a91929a..0000000 --- a/docs/functions/routes_api.getRidePredictions.html +++ /dev/null @@ -1,5 +0,0 @@ -getRidePredictions | mbus-backend
                                      mbus-backend
                                        Preparing search index...

                                        Function getRidePredictions

                                        • Returns predictions for a specific ride bus ID.

                                          -

                                          Parameters

                                          • req: Request

                                            Express request

                                            -
                                          • res: Response

                                            Express response

                                            -

                                          Returns void

                                          JSON object with bustime-response containing prd (predictions).

                                          -
                                        diff --git a/docs/functions/routes_api.getRideStopPredictions.html b/docs/functions/routes_api.getRideStopPredictions.html deleted file mode 100644 index ca779c0..0000000 --- a/docs/functions/routes_api.getRideStopPredictions.html +++ /dev/null @@ -1,5 +0,0 @@ -getRideStopPredictions | mbus-backend
                                        mbus-backend
                                          Preparing search index...

                                          Function getRideStopPredictions

                                          • Returns predictions for a specific ride stop ID.

                                            -

                                            Parameters

                                            • req: Request

                                              Express request

                                              -
                                            • res: Response

                                              Express response

                                              -

                                            Returns void

                                            JSON object with bustime-response containing prd (predictions).

                                            -
                                          diff --git a/docs/functions/routes_api.getRouteCache.html b/docs/functions/routes_api.getRouteCache.html deleted file mode 100644 index 5e3222b..0000000 --- a/docs/functions/routes_api.getRouteCache.html +++ /dev/null @@ -1,5 +0,0 @@ -getRouteCache | mbus-backend
                                          mbus-backend
                                            Preparing search index...

                                            Function getRouteCache

                                            • Returns the route timing cache used for extrapolation.

                                              -

                                              Parameters

                                              • req: Request

                                                Express request

                                                -
                                              • res: Response

                                                Express response

                                                -

                                              Returns void

                                              JSON object with routes containing timing data.

                                              -
                                            diff --git a/docs/functions/routes_api.getRouteColor.html b/docs/functions/routes_api.getRouteColor.html deleted file mode 100644 index 2b49c96..0000000 --- a/docs/functions/routes_api.getRouteColor.html +++ /dev/null @@ -1,5 +0,0 @@ -getRouteColor | mbus-backend
                                            mbus-backend
                                              Preparing search index...

                                              Function getRouteColor

                                              • Returns the color and image for a specific route ID.

                                                -

                                                Parameters

                                                • req: Request

                                                  Express request

                                                  -
                                                • res: Response

                                                  Express response

                                                  -

                                                Returns void

                                                JSON object with routeId, color, and image.

                                                -
                                              diff --git a/docs/functions/routes_api.getRouteColors.html b/docs/functions/routes_api.getRouteColors.html deleted file mode 100644 index 25a616d..0000000 --- a/docs/functions/routes_api.getRouteColors.html +++ /dev/null @@ -1,5 +0,0 @@ -getRouteColors | mbus-backend
                                              mbus-backend
                                                Preparing search index...

                                                Function getRouteColors

                                                • Returns configuration (colors and images) for all routes.

                                                  -

                                                  Parameters

                                                  • req: Request

                                                    Express request

                                                    -
                                                  • res: Response

                                                    Express response

                                                    -

                                                  Returns void

                                                  JSON object with a routes array containing route configs.

                                                  -
                                                diff --git a/docs/functions/routes_api.getRouteInfoVersion.html b/docs/functions/routes_api.getRouteInfoVersion.html deleted file mode 100644 index 5623b6d..0000000 --- a/docs/functions/routes_api.getRouteInfoVersion.html +++ /dev/null @@ -1,5 +0,0 @@ -getRouteInfoVersion | mbus-backend
                                                mbus-backend
                                                  Preparing search index...

                                                  Function getRouteInfoVersion

                                                  • Returns the current version of the route information.

                                                    -

                                                    Parameters

                                                    • req: Request

                                                      Express request

                                                      -
                                                    • res: Response

                                                      Express response

                                                      -

                                                    Returns void

                                                    JSON object with the version string.

                                                    -
                                                  diff --git a/docs/functions/routes_api.getRouteInformation.html b/docs/functions/routes_api.getRouteInformation.html deleted file mode 100644 index a583c28..0000000 --- a/docs/functions/routes_api.getRouteInformation.html +++ /dev/null @@ -1,5 +0,0 @@ -getRouteInformation | mbus-backend
                                                  mbus-backend
                                                    Preparing search index...

                                                    Function getRouteInformation

                                                    • Returns static route metadata including names, images, and colors.

                                                      -

                                                      Parameters

                                                      • req: Request

                                                        Express request

                                                        -
                                                      • res: Response

                                                        Express response

                                                        -

                                                      Returns void

                                                      JSON object containing routeIdToName, routeImages, metadata, and routeColors.

                                                      -
                                                    diff --git a/docs/functions/routes_api.getSelectableRoutes.html b/docs/functions/routes_api.getSelectableRoutes.html deleted file mode 100644 index 253334e..0000000 --- a/docs/functions/routes_api.getSelectableRoutes.html +++ /dev/null @@ -1,5 +0,0 @@ -getSelectableRoutes | mbus-backend
                                                    mbus-backend
                                                      Preparing search index...

                                                      Function getSelectableRoutes

                                                      • Returns a list of all selectable routes with their names and colors.

                                                        -

                                                        Parameters

                                                        • req: Request

                                                          Express request

                                                          -
                                                        • res: Response

                                                          Express response

                                                          -

                                                        Returns void

                                                        JSON object with a bustime-response containing a list of routes.

                                                        -
                                                      diff --git a/docs/functions/routes_api.getStartupInfo.html b/docs/functions/routes_api.getStartupInfo.html deleted file mode 100644 index 5a12518..0000000 --- a/docs/functions/routes_api.getStartupInfo.html +++ /dev/null @@ -1,5 +0,0 @@ -getStartupInfo | mbus-backend
                                                      mbus-backend
                                                        Preparing search index...

                                                        Function getStartupInfo

                                                        • Returns startup configuration info including supported versions and messages.

                                                          -

                                                          Parameters

                                                          • req: Request

                                                            Express request

                                                            -
                                                          • res: Response

                                                            Express response

                                                            -

                                                          Returns void

                                                          JSON object with version info and messages.

                                                          -
                                                        diff --git a/docs/functions/routes_api.getStartupMessages.html b/docs/functions/routes_api.getStartupMessages.html deleted file mode 100644 index df88d25..0000000 --- a/docs/functions/routes_api.getStartupMessages.html +++ /dev/null @@ -1,5 +0,0 @@ -getStartupMessages | mbus-backend
                                                        mbus-backend
                                                          Preparing search index...

                                                          Function getStartupMessages

                                                          • Returns special startup messages (e.g., holiday greetings).

                                                            -

                                                            Parameters

                                                            • req: Request

                                                              Express request

                                                              -
                                                            • res: Response

                                                              Express response

                                                              -

                                                            Returns void

                                                            JSON object with message details.

                                                            -
                                                          diff --git a/docs/functions/routes_api.getStopPredictions.html b/docs/functions/routes_api.getStopPredictions.html deleted file mode 100644 index ff7f2ec..0000000 --- a/docs/functions/routes_api.getStopPredictions.html +++ /dev/null @@ -1,5 +0,0 @@ -getStopPredictions | mbus-backend
                                                          mbus-backend
                                                            Preparing search index...

                                                            Function getStopPredictions

                                                            • Returns predictions for a specific stop ID.

                                                              -

                                                              Parameters

                                                              • req: Request

                                                                Express request

                                                                -
                                                              • res: Response

                                                                Express response

                                                                -

                                                              Returns void

                                                              JSON object with bustime-response containing prd (predictions).

                                                              -
                                                            diff --git a/docs/functions/routes_api.getVehicleImage.html b/docs/functions/routes_api.getVehicleImage.html deleted file mode 100644 index d7d2c1c..0000000 --- a/docs/functions/routes_api.getVehicleImage.html +++ /dev/null @@ -1,5 +0,0 @@ -getVehicleImage | mbus-backend
                                                            mbus-backend
                                                              Preparing search index...

                                                              Function getVehicleImage

                                                              • Serves the image file for a specific route.

                                                                -

                                                                Parameters

                                                                • req: Request

                                                                  Express request

                                                                  -
                                                                • res: Response

                                                                  Express response

                                                                  -

                                                                Returns void

                                                                Image file (PNG).

                                                                -
                                                              diff --git a/docs/functions/routes_api.getVehiclePositions.html b/docs/functions/routes_api.getVehiclePositions.html deleted file mode 100644 index bb3d311..0000000 --- a/docs/functions/routes_api.getVehiclePositions.html +++ /dev/null @@ -1,5 +0,0 @@ -getVehiclePositions | mbus-backend
                                                              mbus-backend
                                                                Preparing search index...

                                                                Function getVehiclePositions

                                                                • Alias for getBusPositions.

                                                                  -

                                                                  Parameters

                                                                  • req: Request

                                                                    Express request

                                                                    -
                                                                  • res: Response

                                                                    Express response

                                                                    -

                                                                  Returns void

                                                                  JSON object with buses array.

                                                                  -
                                                                diff --git a/docs/functions/routes_api.modifyReminders.html b/docs/functions/routes_api.modifyReminders.html deleted file mode 100644 index 7d03dcd..0000000 --- a/docs/functions/routes_api.modifyReminders.html +++ /dev/null @@ -1,4 +0,0 @@ -modifyReminders | mbus-backend
                                                                mbus-backend
                                                                  Preparing search index...

                                                                  Function modifyReminders

                                                                  • Lets you run the equivalent of several setReminder and unsetReminders in one call

                                                                    -

                                                                    Parameters

                                                                    • req: Request

                                                                      Express request expecting ModifyRemindersBody in body

                                                                      -
                                                                    • res: Response

                                                                      Express response

                                                                      -

                                                                    Returns void

                                                                  diff --git a/docs/functions/routes_api.notifyMeLater.html b/docs/functions/routes_api.notifyMeLater.html deleted file mode 100644 index 7035476..0000000 --- a/docs/functions/routes_api.notifyMeLater.html +++ /dev/null @@ -1 +0,0 @@ -notifyMeLater | mbus-backend
                                                                  mbus-backend
                                                                    Preparing search index...

                                                                    Function notifyMeLater

                                                                    • Parameters

                                                                      • req: Request
                                                                      • res: Response

                                                                      Returns void

                                                                    diff --git a/docs/functions/routes_api.planJourney.html b/docs/functions/routes_api.planJourney.html deleted file mode 100644 index 73be18d..0000000 --- a/docs/functions/routes_api.planJourney.html +++ /dev/null @@ -1,5 +0,0 @@ -planJourney | mbus-backend
                                                                    mbus-backend
                                                                      Preparing search index...

                                                                      Function planJourney

                                                                      • Plans a journey between origin and destination coordinates.

                                                                        -

                                                                        Parameters

                                                                        • req: Request

                                                                          Express request

                                                                          -
                                                                        • res: Response

                                                                          Express response

                                                                          -

                                                                        Returns Promise<void>

                                                                        JSON object with journeys array containing possible routes.

                                                                        -
                                                                      diff --git a/docs/functions/routes_api.saveGraph.html b/docs/functions/routes_api.saveGraph.html deleted file mode 100644 index 2dbfb87..0000000 --- a/docs/functions/routes_api.saveGraph.html +++ /dev/null @@ -1,5 +0,0 @@ -saveGraph | mbus-backend
                                                                      mbus-backend
                                                                        Preparing search index...

                                                                        Function saveGraph

                                                                        • Saves the current graph state to a file (DEV mode only).

                                                                          -

                                                                          Parameters

                                                                          • req: Request

                                                                            Express request

                                                                            -
                                                                          • res: Response

                                                                            Express response

                                                                            -

                                                                          Returns Promise<void>

                                                                          JSON message confirming the save path.

                                                                          -
                                                                        diff --git a/docs/functions/routes_api.setReminder.html b/docs/functions/routes_api.setReminder.html deleted file mode 100644 index 0903168..0000000 --- a/docs/functions/routes_api.setReminder.html +++ /dev/null @@ -1,3 +0,0 @@ -setReminder | mbus-backend
                                                                        mbus-backend
                                                                          Preparing search index...

                                                                          Function setReminder

                                                                          • Parameters

                                                                            • req: Request

                                                                              Express request, expects SetReminderBody in the body

                                                                              -
                                                                            • res: Response

                                                                              Express response, error message as string if error occurs

                                                                              -

                                                                            Returns void

                                                                          diff --git a/docs/functions/routes_api.swapToken.html b/docs/functions/routes_api.swapToken.html deleted file mode 100644 index d624bfc..0000000 --- a/docs/functions/routes_api.swapToken.html +++ /dev/null @@ -1,5 +0,0 @@ -swapToken | mbus-backend
                                                                          mbus-backend
                                                                            Preparing search index...

                                                                            Function swapToken

                                                                            • Parameters

                                                                              • req: Request

                                                                                Express request, SwapTokenBody in the body

                                                                                -
                                                                              • res: Response

                                                                                Express response, error message as string if error occurs

                                                                                -

                                                                                Upon responding with 200, future calls to /setReminder, /unsetReminder, and /activeReminders -will need the new token

                                                                                -

                                                                              Returns void

                                                                            diff --git a/docs/functions/routes_api.unsetReminder.html b/docs/functions/routes_api.unsetReminder.html deleted file mode 100644 index 64bb8e6..0000000 --- a/docs/functions/routes_api.unsetReminder.html +++ /dev/null @@ -1,3 +0,0 @@ -unsetReminder | mbus-backend
                                                                            mbus-backend
                                                                              Preparing search index...

                                                                              Function unsetReminder

                                                                              • Parameters

                                                                                • req: Request

                                                                                  Express request, UnsetReminderBody in the body

                                                                                  -
                                                                                • res: Response

                                                                                  Express response, error message as string if error occurs

                                                                                  -

                                                                                Returns void

                                                                              diff --git a/docs/functions/services_graphBuilder.findNearestStops.html b/docs/functions/services_graphBuilder.findNearestStops.html deleted file mode 100644 index 845e914..0000000 --- a/docs/functions/services_graphBuilder.findNearestStops.html +++ /dev/null @@ -1,2 +0,0 @@ -findNearestStops | mbus-backend
                                                                              mbus-backend
                                                                                Preparing search index...

                                                                                Function findNearestStops

                                                                                • Finds the nearest k stops to a given coordinate.

                                                                                  -

                                                                                  Parameters

                                                                                  • lat: number
                                                                                  • lon: number
                                                                                  • k: number = 2

                                                                                  Returns { distance: number; lat: number; lon: number; name: string; stpid: string }[]

                                                                                diff --git a/docs/functions/services_graphBuilder.initializeRoutes.html b/docs/functions/services_graphBuilder.initializeRoutes.html deleted file mode 100644 index 0be282b..0000000 --- a/docs/functions/services_graphBuilder.initializeRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -initializeRoutes | mbus-backend
                                                                                mbus-backend
                                                                                  Preparing search index...

                                                                                  Function initializeRoutes

                                                                                  • Initializes route data, caching patterns and stop locations.

                                                                                    -

                                                                                    Returns Promise<void>

                                                                                  diff --git a/docs/functions/services_graphBuilder.rebuildGraph.html b/docs/functions/services_graphBuilder.rebuildGraph.html deleted file mode 100644 index eef8bcb..0000000 --- a/docs/functions/services_graphBuilder.rebuildGraph.html +++ /dev/null @@ -1,2 +0,0 @@ -rebuildGraph | mbus-backend
                                                                                  mbus-backend
                                                                                    Preparing search index...
                                                                                    • Rebuilds the routing graph based on current predictions and static data.

                                                                                      -

                                                                                      Returns Promise<void>

                                                                                    diff --git a/docs/functions/services_graphBuilder.saveGraphState.html b/docs/functions/services_graphBuilder.saveGraphState.html deleted file mode 100644 index 36d84c0..0000000 --- a/docs/functions/services_graphBuilder.saveGraphState.html +++ /dev/null @@ -1,2 +0,0 @@ -saveGraphState | mbus-backend
                                                                                    mbus-backend
                                                                                      Preparing search index...
                                                                                      • Saves the current graph and state to a JSON file (DEV mode only).

                                                                                        -

                                                                                        Returns string

                                                                                      diff --git a/docs/functions/services_graphBuilder.sortPreds.html b/docs/functions/services_graphBuilder.sortPreds.html deleted file mode 100644 index d9e28f5..0000000 --- a/docs/functions/services_graphBuilder.sortPreds.html +++ /dev/null @@ -1,2 +0,0 @@ -sortPreds | mbus-backend
                                                                                      mbus-backend
                                                                                        Preparing search index...
                                                                                        diff --git a/docs/functions/services_graphBuilder.updateBusPositions.html b/docs/functions/services_graphBuilder.updateBusPositions.html deleted file mode 100644 index 914fac7..0000000 --- a/docs/functions/services_graphBuilder.updateBusPositions.html +++ /dev/null @@ -1,2 +0,0 @@ -updateBusPositions | mbus-backend
                                                                                        mbus-backend
                                                                                          Preparing search index...

                                                                                          Function updateBusPositions

                                                                                          • Fetches and updates current bus positions in state.

                                                                                            -

                                                                                            Returns Promise<void>

                                                                                          diff --git a/docs/functions/services_journey.planJourney.html b/docs/functions/services_journey.planJourney.html deleted file mode 100644 index c3c51ec..0000000 --- a/docs/functions/services_journey.planJourney.html +++ /dev/null @@ -1,8 +0,0 @@ -planJourney | mbus-backend
                                                                                          mbus-backend
                                                                                            Preparing search index...

                                                                                            Function planJourney

                                                                                            • Plans a journey between two coordinates using the McRaptor algorithm.

                                                                                              -

                                                                                              Parameters

                                                                                              • oLat: number

                                                                                                Origin latitude

                                                                                                -
                                                                                              • oLon: number

                                                                                                Origin longitude

                                                                                                -
                                                                                              • dLat: number

                                                                                                Destination latitude

                                                                                                -
                                                                                              • dLon: number

                                                                                                Destination longitude

                                                                                                -
                                                                                              • time: number

                                                                                                Start time in seconds since midnight

                                                                                                -
                                                                                              • options: { range?: number; walkingPenalty?: number }

                                                                                                Optional parameters for walking penalty and search range

                                                                                                -

                                                                                              Returns Promise<
                                                                                                  (
                                                                                                      | {
                                                                                                          arrivalTime: number;
                                                                                                          criteria: {
                                                                                                              arrivalTime: number;
                                                                                                              transferCount: number;
                                                                                                              walkingDistance: number;
                                                                                                          };
                                                                                                          departureTime: number;
                                                                                                          legs: any[];
                                                                                                      }
                                                                                                      | null
                                                                                                  )[],
                                                                                              >

                                                                                            diff --git a/docs/functions/services_mbus.fetchPatterns.html b/docs/functions/services_mbus.fetchPatterns.html deleted file mode 100644 index 3d27eac..0000000 --- a/docs/functions/services_mbus.fetchPatterns.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchPatterns | mbus-backend
                                                                                            mbus-backend
                                                                                              Preparing search index...

                                                                                              Function fetchPatterns

                                                                                              • Fetches route patterns (path points) for a specific route.

                                                                                                -

                                                                                                Parameters

                                                                                                • rt: string

                                                                                                Returns Promise<any>

                                                                                              diff --git a/docs/functions/services_mbus.fetchPredictions.html b/docs/functions/services_mbus.fetchPredictions.html deleted file mode 100644 index b8b7d84..0000000 --- a/docs/functions/services_mbus.fetchPredictions.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchPredictions | mbus-backend
                                                                                              mbus-backend
                                                                                                Preparing search index...

                                                                                                Function fetchPredictions

                                                                                                • Fetches predictions for multiple stop IDs.

                                                                                                  -

                                                                                                  Parameters

                                                                                                  • stopIds: string[]
                                                                                                  • routes: string[]

                                                                                                  Returns Promise<any[]>

                                                                                                diff --git a/docs/functions/services_mbus.fetchRoutes.html b/docs/functions/services_mbus.fetchRoutes.html deleted file mode 100644 index 3a62cea..0000000 --- a/docs/functions/services_mbus.fetchRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchRoutes | mbus-backend
                                                                                                mbus-backend
                                                                                                  Preparing search index...

                                                                                                  Function fetchRoutes

                                                                                                  • Fetches all available routes.

                                                                                                    -

                                                                                                    Returns Promise<any>

                                                                                                  diff --git a/docs/functions/services_mbus.fetchVehicles.html b/docs/functions/services_mbus.fetchVehicles.html deleted file mode 100644 index 9bd7543..0000000 --- a/docs/functions/services_mbus.fetchVehicles.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchVehicles | mbus-backend
                                                                                                  mbus-backend
                                                                                                    Preparing search index...

                                                                                                    Function fetchVehicles

                                                                                                    • Fetches vehicle positions for the given routes.

                                                                                                      -

                                                                                                      Parameters

                                                                                                      • routes: string[]

                                                                                                      Returns Promise<any[]>

                                                                                                    diff --git a/docs/functions/services_metadata.getAllRouteConfig.html b/docs/functions/services_metadata.getAllRouteConfig.html deleted file mode 100644 index 68c8d0c..0000000 --- a/docs/functions/services_metadata.getAllRouteConfig.html +++ /dev/null @@ -1,2 +0,0 @@ -getAllRouteConfig | mbus-backend
                                                                                                    mbus-backend
                                                                                                      Preparing search index...

                                                                                                      Function getAllRouteConfig

                                                                                                      • Returns configuration for all routes.

                                                                                                        -

                                                                                                        Returns { color: string; image: string; routeId: string }[]

                                                                                                      diff --git a/docs/functions/services_metadata.getRouteColor.html b/docs/functions/services_metadata.getRouteColor.html deleted file mode 100644 index 4a6765a..0000000 --- a/docs/functions/services_metadata.getRouteColor.html +++ /dev/null @@ -1,2 +0,0 @@ -getRouteColor | mbus-backend
                                                                                                      mbus-backend
                                                                                                        Preparing search index...

                                                                                                        Function getRouteColor

                                                                                                        • Gets the color for a specific route ID.

                                                                                                          -

                                                                                                          Parameters

                                                                                                          • routeId: string

                                                                                                          Returns string | null

                                                                                                        diff --git a/docs/functions/services_metadata.getRouteImage.html b/docs/functions/services_metadata.getRouteImage.html deleted file mode 100644 index 1bfc935..0000000 --- a/docs/functions/services_metadata.getRouteImage.html +++ /dev/null @@ -1,2 +0,0 @@ -getRouteImage | mbus-backend
                                                                                                        mbus-backend
                                                                                                          Preparing search index...

                                                                                                          Function getRouteImage

                                                                                                          • Gets the image filename for a specific route ID.

                                                                                                            -

                                                                                                            Parameters

                                                                                                            • routeId: string

                                                                                                            Returns string | null

                                                                                                          diff --git a/docs/functions/services_reminder.eventsEqual.html b/docs/functions/services_reminder.eventsEqual.html deleted file mode 100644 index 0f538f6..0000000 --- a/docs/functions/services_reminder.eventsEqual.html +++ /dev/null @@ -1 +0,0 @@ -eventsEqual | mbus-backend
                                                                                                          mbus-backend
                                                                                                            Preparing search index...

                                                                                                            Function eventsEqual

                                                                                                            diff --git a/docs/functions/services_reminder.infoToUseForRoute.html b/docs/functions/services_reminder.infoToUseForRoute.html deleted file mode 100644 index 6677cfb..0000000 --- a/docs/functions/services_reminder.infoToUseForRoute.html +++ /dev/null @@ -1 +0,0 @@ -infoToUseForRoute | mbus-backend
                                                                                                            mbus-backend
                                                                                                              Preparing search index...

                                                                                                              Function infoToUseForRoute

                                                                                                              • Parameters

                                                                                                                • rtid: string

                                                                                                                Returns
                                                                                                                    | {
                                                                                                                        predsByStopId: Record<string, Prediction[]>;
                                                                                                                        predsByVid: Record<string, Prediction[]>;
                                                                                                                        reminderSubscriptions: ReminderSubscriptions;
                                                                                                                    }
                                                                                                                    | null

                                                                                                              diff --git a/docs/functions/services_reminder.processRideReminders.html b/docs/functions/services_reminder.processRideReminders.html deleted file mode 100644 index 562319d..0000000 --- a/docs/functions/services_reminder.processRideReminders.html +++ /dev/null @@ -1 +0,0 @@ -processRideReminders | mbus-backend
                                                                                                              mbus-backend
                                                                                                                Preparing search index...

                                                                                                                Function processRideReminders

                                                                                                                diff --git a/docs/functions/services_reminder.processUniversityReminders.html b/docs/functions/services_reminder.processUniversityReminders.html deleted file mode 100644 index 01b0549..0000000 --- a/docs/functions/services_reminder.processUniversityReminders.html +++ /dev/null @@ -1 +0,0 @@ -processUniversityReminders | mbus-backend
                                                                                                                mbus-backend
                                                                                                                  Preparing search index...

                                                                                                                  Function processUniversityReminders

                                                                                                                  diff --git a/docs/functions/services_reminder.sendNotifToAll.html b/docs/functions/services_reminder.sendNotifToAll.html deleted file mode 100644 index 6b6f2e0..0000000 --- a/docs/functions/services_reminder.sendNotifToAll.html +++ /dev/null @@ -1 +0,0 @@ -sendNotifToAll | mbus-backend
                                                                                                                  mbus-backend
                                                                                                                    Preparing search index...

                                                                                                                    Function sendNotifToAll

                                                                                                                    • Parameters

                                                                                                                      • notif: { body: string; title: string }
                                                                                                                      • tokens: Set<string>

                                                                                                                      Returns void

                                                                                                                    diff --git a/docs/functions/services_reminderTypes.baseEvent.html b/docs/functions/services_reminderTypes.baseEvent.html deleted file mode 100644 index ad93406..0000000 --- a/docs/functions/services_reminderTypes.baseEvent.html +++ /dev/null @@ -1,2 +0,0 @@ -baseEvent | mbus-backend
                                                                                                                    mbus-backend
                                                                                                                      Preparing search index...
                                                                                                                      diff --git a/docs/functions/services_reminderTypes.delayEvent.html b/docs/functions/services_reminderTypes.delayEvent.html deleted file mode 100644 index 1207c39..0000000 --- a/docs/functions/services_reminderTypes.delayEvent.html +++ /dev/null @@ -1,2 +0,0 @@ -delayEvent | mbus-backend
                                                                                                                      mbus-backend
                                                                                                                        Preparing search index...
                                                                                                                        • factory

                                                                                                                          -

                                                                                                                          Parameters

                                                                                                                          • x: { currPred: number; prevPred: number; rtid: string; stpid: string }

                                                                                                                          Returns DelayEvent

                                                                                                                        diff --git a/docs/functions/services_reminderTypes.eventsEqual.html b/docs/functions/services_reminderTypes.eventsEqual.html deleted file mode 100644 index 83d0898..0000000 --- a/docs/functions/services_reminderTypes.eventsEqual.html +++ /dev/null @@ -1 +0,0 @@ -eventsEqual | mbus-backend
                                                                                                                        mbus-backend
                                                                                                                          Preparing search index...
                                                                                                                          diff --git a/docs/functions/services_reminderTypes.fromKey.html b/docs/functions/services_reminderTypes.fromKey.html deleted file mode 100644 index 426b120..0000000 --- a/docs/functions/services_reminderTypes.fromKey.html +++ /dev/null @@ -1 +0,0 @@ -fromKey | mbus-backend
                                                                                                                          mbus-backend
                                                                                                                            Preparing search index...
                                                                                                                            diff --git a/docs/functions/services_reminderTypes.registrationToken.html b/docs/functions/services_reminderTypes.registrationToken.html deleted file mode 100644 index a884ca7..0000000 --- a/docs/functions/services_reminderTypes.registrationToken.html +++ /dev/null @@ -1 +0,0 @@ -registrationToken | mbus-backend
                                                                                                                            mbus-backend
                                                                                                                              Preparing search index...

                                                                                                                              Function registrationToken

                                                                                                                              diff --git a/docs/functions/services_reminderTypes.sameBaseEvent.html b/docs/functions/services_reminderTypes.sameBaseEvent.html deleted file mode 100644 index b6a0765..0000000 --- a/docs/functions/services_reminderTypes.sameBaseEvent.html +++ /dev/null @@ -1 +0,0 @@ -sameBaseEvent | mbus-backend
                                                                                                                              mbus-backend
                                                                                                                                Preparing search index...
                                                                                                                                • Parameters

                                                                                                                                  • e1: CoreEvent
                                                                                                                                  • e2: CoreEvent

                                                                                                                                  Returns boolean

                                                                                                                                diff --git a/docs/functions/services_reminderTypes.thresholdEvent.html b/docs/functions/services_reminderTypes.thresholdEvent.html deleted file mode 100644 index af4ff72..0000000 --- a/docs/functions/services_reminderTypes.thresholdEvent.html +++ /dev/null @@ -1,2 +0,0 @@ -thresholdEvent | mbus-backend
                                                                                                                                mbus-backend
                                                                                                                                  Preparing search index...
                                                                                                                                  diff --git a/docs/functions/services_reminderTypes.toKey.html b/docs/functions/services_reminderTypes.toKey.html deleted file mode 100644 index bcbf4ea..0000000 --- a/docs/functions/services_reminderTypes.toKey.html +++ /dev/null @@ -1,2 +0,0 @@ -toKey | mbus-backend
                                                                                                                                  mbus-backend
                                                                                                                                    Preparing search index...
                                                                                                                                    diff --git a/docs/functions/services_ride.fetchPatterns.html b/docs/functions/services_ride.fetchPatterns.html deleted file mode 100644 index 6850074..0000000 --- a/docs/functions/services_ride.fetchPatterns.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchPatterns | mbus-backend
                                                                                                                                    mbus-backend
                                                                                                                                      Preparing search index...

                                                                                                                                      Function fetchPatterns

                                                                                                                                      • Fetches route patterns (path points) for a specific route.

                                                                                                                                        -

                                                                                                                                        Parameters

                                                                                                                                        • rt: string

                                                                                                                                        Returns Promise<any>

                                                                                                                                      diff --git a/docs/functions/services_ride.fetchPredictions.html b/docs/functions/services_ride.fetchPredictions.html deleted file mode 100644 index 32d4c42..0000000 --- a/docs/functions/services_ride.fetchPredictions.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchPredictions | mbus-backend
                                                                                                                                      mbus-backend
                                                                                                                                        Preparing search index...

                                                                                                                                        Function fetchPredictions

                                                                                                                                        • Fetches predictions for multiple stop IDs.

                                                                                                                                          -

                                                                                                                                          Parameters

                                                                                                                                          • stopIds: string[]
                                                                                                                                          • routes: string[]

                                                                                                                                          Returns Promise<any[]>

                                                                                                                                        diff --git a/docs/functions/services_ride.fetchRoutes.html b/docs/functions/services_ride.fetchRoutes.html deleted file mode 100644 index 21a65e6..0000000 --- a/docs/functions/services_ride.fetchRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchRoutes | mbus-backend
                                                                                                                                        mbus-backend
                                                                                                                                          Preparing search index...

                                                                                                                                          Function fetchRoutes

                                                                                                                                          • Fetches all available routes.

                                                                                                                                            -

                                                                                                                                            Returns Promise<any>

                                                                                                                                          diff --git a/docs/functions/services_ride.fetchVehicles.html b/docs/functions/services_ride.fetchVehicles.html deleted file mode 100644 index 3dd3a95..0000000 --- a/docs/functions/services_ride.fetchVehicles.html +++ /dev/null @@ -1,2 +0,0 @@ -fetchVehicles | mbus-backend
                                                                                                                                          mbus-backend
                                                                                                                                            Preparing search index...

                                                                                                                                            Function fetchVehicles

                                                                                                                                            • Fetches vehicle positions for the given routes.

                                                                                                                                              -

                                                                                                                                              Parameters

                                                                                                                                              • routes: string[]

                                                                                                                                              Returns Promise<any[]>

                                                                                                                                            diff --git a/docs/functions/state_transitState.setCachedGraph.html b/docs/functions/state_transitState.setCachedGraph.html deleted file mode 100644 index 63000ff..0000000 --- a/docs/functions/state_transitState.setCachedGraph.html +++ /dev/null @@ -1,2 +0,0 @@ -setCachedGraph | mbus-backend
                                                                                                                                            mbus-backend
                                                                                                                                              Preparing search index...

                                                                                                                                              Function setCachedGraph

                                                                                                                                              diff --git a/docs/functions/state_transitState.setCachedRideStopLocations.html b/docs/functions/state_transitState.setCachedRideStopLocations.html deleted file mode 100644 index 7331229..0000000 --- a/docs/functions/state_transitState.setCachedRideStopLocations.html +++ /dev/null @@ -1,2 +0,0 @@ -setCachedRideStopLocations | mbus-backend
                                                                                                                                              mbus-backend
                                                                                                                                                Preparing search index...

                                                                                                                                                Function setCachedRideStopLocations

                                                                                                                                                • Updates the cached ride stop locations.

                                                                                                                                                  -

                                                                                                                                                  Parameters

                                                                                                                                                  • newLocs: Record<string, { lat: number; lon: number; name: string }>

                                                                                                                                                  Returns void

                                                                                                                                                diff --git a/docs/functions/state_transitState.setCachedStopLocations.html b/docs/functions/state_transitState.setCachedStopLocations.html deleted file mode 100644 index 9bbf317..0000000 --- a/docs/functions/state_transitState.setCachedStopLocations.html +++ /dev/null @@ -1,2 +0,0 @@ -setCachedStopLocations | mbus-backend
                                                                                                                                                mbus-backend
                                                                                                                                                  Preparing search index...

                                                                                                                                                  Function setCachedStopLocations

                                                                                                                                                  • Updates the cached stop locations.

                                                                                                                                                    -

                                                                                                                                                    Parameters

                                                                                                                                                    • newLocs: Record<string, { lat: number; lon: number; name: string }>

                                                                                                                                                    Returns void

                                                                                                                                                  diff --git a/docs/functions/walking_loadMap.haversine.html b/docs/functions/walking_loadMap.haversine.html deleted file mode 100644 index 79efb48..0000000 --- a/docs/functions/walking_loadMap.haversine.html +++ /dev/null @@ -1,7 +0,0 @@ -haversine | mbus-backend
                                                                                                                                                  mbus-backend
                                                                                                                                                    Preparing search index...

                                                                                                                                                    Function haversine

                                                                                                                                                    • Calculates the great-circle distance between two points using the Haversine formula.

                                                                                                                                                      -

                                                                                                                                                      Parameters

                                                                                                                                                      • aLat: number

                                                                                                                                                        Latitude of point A.

                                                                                                                                                        -
                                                                                                                                                      • aLon: number

                                                                                                                                                        Longitude of point A.

                                                                                                                                                        -
                                                                                                                                                      • bLat: number

                                                                                                                                                        Latitude of point B.

                                                                                                                                                        -
                                                                                                                                                      • bLon: number

                                                                                                                                                        Longitude of point B.

                                                                                                                                                        -

                                                                                                                                                      Returns number

                                                                                                                                                      Distance in meters.

                                                                                                                                                      -
                                                                                                                                                    diff --git a/docs/functions/walking_loadMap.loadMap.html b/docs/functions/walking_loadMap.loadMap.html deleted file mode 100644 index 6618d45..0000000 --- a/docs/functions/walking_loadMap.loadMap.html +++ /dev/null @@ -1,16 +0,0 @@ -loadMap | mbus-backend
                                                                                                                                                    mbus-backend
                                                                                                                                                      Preparing search index...

                                                                                                                                                      Function loadMap

                                                                                                                                                      • Loads and parses the GraphML map file into a usable graph structure.

                                                                                                                                                        -
                                                                                                                                                          -
                                                                                                                                                        • Performs the following steps:
                                                                                                                                                        • -
                                                                                                                                                        -
                                                                                                                                                          -
                                                                                                                                                        1. Reads the XML file.
                                                                                                                                                        2. -
                                                                                                                                                        3. Extracts Nodes (lat/lon).
                                                                                                                                                        4. -
                                                                                                                                                        5. Extracts Edges (filtering for walkable types like 'footway', 'path').
                                                                                                                                                        6. -
                                                                                                                                                        7. Parses edge geometry (WKT) if available.
                                                                                                                                                        8. -
                                                                                                                                                        9. Prunes disconnected components, keeping only the largest connected subgraph.
                                                                                                                                                        10. -
                                                                                                                                                        -
                                                                                                                                                          -
                                                                                                                                                        • -
                                                                                                                                                        -

                                                                                                                                                        Returns { graph: Map<string, GraphMLEdge[]>; nodes: Map<string, GraphMLNode> }

                                                                                                                                                        An object containing the map of Nodes and the Adjacency List (graph).

                                                                                                                                                        -
                                                                                                                                                      diff --git a/docs/functions/walking_walkingMap.buildStopNodeMap.html b/docs/functions/walking_walkingMap.buildStopNodeMap.html deleted file mode 100644 index 10e668b..0000000 --- a/docs/functions/walking_walkingMap.buildStopNodeMap.html +++ /dev/null @@ -1,4 +0,0 @@ -buildStopNodeMap | mbus-backend
                                                                                                                                                      mbus-backend
                                                                                                                                                        Preparing search index...

                                                                                                                                                        Function buildStopNodeMap

                                                                                                                                                        • Maps a list of bus stops to their nearest nodes on the street graph. -This optimizes future lookups by caching the StopID -> NodeID relationship.

                                                                                                                                                          -

                                                                                                                                                          Parameters

                                                                                                                                                          • locations: Record<string, { lat: number; lon: number }>

                                                                                                                                                            A map of StopID to {lat, lon}.

                                                                                                                                                            -

                                                                                                                                                          Returns void

                                                                                                                                                        diff --git a/docs/functions/walking_walkingMap.ensureCacheForStops.html b/docs/functions/walking_walkingMap.ensureCacheForStops.html deleted file mode 100644 index e90fe83..0000000 --- a/docs/functions/walking_walkingMap.ensureCacheForStops.html +++ /dev/null @@ -1,5 +0,0 @@ -ensureCacheForStops | mbus-backend
                                                                                                                                                        mbus-backend
                                                                                                                                                          Preparing search index...

                                                                                                                                                          Function ensureCacheForStops

                                                                                                                                                          • Ensures walking paths between all provided stops are calculated and cached. -Fetches missing paths in parallel and updates the disk cache.

                                                                                                                                                            -

                                                                                                                                                            Parameters

                                                                                                                                                            • stopIds: Set<string>

                                                                                                                                                              Set of stop IDs to verify.

                                                                                                                                                              -
                                                                                                                                                            • stopLocations: Record<string, { lat: number; lon: number }>

                                                                                                                                                              Map of Stop ID to coordinates.

                                                                                                                                                              -

                                                                                                                                                            Returns Promise<void>

                                                                                                                                                          diff --git a/docs/functions/walking_walkingMap.getCachedWalk.html b/docs/functions/walking_walkingMap.getCachedWalk.html deleted file mode 100644 index 65d8590..0000000 --- a/docs/functions/walking_walkingMap.getCachedWalk.html +++ /dev/null @@ -1,5 +0,0 @@ -getCachedWalk | mbus-backend
                                                                                                                                                          mbus-backend
                                                                                                                                                            Preparing search index...

                                                                                                                                                            Function getCachedWalk

                                                                                                                                                            • Retrieves a cached walking path between two stops.

                                                                                                                                                              -

                                                                                                                                                              Parameters

                                                                                                                                                              • originId: string

                                                                                                                                                                Origin Stop ID.

                                                                                                                                                                -
                                                                                                                                                              • destId: string

                                                                                                                                                                Destination Stop ID.

                                                                                                                                                                -

                                                                                                                                                              Returns WalkingResponse | undefined

                                                                                                                                                              Cached walking data or undefined.

                                                                                                                                                              -
                                                                                                                                                            diff --git a/docs/functions/walking_walkingMap.getWalkingDistancesFrom.html b/docs/functions/walking_walkingMap.getWalkingDistancesFrom.html deleted file mode 100644 index 916cc29..0000000 --- a/docs/functions/walking_walkingMap.getWalkingDistancesFrom.html +++ /dev/null @@ -1,8 +0,0 @@ -getWalkingDistancesFrom | mbus-backend
                                                                                                                                                            mbus-backend
                                                                                                                                                              Preparing search index...

                                                                                                                                                              Function getWalkingDistancesFrom

                                                                                                                                                              • Optimized method to get walking distances from an origin to ALL known bus stops. -Optionally includes a direct walk to a specific destination point. -Uses a single Dijkstra pass with early termination and LRU Cache.

                                                                                                                                                                -

                                                                                                                                                                Parameters

                                                                                                                                                                • lat: number

                                                                                                                                                                  Origin latitude.

                                                                                                                                                                  -
                                                                                                                                                                • lon: number

                                                                                                                                                                  Origin longitude.

                                                                                                                                                                  -
                                                                                                                                                                • OptionaldestLat: number

                                                                                                                                                                  (Optional) Destination latitude for direct walk.

                                                                                                                                                                  -
                                                                                                                                                                • OptionaldestLon: number

                                                                                                                                                                  (Optional) Destination longitude for direct walk.

                                                                                                                                                                  -

                                                                                                                                                                Returns { duration: number; stopId: string }[]

                                                                                                                                                              diff --git a/docs/functions/walking_walkingMap.getWalkingResponse.html b/docs/functions/walking_walkingMap.getWalkingResponse.html deleted file mode 100644 index cd96549..0000000 --- a/docs/functions/walking_walkingMap.getWalkingResponse.html +++ /dev/null @@ -1,7 +0,0 @@ -getWalkingResponse | mbus-backend
                                                                                                                                                              mbus-backend
                                                                                                                                                                Preparing search index...

                                                                                                                                                                Function getWalkingResponse

                                                                                                                                                                • Calculates a detailed walking path between two coordinates using A*. -Includes path geometry for rendering.

                                                                                                                                                                  -

                                                                                                                                                                  Parameters

                                                                                                                                                                  • originLat: number

                                                                                                                                                                    Latitude of origin.

                                                                                                                                                                    -
                                                                                                                                                                  • originLon: number

                                                                                                                                                                    Longitude of origin.

                                                                                                                                                                    -
                                                                                                                                                                  • destLat: number

                                                                                                                                                                    Latitude of destination.

                                                                                                                                                                    -
                                                                                                                                                                  • destLon: number

                                                                                                                                                                    Longitude of destination.

                                                                                                                                                                    -

                                                                                                                                                                  Returns Promise<WalkingResponse>

                                                                                                                                                                diff --git a/docs/hierarchy.html b/docs/hierarchy.html deleted file mode 100644 index e83590c..0000000 --- a/docs/hierarchy.html +++ /dev/null @@ -1 +0,0 @@ -mbus-backend
                                                                                                                                                                mbus-backend
                                                                                                                                                                  Preparing search index...

                                                                                                                                                                  mbus-backend

                                                                                                                                                                  Hierarchy Summary

                                                                                                                                                                  diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index e44630e..0000000 --- a/docs/index.html +++ /dev/null @@ -1,39 +0,0 @@ -mbus-backend
                                                                                                                                                                  mbus-backend
                                                                                                                                                                    Preparing search index...

                                                                                                                                                                    mbus-backend

                                                                                                                                                                    - Maizebus Logo -

                                                                                                                                                                    Maizebus Backend

                                                                                                                                                                    -

                                                                                                                                                                    - - Documentation - - License -

                                                                                                                                                                    -

                                                                                                                                                                    - Backend service for the Magic Bus application. Handles real-time bus tracking, route management, and multi-modal journey planning (bus + walking) using the McRaptor algorithm. -

                                                                                                                                                                    -
                                                                                                                                                                    -

                                                                                                                                                                    First, obtain an API key for the Magic Bus backend from the official Magic Bus Website.

                                                                                                                                                                    -

                                                                                                                                                                    Then, define the MBUS_API_KEY environment variable with your API key.

                                                                                                                                                                    -

                                                                                                                                                                    To install dependencies, run npm i

                                                                                                                                                                    -

                                                                                                                                                                    Create a Firebase project if you haven't already, and set FIREBASE_PROJECT_ID to its id. Follow the steps -here to create a service -account key file. Place this file into secrets/ and point GOOGLE_APPLICATION_CREDENTIALS to it. -(you can do this temporarily with export GOOGLE_APPLICATION_CREDENTIALS="./secrets/your-filename.json")

                                                                                                                                                                    -

                                                                                                                                                                    Some additional resources for iOS here. Make -sure that the firebase project is configured with the same app id as xcode.

                                                                                                                                                                    -

                                                                                                                                                                    To run the backend, run npm start.

                                                                                                                                                                    -

                                                                                                                                                                    By default, the service runs on port 3000. To define a port for the service to run on, define an environment variable called PORT before running the backend.

                                                                                                                                                                    -

                                                                                                                                                                    This project uses TSDoc for code documentation. -To compile the static documentation:

                                                                                                                                                                    -
                                                                                                                                                                    npm run docs
                                                                                                                                                                    -
                                                                                                                                                                    - -

                                                                                                                                                                    The documentation is served at http://localhost:3000/docs or this link.

                                                                                                                                                                    -

                                                                                                                                                                    This project uses Vitest for fast unit and integration testing.

                                                                                                                                                                    -
                                                                                                                                                                      -
                                                                                                                                                                    • Run all tests: npm test
                                                                                                                                                                    • -
                                                                                                                                                                    • Run stress tests: npm run stress-test
                                                                                                                                                                    • -
                                                                                                                                                                    -

                                                                                                                                                                    An example of passing the tests is below.

                                                                                                                                                                    -test example -

                                                                                                                                                                    Before submitting a pull request to main, please make sure you pass all the tests and can compile docs. If you believe some of the tests faulty or no longer needed after your commit, please contact Andrew Yu or Ryan Lu on Slack.

                                                                                                                                                                    -
                                                                                                                                                                    diff --git a/docs/interfaces/raptor_McRaptorAlgorithm.Journey.html b/docs/interfaces/raptor_McRaptorAlgorithm.Journey.html deleted file mode 100644 index b0210ca..0000000 --- a/docs/interfaces/raptor_McRaptorAlgorithm.Journey.html +++ /dev/null @@ -1,6 +0,0 @@ -Journey | mbus-backend
                                                                                                                                                                    mbus-backend
                                                                                                                                                                      Preparing search index...

                                                                                                                                                                      Represents a complete transit journey consisting of multiple legs.

                                                                                                                                                                      -
                                                                                                                                                                      interface Journey {
                                                                                                                                                                          criteria: {
                                                                                                                                                                              arrivalTime: number;
                                                                                                                                                                              transferCount: number;
                                                                                                                                                                              walkingDistance: number;
                                                                                                                                                                          };
                                                                                                                                                                          legs: JourneyLeg[];
                                                                                                                                                                      }
                                                                                                                                                                      Index

                                                                                                                                                                      Properties

                                                                                                                                                                      Properties

                                                                                                                                                                      criteria: {
                                                                                                                                                                          arrivalTime: number;
                                                                                                                                                                          transferCount: number;
                                                                                                                                                                          walkingDistance: number;
                                                                                                                                                                      }

                                                                                                                                                                      The performance metrics for this journey.

                                                                                                                                                                      -
                                                                                                                                                                      legs: JourneyLeg[]

                                                                                                                                                                      The sequence of legs (trips or walking transfers) in the journey.

                                                                                                                                                                      -
                                                                                                                                                                      diff --git a/docs/interfaces/raptor_McRaptorAlgorithm.JourneyLeg.html b/docs/interfaces/raptor_McRaptorAlgorithm.JourneyLeg.html deleted file mode 100644 index b6da33e..0000000 --- a/docs/interfaces/raptor_McRaptorAlgorithm.JourneyLeg.html +++ /dev/null @@ -1,14 +0,0 @@ -JourneyLeg | mbus-backend
                                                                                                                                                                      mbus-backend
                                                                                                                                                                        Preparing search index...

                                                                                                                                                                        Represents a single segment of a journey, either a transit trip or a walking transfer.

                                                                                                                                                                        -
                                                                                                                                                                        interface JourneyLeg {
                                                                                                                                                                            destination: string;
                                                                                                                                                                            destinationID: string;
                                                                                                                                                                            duration: number;
                                                                                                                                                                            endTime: number;
                                                                                                                                                                            origin: string;
                                                                                                                                                                            originID: string;
                                                                                                                                                                            rt?: string;
                                                                                                                                                                            startTime: number;
                                                                                                                                                                            stopTimes?: StopTime[];
                                                                                                                                                                            transfer?: Transfer;
                                                                                                                                                                            trip?: Trip;
                                                                                                                                                                            type: "Trip" | "Transfer";
                                                                                                                                                                        }
                                                                                                                                                                        Index

                                                                                                                                                                        Properties

                                                                                                                                                                        destination: string
                                                                                                                                                                        destinationID: string
                                                                                                                                                                        duration: number
                                                                                                                                                                        endTime: number
                                                                                                                                                                        origin: string
                                                                                                                                                                        originID: string
                                                                                                                                                                        rt?: string
                                                                                                                                                                        startTime: number
                                                                                                                                                                        stopTimes?: StopTime[]
                                                                                                                                                                        transfer?: Transfer
                                                                                                                                                                        trip?: Trip
                                                                                                                                                                        type: "Trip" | "Transfer"
                                                                                                                                                                        diff --git a/docs/interfaces/raptor_types.Leg.html b/docs/interfaces/raptor_types.Leg.html deleted file mode 100644 index e209caf..0000000 --- a/docs/interfaces/raptor_types.Leg.html +++ /dev/null @@ -1,4 +0,0 @@ -Leg | mbus-backend
                                                                                                                                                                        mbus-backend
                                                                                                                                                                          Preparing search index...

                                                                                                                                                                          Interface Leg

                                                                                                                                                                          Abstract representation of a connection between two stops.

                                                                                                                                                                          -
                                                                                                                                                                          interface Leg {
                                                                                                                                                                              destination: string;
                                                                                                                                                                              origin: string;
                                                                                                                                                                          }

                                                                                                                                                                          Hierarchy (View Summary)

                                                                                                                                                                          Index

                                                                                                                                                                          Properties

                                                                                                                                                                          Properties

                                                                                                                                                                          destination: string
                                                                                                                                                                          origin: string
                                                                                                                                                                          diff --git a/docs/interfaces/raptor_types.StopTime.html b/docs/interfaces/raptor_types.StopTime.html deleted file mode 100644 index eafc571..0000000 --- a/docs/interfaces/raptor_types.StopTime.html +++ /dev/null @@ -1,16 +0,0 @@ -StopTime | mbus-backend
                                                                                                                                                                          mbus-backend
                                                                                                                                                                            Preparing search index...

                                                                                                                                                                            Interface StopTime

                                                                                                                                                                            Represents a scheduled stop event within a trip (GTFS StopTime).

                                                                                                                                                                            -
                                                                                                                                                                            interface StopTime {
                                                                                                                                                                                arrivalTime: number;
                                                                                                                                                                                departureTime: number;
                                                                                                                                                                                dropOff: boolean;
                                                                                                                                                                                heursticCost?: number;
                                                                                                                                                                                isExtrapolated?: boolean;
                                                                                                                                                                                pickUp: boolean;
                                                                                                                                                                                rt?: string;
                                                                                                                                                                                stop: string;
                                                                                                                                                                            }
                                                                                                                                                                            Index

                                                                                                                                                                            Properties

                                                                                                                                                                            arrivalTime: number
                                                                                                                                                                            departureTime: number
                                                                                                                                                                            dropOff: boolean

                                                                                                                                                                            Whether passengers can alight from the vehicle here.

                                                                                                                                                                            -
                                                                                                                                                                            heursticCost?: number

                                                                                                                                                                            Optional pre-calculated cost for routing heuristics.

                                                                                                                                                                            -
                                                                                                                                                                            isExtrapolated?: boolean

                                                                                                                                                                            If the stop is predicted or not.

                                                                                                                                                                            -
                                                                                                                                                                            pickUp: boolean

                                                                                                                                                                            Whether passengers can board the vehicle here.

                                                                                                                                                                            -
                                                                                                                                                                            rt?: string

                                                                                                                                                                            Real-time status string (if available).

                                                                                                                                                                            -
                                                                                                                                                                            stop: string

                                                                                                                                                                            The ID of the stop.

                                                                                                                                                                            -
                                                                                                                                                                            diff --git a/docs/interfaces/raptor_types.TimetableLeg.html b/docs/interfaces/raptor_types.TimetableLeg.html deleted file mode 100644 index 347f2af..0000000 --- a/docs/interfaces/raptor_types.TimetableLeg.html +++ /dev/null @@ -1,6 +0,0 @@ -TimetableLeg | mbus-backend
                                                                                                                                                                            mbus-backend
                                                                                                                                                                              Preparing search index...

                                                                                                                                                                              Interface TimetableLeg

                                                                                                                                                                              A specific segment of a scheduled trip with fixed times.

                                                                                                                                                                              -
                                                                                                                                                                              interface TimetableLeg {
                                                                                                                                                                                  destination: string;
                                                                                                                                                                                  origin: string;
                                                                                                                                                                                  stopTimes: StopTime[];
                                                                                                                                                                                  trip: Trip;
                                                                                                                                                                              }

                                                                                                                                                                              Hierarchy (View Summary)

                                                                                                                                                                              • Leg
                                                                                                                                                                                • TimetableLeg
                                                                                                                                                                              Index

                                                                                                                                                                              Properties

                                                                                                                                                                              destination: string
                                                                                                                                                                              origin: string
                                                                                                                                                                              stopTimes: StopTime[]
                                                                                                                                                                              trip: Trip
                                                                                                                                                                              diff --git a/docs/interfaces/raptor_types.Transfer.html b/docs/interfaces/raptor_types.Transfer.html deleted file mode 100644 index 5249ef0..0000000 --- a/docs/interfaces/raptor_types.Transfer.html +++ /dev/null @@ -1,9 +0,0 @@ -Transfer | mbus-backend
                                                                                                                                                                              mbus-backend
                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                Interface Transfer

                                                                                                                                                                                A walking connection between two stops with a defined duration.

                                                                                                                                                                                -
                                                                                                                                                                                interface Transfer {
                                                                                                                                                                                    destination: string;
                                                                                                                                                                                    duration: number;
                                                                                                                                                                                    endTime: number;
                                                                                                                                                                                    origin: string;
                                                                                                                                                                                    startTime: number;
                                                                                                                                                                                }

                                                                                                                                                                                Hierarchy (View Summary)

                                                                                                                                                                                Index

                                                                                                                                                                                Properties

                                                                                                                                                                                destination: string
                                                                                                                                                                                duration: number
                                                                                                                                                                                endTime: number

                                                                                                                                                                                Valid end time for this transfer window.

                                                                                                                                                                                -
                                                                                                                                                                                origin: string
                                                                                                                                                                                startTime: number

                                                                                                                                                                                Valid start time for this transfer window.

                                                                                                                                                                                -
                                                                                                                                                                                diff --git a/docs/interfaces/raptor_types.Trip.html b/docs/interfaces/raptor_types.Trip.html deleted file mode 100644 index 946cd62..0000000 --- a/docs/interfaces/raptor_types.Trip.html +++ /dev/null @@ -1,7 +0,0 @@ -Trip | mbus-backend
                                                                                                                                                                                mbus-backend
                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                  Interface Trip

                                                                                                                                                                                  Represents a transit vehicle run (GTFS Trip).

                                                                                                                                                                                  -
                                                                                                                                                                                  interface Trip {
                                                                                                                                                                                      stopTimes: StopTime[];
                                                                                                                                                                                      tripId: string;
                                                                                                                                                                                      vid: string | null;
                                                                                                                                                                                  }
                                                                                                                                                                                  Index

                                                                                                                                                                                  Properties

                                                                                                                                                                                  Properties

                                                                                                                                                                                  stopTimes: StopTime[]

                                                                                                                                                                                  Ordered list of stops made by this trip.

                                                                                                                                                                                  -
                                                                                                                                                                                  tripId: string
                                                                                                                                                                                  vid: string | null

                                                                                                                                                                                  Vehicle ID, if available.

                                                                                                                                                                                  -
                                                                                                                                                                                  diff --git a/docs/interfaces/walking_walkingMap.BatchWalkingResult.html b/docs/interfaces/walking_walkingMap.BatchWalkingResult.html deleted file mode 100644 index 7995faa..0000000 --- a/docs/interfaces/walking_walkingMap.BatchWalkingResult.html +++ /dev/null @@ -1,8 +0,0 @@ -BatchWalkingResult | mbus-backend
                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                    Interface BatchWalkingResult

                                                                                                                                                                                    Result of a batch query from a single origin node to multiple destinations.

                                                                                                                                                                                    -
                                                                                                                                                                                    interface BatchWalkingResult {
                                                                                                                                                                                        distanceToNode: number;
                                                                                                                                                                                        nearestNodeId: string;
                                                                                                                                                                                        nodeDistances: Map<string, number>;
                                                                                                                                                                                    }
                                                                                                                                                                                    Index

                                                                                                                                                                                    Properties

                                                                                                                                                                                    distanceToNode: number

                                                                                                                                                                                    The straight-line distance from the origin coordinates to the street node.

                                                                                                                                                                                    -
                                                                                                                                                                                    nearestNodeId: string

                                                                                                                                                                                    The ID of the street node closest to the origin coordinates.

                                                                                                                                                                                    -
                                                                                                                                                                                    nodeDistances: Map<string, number>

                                                                                                                                                                                    A map of NodeID -> Distance (in meters) for all reachable nodes.

                                                                                                                                                                                    -
                                                                                                                                                                                    diff --git a/docs/interfaces/walking_walkingMap.WalkingResponse.html b/docs/interfaces/walking_walkingMap.WalkingResponse.html deleted file mode 100644 index 2889134..0000000 --- a/docs/interfaces/walking_walkingMap.WalkingResponse.html +++ /dev/null @@ -1,8 +0,0 @@ -WalkingResponse | mbus-backend
                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                      Interface WalkingResponse

                                                                                                                                                                                      Standard response for a single point-to-point walking query.

                                                                                                                                                                                      -
                                                                                                                                                                                      interface WalkingResponse {
                                                                                                                                                                                          distance: number;
                                                                                                                                                                                          duration: number;
                                                                                                                                                                                          path_coords: { lat: number; lon: number }[];
                                                                                                                                                                                      }
                                                                                                                                                                                      Index

                                                                                                                                                                                      Properties

                                                                                                                                                                                      distance: number

                                                                                                                                                                                      Walking distance in meters.

                                                                                                                                                                                      -
                                                                                                                                                                                      duration: number

                                                                                                                                                                                      Walking duration in seconds.

                                                                                                                                                                                      -
                                                                                                                                                                                      path_coords: { lat: number; lon: number }[]

                                                                                                                                                                                      Ordered list of coordinates representing the walking path geometry.

                                                                                                                                                                                      -
                                                                                                                                                                                      diff --git a/docs/media/logo.png b/docs/media/logo.png deleted file mode 100644 index b086987ec872bbefac07b441bf516ec733165d16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61262 zcmeFZcUV(f^9C9sN>va<4$_MtC7_@n9i{gU(p5T0k=_Xw5RgtlItl^ly;tc?0-;M4 zX`vGWp(c0h_x-+eo_qhhf1ig3viBxgW!9QmGw-~Ua4ikR>!f!`K_Jj|WhFTs5Qq@C zBm@zIftUT@=5gSKz+Ff2DX4Uq0R`O1SwB;@QCA1?0N2DIf-w6(A0Pnk?f}0a(3NZg z&=ug70QdoAga7ZpgrMvze_#K8ePPn6DR7`SoZpEp;l--J{t zTCi>iQN91^<$a0v8@`;M>4-T9)wnRU_ggH>Lu{#7LSjK7gik3hXD~N<=94D;=gsW5 zAY%)`rLT;PcS@Zz+}6EkVrE*rZH7e`g;K@wLizU)hdRxaG9UuN|Ndd20~-rQD0AQZ z$Fp`?7SNK!KOV3=0TY5q3SUJ;fWX8o(Et1)0ImPy4opJD0#eel*46vJmVrKqL63?4 z(V0>#h(P8IPudr@|26?MCIf00{re6o^9J}3mEO!Pn*WUuL;wa2|KpC3ibDnzn>~>C z^?ySF6H|g*Z~WiDfL3E!2*6N6ePMa|zh?>sLEZnp0|ZAx3F7!#$<6cklz>^LU-?I? z97<3S%M+No_CKTph=$=`(GdSDn!oqSzq{tQ&i|`We_NM-ZOtE>{;wJS`%L=xg!*R$d697)7Y;7QDR=7ID{3qBB;Uw|Nlw5P3A1-yxs<4reIC@ zP{HRI(@$pj8<46`Aq3Y&D}}(}H-Xuy>Fa9!nOz_8V`}WJI`j39i)MzMc=GO%%E8L5 z1qY0&jCVGjhYv6V4H_2EV+Wk57x3b#2Exdh-cb-aJR^A)7Q8W&6Jl+ItW*q| zKz_Rx0(<`sSZEZ0(5Q2*LjMzctI^(LPFll*ESzWPn#QWQz-sZilrk*Bz?&)xcm)4| zRg}5}h!oeJJ>tiQ&aY!^qX^UQ^|L}{_yCycrM9{i)$h&5(gUtMG2C}Q^qi3Wc2m?Z(oOn?h6DDz=;gf>B16p9>OJsmk&-5P`f5e!eETF!I zWXQ*33e86XYNnH3Q75ESss!X8@0eA|{(E~8vQkbyH$`Nq_!5Gi=smD!p%ef*@tL4) z_=8h@$br&pvwFfQe|AGNMC)kFt#10ILkX*CB^n>u}SkAUS~9Y2OB< z=C%_n@_UFOUX)s>Q`TFu_S`w*ck!#g*E5}`-Sej&1@7se$TWKf%u`i96DDzZkeF$x zu%1$938;cnCNM(uW;)e>M#!7JYCyP1qev$?uzkHYI~VBtfD-6NQ8G^TPd6u|b|{<* zIi(%RO2u27H1jjoN_yK?;e$cj#)Bn?3J*i!ayaJ*-WYv6-f3gX2ollhNDJaAT z!0x(=TKgcsx1Wr}RVxkLs(_ZDfGtZI2Dv`SvLqAFb`#kBS-{*bHa{}_nOm2Zj6LI4 z6t4H$ea6^@h6nqsL=TE7D?iG-xe8#8rl+?U{|sJ+Amx*E%SwZBkhQ8M$hR+6eCv|i zn(&!mJkar{-yIis^zr}cIN&NK`q2zcnU;cKWCV+4uuu`sd=TO|dLYUNCaw+xI`tto-t>b9c?BiIr@3QGF1iq8XK0BA%Ptum{;yHgp|bQ0NCi`t|Rw*v6RZ8 zf572<(b&0tw37;$l8ub&cC(eceB)^GE~M2SR*!F8Y{v-(=-BS3ca>?J$tm<)sksa zT(vQf$c=|DwxJLLUB6B6R~0BIn}<{Qzk7!UocYLs@ifl!M0|K9Dbb{mn*>rd{cQgP z^Q8^xrmD;R1LxRbX-P;00l?Xf&HVj8DteQ0e-8P=_JV(Fq%NakR?`21+z5&E3xYK) zk>>2_z|6i>Z`0MTTLNpnqz9;iuH>Ji0NBm0gma0Gs`r*YF4{AnzZGwofb3$oM-xqs z{g1a8js0W>%SM`*Ut*-xQUX;}^AnjgG?W3z_$9v#i1Lt>aEqg*7h+l?8M` zVtghm5^a5*Q9f&lqXifZ>*KE;ZAo-`DFl!ftwHkKYPIPG7wxl5;(GX7bJT~6DG1|n zF)QMZYJ+a3*|CH1w1}JLRgeOck@9RVOdg5rw(1J=J1YN|}qBO{-#2py@_V6Yk<@?Fd^?J8&+{{T^ zF}!$4e~n!itc=_i>7K8X=^bEkckzzj0$%FTy1h+X!0WHo7nL&naw-UfXMj|iG8FWj zlV(BoIX?m7@Rj$n)cG`X`lz(nFRb73GagSojYH{WUSJ-%WSh=jtIS?Y-$ui;j<-rm#2A+?&#GZXHe;fOKK_H@=uHJXVd8#N75*|lCfOGi-3$Ph}H z7|TjJjx$~6Ji<_WyCqzh=Wl{k=f<@eyTarG#qEJKF~?v2bsLfgUDGStnJO{FFD>vq=);@FE1pT zlx{t9-^swU8TuHn|n)NIQg$E)>vW!ytv0u8)4Li;*lR@2STXqxyYyI%qz$FS?8ys9x@GZ&a zH1VxJvZyysb!3|HcmuLKUORy8<~FHDQ>YK}BgKUK^p*CcGzZJ_@<;lA5Q4ZI_x)YL zyW_*l!}Pion0N}#7uFaXgI2Xc{t`}6`=VH~B+vb=-4!p?qCntT(M*xi>QKnL$gqb{?`x1z$oBZa|m|(IxEVw~`$5$iX=&QH$ecDS{-#rKw=l8+`PG&{$ zRJi)&&%MEtHtD}){l-GwdO7uz%yPXmlFcvFT6F!0CNAWH9LCaggJ_#rER1bVBQd*S z4@H#g%B$*kI=@S<(Z%Eq;f5lT2Vg57O(v_KoG#UEe`cPjCZnI?$`*V(11pPlZET(I zoExmlDA<|&$*iOsXEL{5m*M;KYE&vJhOUqQ(YnR1^zA;rS5MwCb9x2ZA6_@kqW6Eq z!;*YueVRF!-7SZx&^q|kR-o?4cA*oZnw5miL^O6^!YJ>aTvI}Qkwn#{p3si${ne73 zYuG$aaizn*A8O;j!3CekFDKo2Z_W1LlZR=XN?iT}o+^$e^s2%loZGXx%+}}OP1P9+ zWb{QFvK7A{ma7Wg5t$6d#`ExQ$CU;9pXB>tPg7uJ-+}(R8L>Bq5#hP434t=qWkBgtZf`4oTzp_CcUT`J!2i*j5G~u`}xxs?bH7wt0 zx*0`OY{PY>NVZ~Br2QQ?I7yT~Uez2Z^$B0(-oX7-|F%-_Qqar9eqCDGCF{PJWxBbV zVPSvT4>8X@dbqu4)uujj;+@8mAP+q$2S!{L8YeI)gdLmc21ex8D_N52 zKOjaOvE(f1dptgj{_HZ)C58OX`Gzk2fvP!5=JmPa(Pw7cBnd@M{}MHyN54XGX~=Nv zNyG`@26WtxebOQ*lqun#X#d{QZ41wm;t`v$_n2tm zms(%H{91jOPI`E{WP>sBez2`@p`eb17=Qplw==ru>mG?DbV-G;Yh)rC19Z-;yF&c0neuzC)C zcvHojB?tf7N#gM*`5(;1?m?<=po{K)d+QM<(j&LM@z|+P6213c1%*Ajs5(0nJe?1! zUDW!)4H1jWl+8;z9D}X@^&Yav&3xkUnC$sP{FFm2?5{G{#o35iX|}gjvpc(ZpVRsH z0Mu<^Gu{{N1uPEHH^KSN{T4v9DM)~bJI59H<6=BF#GL}M!3-k_6T6YK&i9U?nLff|U1KXJLuh0F5(&YbnlKV{X<|pO)9WlPQAhCaZIuYRXZN)wdQd zZH|o+Ly+B*HaH`5%%Ij<%9ci}cUZ76un-qUh3Oqbv(>##l^z>iEdcuQRN-;DDU0=S z<^@+9J5;6}jCAEhY>=icu4*``Y6MHr<#N1b$bI{AsHuC{uaXipq|!;W!^QHsIdB_W zspoJ`qi+2EQrjqPQFj5$%so|D3e7YW)2rXx5hSg0DnmIJRPU)GW7#!D3x&cb4cvMK zDCWqpEpWj>TMw?UPMN7(vWH}83#L*h--$Ye_30Lo&9@#?fr-c2mg;g}1=;%Uty}uh zl)#Jgowg{NemwGBAGG?>LR6}h??gQ-vbpnsVHTY5n(&8lJMZpE{rau3$T9>qDAqou1Umb>D$FvrFTU0z={UORJ>9 zaDS`kp+a7Y&;o^f+`czh5*U>^VvWuM?pBE&0O2q6szmRdQ+@mM>&~xT+PM|)iyG|} zS8wS$zsMSD@b2lUAzlma;kyYM>gz}&?s_J32JV-!h3zJHzt(jKbq;caBn06r<7NDB zaAj0%&V4EV#47|oeIV1de(lKAC`IQ^Iu)*EtBk6Ay^0$#(S%5=Q1Jy21>?I*Mys9D zd^;EQ4{2(6!s{8QvYxCgOb8e^Y$*TT%$>pob#=LXq3c{zR7TEPLC%SAJ=R(MN0_vB?pj=f+29F7OW9lF@tr zg(bBGZ}ep;IW#HkO0@K#3Y!bRWL+~hax#v2Ld3#h5J5gw85*opzwVhSxqz--j)w*d zpyz9ij`;XDSA-hCxa@+x+bg@$nbcg>t;;JjD|@6Si@cUOCRqlKx-1~O5&=a;7CC~3 zH-j9~&OhZSGz^_D2Z>sdd50|ecOkScDAQfFbShf?8rw*bc$JFifHt4S+1Y?n#BCur zA0V1Hkug>pAZojtu$Z4-&`5#AiK_^FkFx+!Os))jOS5NS=rcp+6vZWS!12|fYvhpS zu@*<^>&)RQ>Mg2WC7_`8DaZY24S%hV`zu2pL zhuLX~`1|}sRSd4D?Yu5p7+cS9{SN>kvuhU?Z2aRi{Mh7XW#RHvMVtiDUpQaj$XPy@ z%K&9ZJJ`|^E_1LX=Oars2gSbauB<&?ZG!v4T$*GTYoq5p(4g=n&d2B9F72!w4rk#m z$nDwvKO=rhVC$x9f39fv_G{d;FL`N$O?drAjfr|o4q-0P2f0VFB!tF1ES<1o)`po? z&j`SiINBZG)meTOO zI~9A~p9l;scZ6bY%CK+{AntJQoO*nCOE6c!2%N!~;-9e~B>pgo$VZUSOZs`e?v6#~L#ZWi~)iP*pg?^5FCbbRr_ z1Jf2ppCFlTD|dc_CQH7P-^xrnr6b$5zJ5|YOW58?{ozqU&L63*48VGNMpgi{k}9zD zah`k7FaI&RW-n0M#$joQWH**hfy zV4r<5YL`0hMTeC2yj~kf8KnN~ZT)O!XZ7u3M0YtU7)qS+*y<|aE>gwL+%JB+=zO3* z>#pEZb0aV^r0vCoAc_qNo%=Gd-N{{di-;5g$0P);B(i>mjhwug~3SL(HP}9%{>oGxr9v}mrN#w0R^cjvM>_cEUq)UMJ)cB$)Q;s@o&$J&yyv%%xWUAQQB1C+ zZFBXxP`un&%n$*9k%c%A=Jq!?!BvO%vPQjUijK>YH4C- zLYAIQ+(KaHx`e0`V**Zi_0qyk0ly-e@WlFj2$hHp`nJ&`HwY0w%wu&Ll_HQ)f^q=J zniD&VH_E#|HJYa_4<*mDgDW^7WTuz0V*lB zjeA)YAFxDMjJ@JU{XYxUR8=2lZO3IH>h1Sk8sS$2kz!4odzTN$;{tAiMToS}72Wk!A$+kORKc@8f!iHCxBn*q-jx zWmS0e@Lad?uBHNezd(3k{}KeUm3C6XD5(85Ieu2|!E3mq&B`_V@5ZWb{Y+;Si)2ch zbw&bprgKOAf6X!QnmJ=?E_hnD7+TI*jlEKmcFWRN+@JbHliy2J+#lX>8t$6k9rvp9 z_=LK;&hbl@@F`{NL@$62%PRR8#}C|JlVq#9xPz~)zpDPr4gb}HXiwzWsLNoSjpg^^@oe&m_-wlYUJ7OLijNZRWKGt0 z(l>~%9G_$ajcFf(LAJ|G>l=G)z6Og~+$n`mLl^ruY+D?27N=c2Cig)rKGU&u5B>1P zXwBzY9y#%&F2h}U`zA|YK58sb66>@>Zh7N$H`Mh6TQqG>$yRmPH9^LPe%8Z-e1WYC zflpqaUq?sHHNG1Tuxb!}d=cn7`Pn)--S<~}9Sev!J)O{!GaHjhX62>Sa{d(Gqco^= z@4lmpJR*MKrrYALq_9<{J}I{Z5AJXr#ASzuO;RrD4q2uhzfYyjv4Qg${AX}dWca!t zQb;Z{_HhDIiH|o|&!!`M_nudZX$NF`ylJ>B!#Y&bsv`ohxqTT2uc^?3pN<@hg-?ruly$uT9e}5i4C9UFDGG*I;Bf~fxiEcUkl{l!y~pgMILTJ)g^}c z7H8DeLS$JfRS8h*2@lQ%RLgt{GEK~#ND>P?gy7yAHd(Ek69qH^HGu#0;|Kvb$Y~xC zv7Gpeh;4N8oxqsFw7yTLp{fnUhe$A`ZxM&!h&atLG8h8 zE7D#u=I!hdY{P29BYZa2+*H;-_z|A!BBj~?<3d<}%p=S%WOU5wi*j1Y5Ql*dVIi`< z1cbuN?i7kU+f5{5tk&oXWM(iK_GOWE@|tk7$=U5|&jyjtrjqCP7siic43aFWuc)1^ z;D~gd%9@hPAar;4-Mbyw` zZP@y>UyvZIjd~JWwtidXy!DgWX(gvf&BJ14(8zsOBH(N;v2?QOKfHL69a{Vp`7W89 zMoHj;ENA@-Is{*PBgn+yzJ14&x03HX3e+fYu!fDY>Y=MC0U8MgUF_pL?7 zfqDFE5qm#GaX?C!e^M8SwPod|oXtU1qFNCp+;A>yS-wBMxyww34*5J~@#Ka3&n%Ix zT|5C*3X5&HgifE+1+>@+*PeE865RF;w@m?0zRXB68c%P+6AeHtd8{5j10JSb#*lq6 z+_-|uJixCGBDuGve%aX0wM(7Rw_y!E%m;?}{GT{qHeq%T-!_~}n|p+Z0GY`ZVRJ6c z&O3g&w;7e)s5A-cJj&}=B?Uz->n~pveoGimI=#L(DsEMn9=bbb^^)KAVz+#NSM$Ex z)*{Nn^=aT~V2DARf!N(p7#ZSD4O^AWH{ZB@+$GkqG$2PH@f&hsf8lm%;;s<|od zTJbcF=}8 zjK4n1B?j3@nwIBe;ws%rIa+_D=%iI2AAe< z%gb?nTG5vAnkYi5W={E(rBV03+NU+TQT&trl^55p<35Y}53~NR8Y=6QE1Ea3#R(Bf z{MV`MMP4UOaNd0VNtiY^2oJy|rF_)%J59kTrkRQ-HkB?a*}F5Af|SzfYr!d$mN>lN znl$U2<8Xg|jl?vfG&orf%+*FWy$8g@R;@R81s)Q}Jg?Dws!cPpx{JS>VjWCBJ)f^a zVKrsW8?_ZxyIZZHXA_o={ji;iXK%rqB=>PECe?mfow7>0@RW1DK3|}41&VIPldk(? zZyDezV7m#07;&e%=Q9~&I^v!5Xcm^H<-4f6h$tobEY_xgx!Yjp1DO|x;yZB`axD+t zu#2ANyTw?Cl#o2DiIg8~gRvs3S~W~^nJ3msZS7g&K-8BqEz2oQyt>TJ`W1jm;*4*` zgIHA7IekgYW&Gp?f;4PUi-dEKZ&@L)chamXCYDr9)g%0R&$d%V^u#U=t9%n`N0F5h zR(|{T+Vz^AWd8KrF!H0?uwZ20&D5GQiSdC_UtPIf+@3&UQXGs(FtY5%3A0(1lBh;A zp_Ne&KmroT$#QCOxAdAfu`21ek@SE~xXPx67+V`Os|}WXNNsp1^C>cu#}W2WwLTO) zAb8jtw0BnYLSa=NLjuPkS!BwNX;EwqVk-( zZHvVZ7l-M5qcj!r^6mFM&5DngY$v6;sqNCY7JCYOK{{ zGrzIy>%_R({n7!Y4K1}??Rt?aH2kLsqp!vl>UCdSfO{rw^wQe`hZHzMh$!<`O%whX zT_Ubtkj-dMZ2j8>njWl96D$8LG7Z>YNquFq>%p`h5-S#I!U(tbqgmU1DX$9cJc)Es z+dt|;k;MkqxZEi2#PDz{%5uqzs*Ut0LeNCU{Z|uSU_tH(%*8>z5%G~Ve|@E(h|xo1 z6|3pVb{av=fUg|fl5HA2;h`6=x(+vQfL3ZdQ>GcvAP~IY_ij<3d_!84v`A_3sO9l{ z|JFD^6Vko_yl&cpRSb@G6RsOtES{2px?R0iI>7ava*-luTZNN;q_Xm*+B*xCRf87J z#5mAoIl0_xwx_Zn%D4y?`X^)?Ex|S?jx+B9)=R92(Gj$R9FQl;!Fib6Sxt_-IM#SXs6W!*%=h3_1KsMoRv& zQD1C_Y`b=*!j7stC_(889rPrWvE37wtKW_S2nRL=uyzU3Z9>H|)_AP?& zvHE4C6LL%h)1FU!c2DLrCC#T=zyDC~_jZMQtM?u3qzvYK#4HybX^4R{0NYo1D;8b` zfSET3c3fbh5)~;!SCh@KwF4^{bzJ@?kR)w@Qr#8GW|ROh0cLTZ1V+Wu*IsPhe} zQ94}?(5JZfBD2OaHf$C_>b#{5o<($K>kbY2o_h-)8DVM{%s+U-g=l50liTDtE3!^I zSr$rcZJ%}0j2@$a}Xlypy^8x z7D#^$``0h-wLQ}OY>i{Ky%=61N-NyXUhs4_#j&2NyBu1xRc5=qU7gXJzcQ41j^N&i z7ZJfSTn`Z={Fq6`6UjGO;W+3uI)qsg>S%Tz*k6#!Pk}RkVHmmZA$bn$|>-)P^Ym<1H#(AbV{r0uFy!XsJ zRa`CGd&Zw+25&&VWsc%MZInjMSH5vy$^+PmX~5Q6Q~1^DuuF9sSzH!mshVu$5$XT* zuh3j1uKCUbl&?>7boEd+Q;&l+5RtiOaeNE76Ql9v+p|~|DnhGP#unLKk2Hzp!q;MS zSF*9DR?L^4zrqTC5m#~~kXk;f7P8V$O%y{U-M*9Z?2z0hnoD>>#3!5kZmfCt zPl3-`hRV4D?`DD(I|W;y?L<=ox_#rsAbf&Jj^=ZWq*xt}v4rVhRbwZSd;RU? zKEqaD%yv#2nb>?NvT7b37kWc$Y8Xh|0tZ)lsaaYBHGz!KBT)m)RjVX=`@2zAQm~<` zw+ukfhy1NL)UAlyCG6?FUQ&Vjeh?t3=#p~hWa-H=?^!x@4#>PksUYssy2+I zK7UygwC7(mbU}UU##@CKL}3><*SLI1xivvLo*FMFpey@=DBmuv1vqd(3ZPs;DY0%z`RV`FY{RM0RzG`4lWzA6=#|464d9m7+ zHO@9nwl#2z4fm<}nI|i8QK@nr+fu{(3|;Rw&THOy!G81`E~PfS!Q$mP-*6(Kd^)T4 z?fvvh@@Ev1VT7R1h6HrPS~7Hk@~=Ob?X2?`CRs2ItUy|o_4XRAK0gdLu%}7jg{}L% zkkC3t@Y0QNx+}wJhXSMJFLZs0^Ikp**6xy=74y&hh|Op`_k2))o?M}J$ed+#*=T^h z5H+6{?ELsq&S9%CCirJ_ydil>!3Lp)TC0KPO0or|os5jVkrC^o55k|$1Pj!@lfPg~ zv_s5hU+_fstA7qS3azNnRA-Y_w?4q+$>gi!>Gkl_MwqOA50BNv$pB-XeCj-lX{=W9oMXS zhJTkF=AbJ~i<1YO3K-pzX@Z8f0egXP@GIH~sH5-AjXc12P+3i|Qvwgf)<{29X==2J z3hm#a`RF;D-k;hgkNMmsKX0smPpMqS{!wS?aaC(6O^f#~xVFtWX+ z#dR-ju4DIW*)cq2?MuGRR4ezixl^WeNtErx;9$@<;`-7@Y@Ic4m0#8B0p4rE&r9K3 zT1c4052yam4?R_-&+i%5N=rTI{uMm}VI)^YZUo9bQx*|1qZ?qD@NG;r(TX-`g0BCt z^ghW6TGck`vM}yp@KNzv<%PSLXNw*+-+KrlGG6(_X``8&{Z~<;auTte^_nq=Pk1SO*`{lGm-Cxeio%OTCbzQm901R2J(0;vW zt7Pus;6?2Y8hHUf^I>(3ht6FBEaJH{DUoJ#FRoRaT?>7`gDN59F|$=0p2(fU4EoeD z)aO3!g%>9QY9NWUiHwpgB%>hdgyA>FuhULf=GM99oM(L-&L&k4PXarhde*!euH6w> ziaCST;>*{jO9-B+3ixVx9XUEq=QO0L(6TsIH-xR&L2kOLW>TZ60Xjj_I3JNbP=QM7 z!+L}ouN<6JHbIm*cOGacvoSa5MDEA#}St&fHkudh@_J>4s`inmf71vr3IW!lY-KcJaMl|q3hF%!9t#h ztzWL#EC6Yfth(5xbgrsu;1d!GeWGn38FrUo`hAOE!P z_r*O&#k%n3TZc>A0;WPwX_1x-Eempe^Ty&g0l0@yqORg{Ykqd4)Ei;9o3CRm25kH9 z10?qhGXYP(yM*~e=X@J5{rDkdo3j1rv$9xu5Lir}Uad!6nVfPn62zhxM5PEYiK&PS zense@ymTWPmz{2=6eM7)DolVB=|okuJf~)rmE53JQp^3S?bA4;7d@)J=)a(b zD_1WZNE`A1nrU!S>=OVlj+A-E%OjVIsz{l*6$4{VHF_ECY1&>@5@$gx(l%C=Bb65A zflU?-Myi%Z56uV5YrPLJ=?`b11*o9)%(FlX|g&w*Y>j zJa1rg!RPGjLT(eRqX4ik;5*V^XeL4#!R$QqTD6I#9ZV=W(1_M`ptOLP#q}u*0Hd^^ zN5UnlI|ZB{+?8&QXJ48*?kmgN^*6!f2gL{fN?8>UrZuPeJ`nfwkf%8M!|1JWhtfow z6ZeewXKWy1SXS3fnd~US3!35%A78la3y#^shx5p9BkR3(`ZJGrQDEnOF*KfZR_YU} zJ?qYx`@>mr+}A~Gfrqq`kB}lWgrKSki`)f6P6C-+o_9mPIj2WtcBqguZ|CQl`Q=3+ zE$nqg;x!OAUp83?mFwWD>>~HhnH**hXI+@JU1&&u#gIpGitQsOgMo5ed;oQHC#x|e z+xjU5yDxZTQ)TT0_)3Ob1dt|<#4iKc%7{DqHk$VeL?pGn-5kea`U!IGu{d5bood^! z_e%OpM9hebYVu^5U~juG^~YI!ehP-RCI}7hjo#Yt>?_ZjxNj_xx_+$zNJpQL=z*bH zoaNZL{_h8esdsw;YO;~k&mCc^uXC5QRwavlir-46y$iy+yayJ=UY`IKF*_J7-;|- z2*=sEoGNA*o$^?Iqt<-^ITWE^9@^uD(WReKFGR&d$i%pSinwkx^Wh5PnS=J3fn|zrS4*Oe@sk< zAgi~RM+`p|3fJ||Yv`^uk7)9Mp(~ltM8J5a@?~SndkC7kTbxaXu3E)hH21?gezM(V zamO)SDA;3dU*2DA%N#5Tw)Oi4`|LgOwEzs8VMM(cctn$DCNlYP;BBhbS)`Pm3TQw3 zY8xxC9Bd zN@Pu1il)x9CNW7@!JBL|T2@$Hrl2|rpdofn__Np$6dFcf{`iOe0k+`i z@H$_^*rA{^tG?L%!QPTUlf8y#dr}sY?2b-?ucaF^$HYZK&56O#ks>HLkdkd8RwA04 zqe6)=C}6Lp5ZgtXOy`6h5q~)l!Sd_-_ctG$5N4{pVO1vZBV{;(2& z6_2I)Z@A-zv=B(VqBW5&HFkL4XloHUlsSZ453Awy+ZvoQ;2yd9wWKhi1L&$AjFXdL zjk@BcN(7LSd%W+Jn@DXlT$%+OGVg}du8vD_D-k%n!DV}FiJUa$5G2#z-x9% zVb?zFud!>0T6+6URx}DBqMra|K!gSA#z0PV4LqjT6wAUA&w9;(CV${dlw_9VQ0*f?E$1okg{jTN9pKN&3?PVq}vr&iLgZX0WxsyQXhlhLjpwR zy`9rKpjszF*d`V;Ff|keGp97a|BJ>O$F6y(QI`C*1wbQe?yyP|vrxJaNH)o(T>gZ8 z@{4{GJ7&&j@d|7hELb+k}>)HV>KpByB(L+HO81pKv zDY)% zu90&)xA1pwXFVEstrj_&LuUp98FdN-x14y6;4fPXTzU*jk~TMy>7aNrwM7L)`SP=b zZ{8G>W5N^ITC?`D~>N&`@)^Y=?YIbtk074xTu7EGu zz^M9l2w!TRcSezS24t&Fj~~W^DZZ8jC|LVfWnu#03yN44TLF$6#nJ90z={xX4s_Wq zrU;#7w(l{<4k*G8DR_gwf1qv>fj700OA0WbWo^WqO$bK1tuK6CHw+U|){vQS^vEi+ zzGfY=4@IVN)6rcwoxX^^Xu$u4zS~z5A?{qQ7=)AY*zAYRv^}Q90w$!7gAk~LsV>g6 zD8QOKU?k+WBzTKq<2E|4Cj1FOCGo5Ez!7XkU_{!!;h*Ta683`4C;Ab_vSz0dNW|r? z(DRE4)agy5HH>Qc#6;P+j>zg)0f*?_?6j%b8tfrF2*<$ko=r_kael4uHbc-3a7GpBfrF|Bm>MhOfsV9L5Cg_%9YGLtK2E`^Fv^DF$T^ z?GB+G-?S0-R}}zRC?M$=Kesy7zL^B%npe1L&V_KxyFj4>))%M);i>A|du-*wD>-#d zGnN?S@c8cZt>5v9xlF?6b~9V?oZ!Ns{H53BJNYgBA>DKA<|E?D}7p$M@ae z)#Vmmk@{*VwY+%AeEOsvH5r$lWRhft_sZF77OrFJWl{BrADD3*u4x}V_g6@VjH zqv(>cY81f0E85_DJd3Lf9*Tc9?9NuoBI3|cRi^p04R24w%6RkpRn7Pcna`R5Mh%34 zs<-c91fJOJRR`2AYZ|@Ju0Og0ATf`2&|9LJkGA^|U6PgW-c1kG=w)8pm|wrsLNO&a zX_wM{aK}IcG!j7_WBI#+6gmD?RX_*jv!vlnlGOH6dy zzHojY(vl6k`f9iWV9NjM)Bf$2j9pzRn)-z8Lyt#~m@M)59yTxI`o&B8O9S8!@FW8p z#JS?{xFV?lY#YAAOcMCG3q{i}i}+XXOgL7`bT8HG#Sfo~?asGy3O;4|;yirY;QUPC%`*RbFJ`kn?C`vSa@*G;#rPKIYQ2ItlNL zdwc61^MxNkXnZf%KNk(qVs3DZI4NIOqCFg{q?;r1{vkr& zLQ&+kmtE_)3YY#W7<&UaDJYEye2HVtPZELB5e2R=L7`C36;8Tz00$IqIiVAj(phV9 z^gFhS#slrnc1ph<4Er*AHjQE9#6SsZON8%jH|ox=J}g*n(kq)Xi2 zE&zl|bR;F2prkz_E>q~e6EnbgNxMuQ^nh1dJ(<_MBH^#5V#|1zDHLS8!gO@v{xNCQ zzTG2)_(B~-8KS~M26$UNU?gE3rVO57*X5j+8?`BO+HP3WsADh9@%RDNs5{)uqH!)S z{Y&u!jzcR|7iOdBLAsXjklk>#xISVqvBbStv&+=}3X@fft+y`n`yvR@1;;_LI1y{T z&?kf63)c~Blx3gg1VNSu6N1c`aHQNOEf}h#Pm}_z!SO9EKhCC$Zr~7#-7Or2d|q#a zU+%_TPR8vGCMOA=>o;1cBCzy7G0h&<@yDWV@I{yjo}2r_P{dABn51J@Rj!t^$DsT$ zrBXALTtSeily48OvXUt~Z1xB_xztrd|C#T$4MsArh8i+dBC?)O2y#d719V505e5SF zy#|>)LKss~MZIBC($ltz^76xR`OFogfLs1E!ub)8Nx@D)hz2AW093nRD0;DH^`pw@ z%0WTHeu3asEj>XGW2sc>!%lnU{cAvrQ0T)ep8Z2<#+=v4x`xb6<}MM=om|9nCNc(c zKw$prEHCoI}vg}u9i zcOGlY->5GKs4W0@=>MVWE2G+qx@|*ncQ5W@gY(mGrP+LuL;{C3IL8tI2a)#LF`v>Hp6scFgo&c8!j92>_<|i-` zt|#c<0qj*Ub}TaTq{2(;Zmd#oQXMYPTg@UM{MhcDs{8l`?KRRX1C105tv20ZG|dJ9 zz1MR1FYY)OfbtTH5Q;W-yI)3UjL-~Lhs{q{0IAxBy3hYWRD8IxJ2}oZHmjvPzqjpc zQuE&-{Sg&e>g2~_-W%p-eK0qhZB;v6B6?2G9H4^fL`Ly@52Wee@KsYM+^yaI zrdbD}&SXrzPKG9~G_g0_EbNVG;odK(b2Syu`+K&QZvi-#Sj7M(uq`zZ3-+g1cior2 zXeFctZ!Sss6)aCrJ5cH)Fq`#YV@SO7jo~+;n2@3Si@G5g^1zZI@)|AZkp})?D`aMn zd!UqD^1viW0uLez478c~pARu{ac7Yj(pU^mn<#58eqbA2x%YkhZyG=FHb*d*s|&#P z7=iZpm7_DgqfrN{NCITpm+K!KypQY(Ot~MJY7b57(pe8K5K<4@!ayYOgfYJ{2Y4zLRc6BC*RFI{O;NM^WHz6}r9rB`1~qiA$4df6 zN0_VQ+zXg~aT&G!#T6nA(0t(%lXQLp6=*4zaNu7>hrwn4eo4`iU9H}$6Qdz1&|8h( z3-Z@c6AqaK7%@~m-*oc0@%(T;P!58*IIW$l<;AYXO~7;=VS9xM|MoXzCvjp+O3Z)=&)wke%zi(T%X zdjdKQqOKp50eUwvcqlzt$4?1>>ea&xXcSXMQ{c7!gee7Wa6KKIoy zH~4Zto$|3F$vUohDf2H-G0lVJGbMLM+q>S}InOYh+tt-hyv#j$W~o~E`^Y>i3juWR z-vMU~ubW5)lkaXflJ#to`%)d`5~jw5KltD-Cu7$1k{!k@$UrS1mkm)wqjknHOX`r# z-!A8G;&|~q+OU*sU`#12%fLedEfn!Fp#lb*1rd%miqrG9`$Uj-bsDyKzs)aL-ZqmJ zM4L~GBWum7Ff}@@H2;|r@RjkqLml!u=f!rq?KYpa_S*r{$xt?{`OQqN=@macDAbQE zP7)ADXof5iE8uEEmtqbLcIyvkD<_4xN(=!)*q`&E8w&7%sxjbZu!-HlH;XqG|uLuYrv;z#YJhC}wy7PYm{uvzpXFUhAENvMKCNv<~&JLaMP!RZ-Hk&6UvtqMVMZQ6k zm>lbNhKX1!8E9x+RTC=eJ!un*xWIfV_?J{&8wgQUn(?kuRERZna(%oGOGb$wj&3?* zx~~!Y46s8dCy!OlYmx(Qe$3n5y$V8v7DIdl68lNh7Kn;SNFW7Bu=3DLmptP z$IB!z@Bnk*x1C z6H0)~UZr#&m7zncym@H=loKezHj=9*^V-JW_~-&0!qIo3I>QxK#n_0Fpnx4z*$z)@ zQ56oaFP<-2Kpx;0;jLai{bZKvBeg$Jt9{y}O8@bn&`hr{?MGieIM8)d)vLAumH>=@ z-$`afWcg*rAlrqKE#@jPs;S_qEXBoq{9St093X&A2#v`Xal4CWJl=~-p?u(bjU8J? zHURr=>4OS@mGuc;&{%%f7>Y0>%0^>rSW16^19C_&KUeu-+WH4T@I>z#4?vL@G{w2E z%WLv=6c)D9i;jVcz)jlWJZm)MVN!6$9EgXff-1z-dC|r699&Y3sek7XfKdu6%G()W z3aqJ(+@qSCNh|ZkDf+p~nVve1Uko>O<#HUzd4M@rtNr%+%)we_CorV==Um}FpgzOc zcJv*l0ZZ0F?1$m_RW;8!WHL+rRJ0-tv2;fjAbU^S63p;1b2BFVK@=H|O8T^aZ-U<> zu>a*ZURP`uz|dXp;B~2SnRM+tEkeUYateaP-_!%M??0;tw4yjtqV(vu3%?fh@h2nV zmyn1J)za+kf9Oj7V4*%a0<{*fep1Q3jkk8L=krsH2IL#K9yj>$+gwWdA0rL#o91ew zbwfIgM9+8u4JGwX$_nBB56|@oDaxHhjnpD{ifoc;-GL0L7p-fDn_XLJcZ*~~!R)@9 z$!Q*)1LVxfe4^0Fe#7UV=y89kh=C_>h0>VcGrE^mx=zuOuqbS~RKuWQUj$DR{A03a zl6%epL;vY$ORMA`EV6QnbNCb>+MT zxoP`BBk9y2SBqq^HoA_BdVa56JoU^nbE5{zGY3r8ZO~InzFe04yQsNKu|JO$s+&%k zJ0fsv?0q)$9H^7gP_CM=K=QP(aT!iPBwk>Nd1Ef^U*?>VWH99W@@5wWrt{4^pH~4I z0Et~HO7m@ga>?R2cJvEOf8nMVv)|9wn>)t8ZJBW#B2Om%AW{(P6p^WT_*Fh4BfkGY zevB#ipHVe`jp|s%w9u>qq0o;Lpv5tCYyXk#d2u3{iwe@I2nG}}6t?^KfZGSlMg;oL zSM{}Cm;j1mdJCsX825j%Zt`}AR0gw@_7VlqwyG17Y$EhM)thRNb38CT?Q{&%HbcZ5fh}krM{wqwXjIA2X%FHTu+p*tNl(;$Q|9on2UvY&k0yXNW zDP-V;Xq*uasa5a&lxJ${oqbx(pLN*o_!xa6LI?X=u7%;oqDqJO7i8*aGBx{mrCe9j z#L$WKckJI9IsFy*x*Zo0^VSe=uN2iy$${U3=AQqTB~VZwq%;=f-78z^HRG5jHue>8a^QuRyce zYnniJPt1|X5aIUAObL%|_S(#H@p>z{_NzaQ?ZQ-zbsKlusAXhy>HK0`T$X1>O1XZs zP}crvfw$l!8L`H{sS)H$c5odaAT(v)NB-Z}A8Q*B_O0%Ct?C$2hW}Wk*>iQm4pADD zJfrr_>{pTduLduKvk6A(7pp_VFXqzR`RW&9e=!jge?J*9zg+vz@+!?HmY4V}XxCL* z9&fC;MtEzXxl|Az=?IKxa9$H*4x}Nat3g0(ky5tfg%JJoH?uzwFbkZ_Yi%u0&;FE4 zZni{64suB5!gr*Y4LR_pFfVAB4_BvK%k9+s{$(>MPOU_FA36Vnzs1?_aNy}=NnFLg zvcvhSQU3;Xw6tjWd$m*V6-Vl%HnqR95T5^kslTbVL6-U#qgh1Uv3*NkT8TKQX*CgUR5`bN|+^ zxBn7Vn0!bM-E)Qwf;Y!}<=%!X>bAF|pNg{XP_=cSHf5!Jn3@Ej?^Ik$WcE?;-HE8M z+iv-KiyOM#io0$9uZf<16dK%K3*Lm0_mpyx%JL1v7o(D<415XoSo?xZYF*tcPm|Em zZPezi4aR`3cqoP^gWcKL6&!xYe@;>!#+!^*%i94qJf<3A@O{&M{qpZ$YN)--YHvN75E3lyKHQ!Zt6466Mm%y-#D zygjq7@-+1cd&-#AUyr>6PAtYlNHo5m_i8}J)91@JZ)r2i)4fEry{L0mk@)*(nuLqX zmcNMHzb6t@Zrv1@dTX4W>^mD|rH1ZSxeSz*M3m}%T};ua6}>dB!?e{X#@ z`4_joFgcSBnDY$f$41NHq&)fGjDjn}ZS;DmPEI7?P^lVQ2srYmtbQeuw7IsqChK+B zSv$ZVuqP6@yCV^N!=*Vn>3%Fav!YzzN{V%aSfFs|d^ zJWco!^7i`H)&0#Pw~s_tD7JxQoa_57DpfulN*Lg;2x)4DpLH?e;_pMQUW{2MKfchQ zgjkQRm~CW1b3J)Q`i8s|Gsi*-ocla^9Q0p^Yx<-Z^T1;MwbBJz20#zGi~Q>{az1z; z2z^f2@3*;?Ej8(QslW!_sBVt*Q!@GE%ub>vv~mBgo2(!f^j_sw;SX_t@MHA;gqy@^ zs4)ehJA=0^VPSVlMmz{P7KA+T9#pdFsMuS7mV6jpx{w^sisy7i?UxpczDK<6zFZmY zv1Ow0Cc;QDjjDZyHZfKRgws9csi93QH_ATm$Afwa&FHT&LD+NXoUTLv%HVwFwR`J} zL>U}2K0X&aS1&ry6r4tLt9V`TH98bdwv!UB@)P{+6pb}}8V=W5CCUqQ=6CKmF{3T& z(YvJY$qi{V-+~#g!=$bpA1N`35Cln?LY&pWnwKA{&W8Q5ASGkxS2-246!RX8uwUDL z@Ls>%>BLZ+8F$8>KYSey!*WQDrZPOk=;lIRag35O`K~p~ieu7GV4Awa{p9Kk(Z> zMkIFnQJtSmUIypaoMV=C-~wh0`t_wFR~tNe(FZUOsJ4)I+pN#vLi5vk8tUfEkyunC zW1wR9=&qjLEF=$Q02-XO2@sg51IO)5P5ZA=`r`-hL(bcL;3_rzA0KVbN0KT~zv}w= z-o)C3xZ%l=+sT0mPqh5!FAwVz7H}4Yt>dQ5rxpJFTse=wszza1JGk6l=AR8CiL;D>T5VLCP6t`ljiYuQT&;u=iGnkU51+tlkJK=L?^cMARF+MmF4E&a!%Bp zw{;**bG(rf;JR0%FwtM*PBtd}Wn%d8!!mc1P<;4jvS@E`buspj%}VhfTIzH*9N%~h z4GLb4dGA#>Pw|Fd5Slb&x70-A1+9pqq4)V8PuW&tWVF9}Mqx&U2skt)am&Fkv{Q5!ttNDji|8``OFrF| zFzxYYf6R=#>NON@^UxwOnw>w-W~xC03`Z4H*pT(GN!AlTz_B6G!oH#7yngX|R%`4a z9bYf_m@2NxQ=Lt&IEs1eEGYt$rz!ac--)TV7@J%XOe+qir9_4?I~R^keEA!kJA6ZH zN%(18IzEW`^LPF~1;>J!(=>#djYL-kj9vVOR=3 z9%JO8@Jalv&^$7sr?W_=-A-g(`4RMl?5?;Mj+ax;N>7PzR4@7ZZS+{;c{7KoH>F}f zql0es+qht~4>7t*K>{E(;oX0{A(qjheKY*9>$)OPX_xY2OX*KE+4C7iq0){E#j?*xX5Ro_}xVpLK*?-A;W>iK%y{3Oalk2-Ug!GI6sTyvBI?oONl zJfP(Mu5K+CKg4hGYw-{$-`Xs|>T9keQRXFd;eAFRl(&jB-lS2WDmbiH5#JVq0Qpw= z;Q*yv)bY;Kazd0=Cxn+H-s&MPzkPjV{U5xFPaXPuYc0$J$LBNUfE9Kg@KvsHbP${- zt?}9-pVOmH{mxtUM;eoia1!HLN=Osj0m6~O$cN)f#Dbdx^8H~lhcbO4z&YeFF>SM! z75h4_&~M3!HygoAd6aOOS&l2+-?2TNM_>$B4#(F-#1mv~) zVM6czCE=cBZXFqM^5%rjg+*>G?vxW>oo3ypkGzi~>DEFM6{3d00d!`U-l`Sf-omVh9L<5GG-wbj)w=MRF4I5?EY zcI%72go`G|i|ya9R(*p<{Io*-Q3FzC&R*-^u*y zNmc_kMjsjno{o+S433VF`cTqG?ehzj7D9Wm@3ms;^~3eLDj?(^9jh)rixVTnG&xl! zBpaIx4}2a7$gz-L$V8T?RaNIBIRLJJFnzXTMs-n+P+n1lnnHfty zsiC>q@da#zr_!|~1dHBq?@+N$8S_b}DCfaY;%ZZ+e()==m?gWPeVN%#)2AG3)6I>8x@dJd1`+3j8*Id)vWD4Bs2YQPadU z#n^dPV5{%our6AJ+3$b9luLlkN1uCVlbLWn+Z}dvoVK{0EYt{Y8$y@{w#0(th%dN5 zz5<=aX(5KgZN-JG%ik4=j?U{M$yu_5@=LtU}&($_os;NMZ|PG zkrH~psW(6G9S8;+G~9IVPo+;56x^mQaSU~hN^AA}TQhEi&3>P6Ais5#gA%k%IfiEW zk}N^DbUJq=eNb!JzRY=9_Ct1wHr)pg$SlOsz|H9|rkf99Vy9gZHU6CCT>JU&Qa<{; zv?@8UhURvZTsi8^Q=>yZfpMXZBhYo}>KkK{XZr86A8WuHOpRXt2aphd{U-jpUvb-- zsqnoNuf`w=;_fDFU%iLM!#2VkSg5`k_zs6f{IuiXO>u9F`UThEj-^8_5`+%wRb`pL zcA_7-H(ow?F4#9MfU{3|6hG?&o`K)`qrv+QMo;L{R`w(2y0oNSmg6>?o@V!Vde?#m3|2R4t4hQB<89CSWjP6v@=P=!P$F5|27&mgbqTMb)73kH$ z!%7^T4MPd5$(yS9m#yWxjn{t!I=z?aJ0uON180AtMSAe-;cQJVqu>L=Up5oiONak2 zN12x+^fv_`S;1oQ?{YEgAdxsVm)VfR{560z6{i^U zn^&ze0a9voEb+=yAaoiZXOUBqj3?PrZ+!ivuHy`x!44h&+TYPFOVt7G*(M|)LduCL zLVRA=G2aH*{Ca`M*~FC*Jc0m?;Z5~&Z@c@O+!PW=ts>LBj$!dylgfn!bTiXgN#@;ZRp8yPhgwDVlB3g_K@^z^!ilbtdMo*MT*lA z3;%lW7#J$PHGc=Y-1lP?hSs_{)dF6Dv1{cC%c9T_OKOs{(I9_;4~Nrr%MkR=woPK_+qzg@ldH8T??Zd zY<^PV0>hP@?zL;OoLu97eHJlyS&lpJ4s}?D{t-S&2`?lcl6u`eU8=Y5URrO4$rF7f z__zf;DwQ&@3k%CbIL0TJW-U>ESLoZjI%7>K;Wc= zNkBF}cv;zit-Fq*&+3AWQl_kEya=nPCsQ2F9c1j!7l#$cD7FQP{6Mw(q;b=a|-q1s=1pOYj9-JnzxaTe!}n8n3r7qFPOV%Xcjgk0okbRI zRF+6Cx;bhPQZXkOUP<5- z1dIz!#5pmTR#nrG`*C?%D8`)gyq@ZM?EPU1l1b?-G52Vbe{!`GHGz!iDto`TH*>>*+JO%h;}3 z!SPXydO%yq(4$xxO^SA`LE7@My9tm1xHWc9p0cyd7=E*V=vrnXYJ523gfQn0Kw4>+^y_OITu&k&5Ni!91S5O`U#30i8|j$bEw(EsjS;F%TxdyG!>Y!e{=Wb zYUB!fGI~RTla>R31p1MXYW2G zKjiYghwUs(-EEAL0YMvAZQqe#ulYSTYJ2OEZo;gE0-nZ<0Tj{`6*6gl8caqMFJ2gP z*imu9oo|#_(PEm$m;S8hf;|qZM50ikhq1$EtSI)r-W4(E_6c@J-~Owi*PL5Rdxi=A zW)IS)y0%m@=n<3JM#QQ73CSqCt_?Ug%H(An81CKZo9om8N5ZVRii7*8RrS>ZjUij< zIHu@nxpXi%v00taKl z+U!nJOS@6*LKT>RYp)g0ZvXZ5Bp#MkAP3&ST2fk%^zi4~Q_G6ej-&e`nwIYqn?|~I z6QI~620a>JfjM95-71dyq>ojZIeb?inB=mNVPHfc%I5eELhzDNN*9c;om)l!CfgD->+=NBtHtfm^-kS?CJb{LyF8O0YZK0 zIF%jZFwZgh;CR@UuwF&wu*xUQ)w$dieb2n5&W8?a8mKnF!Aci*wd-ME!My&mD^~6O zlb7Zj{47B)O#nR{+#+~@t!T-Ev8+CGy+i5hPfQslP#R)U%raCQd;g8aQ2aQH;%Gr8 z58KIVD;x&r@}9D#@S^F|y&m%h?bdy^7xE4X@PqhBokRjjh8}?A`uFzve0C(tT+7&) z;jQ+#TZ0vD;m!WSg6)-WlCN#O`|rx11rey13*>gsC?k*o;~=6UrG#O_wGwu=I4}Pb zlk~Xi?TN`26Ih)9LN1ifZf&-oUP?yWp$Wz#{M+Mlzw0?kp`md zg@pqxC3(QYL!V{GGH0!VYz(8=d0ws*aJUJnD90Z?8TgzR92Y_=zO&dqOY zXeCDRaNBCE$?Ec_+2i+dbIIXgIdLJl0}>K7GTScP1h9^onvia89xWwOfCE3djTPPy zEjC;vzR&!zt=-Xa>9K7o=V~u1G2v)?>A40erOhAu(rMx+4iFy?-wbd1dja@H&Gk&y zA)>q_*b?Z8@(rvI;)~@>Hh^cT^N-yq(uu=%YN`uI!(AzXIDIJCWBiW}MA|$w zWB{y!3dRFkx{}On5~%Bd(x57)QUFr1Oe_<5>{wyouZge0Ne;m@nOVJ3F>fhO*k_bDsy!N3pdJ;a|Fw!eDP>1a`RnC=|9J-kd~Lm zm37DG+1{VEf=DDF-RU>m^f1=Qlq`DKe`` z^$;&cThN)~Yt34}oA{#V-|$#)l|IG5^{4;4O3LMQ*^oC0sMy%DfR>Uvpf!Gop?#_O zpqIs<=`Br;A0sYusI2jH`;-^#;RF0*qw%HWVEMe3Gn^HO zM<#eR0kV!{9CL5%1O;$C5pPNV%THx!A(623Fh7uxHgLYB^-YS%F>|Wc=-pjCdc9lr z(n;21KioLoXDwlzi|d6W;ZV^EDaUT-7$ItOGCEl5eT@6ll=Iv0Y)heV7oT_!y2Bx1a0Z=(-SiH@48@qdeM9nGV>CO#{+9}Y? z4$aeYIoZPb4yVD|Qbp??76`s(t-MK$^Y)nzaYK10J1-aV9vtc{9yX|xD>z0xJ3Srt z%Y4X)DS0mrp_2}DZi(}jBp|gpSf*p{VHh_7tKFiu%DELd8)ejv!nsIHHoC6izcFtd z>$CU@pEGbf6oQyWRrVcP|l^- zDw<2@9zOu*xRH^-PYxVR9~-NC2H*)Y6$gR&^pb&VYk;TKrNwfmMqDpuBhSgAh#Lf` zk!N@A&IEM6=x=NhTro}v_9KdJE?18M?`7b+^z$gUcx2c=@6N?_tGnX>#rhMFHvP?6 z$D}pZ1`o*HF86J2ddXbb?>cBBy?KWmswf^?w_?ChjgA8oNj8Dcp?HjSM5i0gGZ5&L ziiBtQG?Iw#t#R^bW~%%(UpJYZE32K$X8dEIkmIxw8~)D~j^tZK%U&9}PH{Np-K0^y zuSlMIXgn4eKj3(z#6hUpdDVQp4Vq_^n!_K%BcD0#+W6buc#A)U@jZ(9yTm%HuMU(s z=%Y4xV-kj3`o}+te0qKsPRGJ*Tc0k$BI}y(Sn8y+&O(6D63rta??r(u2o>BI0IadB zA>gYp@DOmY#iN*Mi<1jE-=}p&iq)5m?cM@d^jBQXKmOt08@C$l$!?%zG@pBX6Th~} zGzB92Qg`@SEiE>nqh3!VYSMfB?yC}DTo7hxQf5rs%; zB9l#NVU(~{{ZT0k3e|7Zg3g`-guHj({+flR={JmG)N5hbBEqgk8Eq2Ss{|=nCcx%B zg#LiCuZv*0we6zkOIqQSftK^7dJZt7>wGLHz>7b`T3V;DQID71V6n?%3- zUZej;$OYH)_FWpo-BNKcF-snwWV6i^M|eIz;6?e<-*@U5NSewk@3;R+7h!P5%-_ly zVkLMBn<}d5$C$sixqS}6W*QVd>x@7`MN1oNsQO7wgTW*)hxa?;zw~p15Le{5y!zz$ z+@61U7z(FLqHkPb4UMourr!*D_v1cw6}3Tme~}VgfaEW3=ChXoXE2~Nmwmix0U2y- z%RomV&IzKLq`x{Og4~w%z<95{lm+;whvysy3cma(B=-g{##oduWHo z|J+;UKTtA_Sy^fb^}OYk6oT_^`QnO}mP@|a-7zkc9#6uyLk6F7&Wg(%gi}8?TKFF{2Nona%d3(0zPsPwYROr% zyUxnG>1;}f7Qc9JF-$wI3ofqsIyJ?gUM7~m+DkC?;Cs14btZ3D_9aM=Jg#eC5O;6e zX{?_V$Z+(u#Ysw_2Hn0CKPOE;ugaDsV9P5NBjp~m=;50k)d~RN-EEorx$hPwWcD2& z1vb&tQXH3WjJL+EtWj&FwKrFd$Kpif4{r@M*0#nR>EGm0k!9ZGsy~g&gzijc-=E;E< z)k~;!ap(FAs^K6wBJ;1>kyZQ|b0M8E&vhvU_+A}k%~{^PMbJ-f(NEWwDM2KE(4P`o z`i&`!7vn}|7C`LLZdz9{US_(d10YP>3k62}H1#;(yYbf#f7!@*r`aI5d+aDu&kcOjg%=2+P2G`Z$g4r8tx=W&N~iMxCeV`qP8pj*+yO)?j{r zU$O<*t!(rZ7W&4gjpKuNJbYVWHV@syMwKc48mUfWs34FyNKWd#CcZH~;#V-o-#0G1 ze@udz#Iy&G(t&|Ys!phe`Ku){VLtFmKvEOuiqA5V@p?*$0PHF>c zVW33WS7;;@TD&+tI3RUR2P0V@#wx8k$%E@5Q_`!?-cL~uWrC@O9%|>6orqd1fLlE2 zXtgX*t%xA+;cyj)wCfA1<~T`qste9QR@1nj61@A+BG9L2j$Tw0iNN8_9bboIIVj$E zZ+G74&%J#HB~Cpr?W^q z)J!>z6Qx+;koaCJCwjJW3~QJwfaMtwK8m`9bm{E79vo1(80dpJa!DiLJVCOB0kI;% zRwFM>H7zopR?uqqyTsbM>zBdKx6N17-t9E-JAk+et!DZik4GyyIiQG58TZjcqPhLk zzybXLq6GoDfgB~r=}-t|^gNmmoUC>czVF`Uwa4*CA4O*P2v3~zv|d-Urx~>ns7PWG zB921G0w&K%Pe6OxO_ONox8K8jX$%`p#0x7#Z2&Y@>}7>h<3Xkk0G{%WaAq)U?wjX* zslAOp+f&$sYa_!t;vwb8ozI1u9oHY<9NAuzfE=M8!^|rXf8PKtI<3{YyC-zm*sUl} zztP>?$6ElNulO8+5PA*muh@SrXdVnPx^xG&pK}D^yxZF;?FY+g+t_V%T$rAGxh@L* z>IGq#xPD^nInX|FAQy^@ZzDmtKjHIUGo$Inv8!oJQfip^WA4VBkZ*4v43Kby>+5`W zl^~?7x}r+t`MJgB@p0|5!uSHMqjWziU7>YgGT-&&m!kF6;d%d(qWujx5>T^h?o=SeU$`4WAm;sH%nhom zcx}puNx|PQu-VM+b8rDf!y3|w=P&?QntAh1$%tv0B^8!7fBdoDy2d_X6>zl$vo85D zcht&XB+XL-_&+_8v0LdT8RTFAp_S(s5{ewy0_Y|i^9lN9hR(la;5Jh&VmkRAI0w;3 zqL5NL`b$uoX-Z(X4pbrM#%;&aSbs-MxHPv;jRF9KpAzEJ_+Re&_dI;z@S`KHNjGeV zdV5VH#UTg~>{{CcB7=;h%oe{++}RuMZ~tECeo4W5jbw0d)PJpV<9p(^mM^I|OiwQ$2|w`Sjk6d44S{uj1w zdWh$l2LZBGx;QDz5-G1}utjgk*E&(Ci?z93jm#M$&bTO$+$_xg>ZO6KzKA5WtP1jd z>ep*d5_hU@@U{9fw%Ff4iD32Z{P0?4pJ_1&Su7rcjYNsi*)vbRuI}~he&=H1BcEv~ z)BiON1R!&7AIu@*R~cXE{yS!4QQC3KQh#BW1(GeW#or^kG=mK zs3H2eyH$Lb=Gny+oSC@m-*XFWzC4zy5E7`y-40NcE&e6c$7Pmz~*Rvi2iz0hukox|`18NBYR;kH+S|YWQ&~s|5pJG_JEU z%A#t@v&a}dE*8Eu)*&jFgr{UAK=fa8s}G;f+}2x&ad(~%O1oCklw%e@l$dGcw;Mv5bfovfyD{et*OWfnx{eZa{^JPGNyA=gv-UgMpX)V&~I*pF}6ViwcBx zygt*7{I~7ye}Fuc?C0Ey{o9vhb({>{w4@~ZosyleyDG#LO7;EK=4CSKVv43r8cO-86q ziwoMT0>2g$p~qIRKt89_$`W>e!P=VRA&6`h0m*G+%cOrOgB#Z*MS_(bWb!qJ{$7va zxbqxFHWS+{meG)YDrEvlFFg6|5#PTL@3c5eHwp-7FX50@c8hin^J5(0ZJ4La7(45( z`ck*#G?zCS-HQO%3PtJ+tSzG;rw?YKbY`x(OS+x8^4$wjNum%;(TUWfa2LCF_arru z;sHfwZ+G;CemG=7tS5bg`{#pAQ7!q-;msYdZyQ>c98*c*g*Z-$g}kdy6&X$=4-7Va zMk7p)>_)!%^d|NI<(45t}+if@00(j^P~0B~+BB(|&pTerZ%GOi~++B~q=gawiGL{eNr zfv#-ZX#%=dNAuMv=4{1EmahIN5)5~_MP?2drpIojs8c(V9bjBIkP$8ljHE%CCz;_= zDviFkQ4CgUOSa9D6h`(Li`>4-iL1nN6ApK0r2 z&%BR)V=bG!#)4Q&F~K&q+LPigg<8&$$;<(`k&6rbg6o^E%m)3L@1A1Y+1X_IsTkbJe34w1HX<=}zB*Y=;AQreEu1Gga?##*SmE#zc*`Gj$3hoS> z=9V_goO8~`E^k=_4Ar2c(e(qZyH=JFr)h=p6msJDz=PK8Dt9Run7x@{lXNwzQ?oAJ zz2>)5eT3IjVP8)0S#b~cZn0RkCIJQi6GXJN1xvOB8PB)W8^U=@u_{eX^OK7jgw7U} z;9@aHd4##WCvVGn0?N}sUwyE!fzL8ooSYo%FQ%wCq_Yj~pn8Ves5dycpF@8Y^T^tk z35%I_w*Ofg=|=e>rP{G*{&f)3U>K`N@P2PfPy5ZXZV>X(>@6m6&H!c zsRhl3H{u<^-ZcwR1u};Z^-JH~9IvfX{Xrd-K)|H^SNx@pl^-3%W;4b!|Fy!?%gbMR zSTWZes-_k|-Vk|wk(G7JL&8fa_1R7CliG*Sn38)ePkO+7!{Gh^L{P%L_5BT19Sw(^ zDPc5G3C7IO*~|oi2zQ32cMI$Ak;%6a-EQ*zSSm!Cc~XEg0(yiXGv1cY&qsBVLctG> zMNC1Q5A_XoOMa^lH}iP7v@H4^8;I5bYp_e`?lw{U;vz?Ib!aCpm5+NOok^ePF%i5E7ZcUu!i z&C8d^ZCSQUPVZprVfeLayN0DxvDPpE+DG#PQdW1|a<^*nC#_r@kGG)c=cH3Ua*-b& zsVjdvg$2{fKH^>iFe33hJ>lni1+YIZmidE&Id8T`Y(WQhXmZRfuXs53aZIOX~RF{$({=V)Hl*(wR{I zwdO=t$9YENbQ$q9Rxai8fFUq%@1*bC_RUS)SEx0NE+G6gH5EpWzfA>nNn(JX z>+Qd?I^12SH6pZa5&-A_r~}IHrRRwU(iMFu&?=if5;M>={I}HglnFPAoekrN@x6Sd zQD||DgeqJbUS34j z;8}(^31D=#ZMX5_X1zS;ZlA-OPkRv&^;41puCDsm$GY`joK%%Cn)qFN86gkNH=!5Y zl<;`4flwYPlvi*j_=D@-VXH4Tu-mj37jQwHQWm)C$27Iz=GRWS&fw&GOym?D+uPp~? zTR^8+jC2Gy%kVEh(Nn56mIqjfqjsWQ;i7}cm|GnB#U1!*erIDVB~ScX0kV}GxqM*A zFyXRkyA)*UW?}~Z-0ZsaHb(<+SaH|XJ9BYlR=ZV41s(H#&!ocu+h?)rN`iAcPg5S~ zx@Xhc(LGc*)Dh1yA<4}r?nV06$^v<&iL7E}M$|fVNZEn_bvt7zC+Us`aD2eekRzXM z)%nudM5D{egDg7FBXjOcaHK`<50Bin81e{0t)=A!t@vhGVS1F5Qt5srQ^bar=_PVJ zzkC>HsD-=*A$pTy2dSwCUxD#pcgP{}1M`H)p%QDs*b@LmBo!Czr2pDm!%mSTv=tG! z7=*7`HTb>^+OpexegG>!ynI7|thl_{+QuPXD{oM z4fXc_sQ&!xkDAt&nm~=O!Z^lZ4d;;`RMRmCiNuw^?(+k3W;kj{#+V-&tc<(EaCaxz zI^R=msN_)fgU5~@ppfLzlL}i@O1C7;-1ZEBZCWJXTkg;1ut;qzKsd5xxZW~Iv{BSK z#^*1ZpQ@-0s&D}(vyPOF_h5kA0?$cT=$LB#iBc0?ua;%MzR9Mbz10kWjil|@`6A@S zfM)J^3_B-|x89+BoHVN_T{Qt>Kao8m=-?gTcdOMINs+BGAOoUqg%aGA&f|$tHT|f` zar0m=lfsSaZO6X6T|z1yEGL0bpD1gj(#o7k5Y{K&9i$yA2U7e25XgCa&|Nv3Dwj*W z8sIv(D^;1}U}b=w{K?yjRaz)jCgAgZ2(bzsZ1o9}xi-S!F-I4FrfcXL%sO^aJxO2! z$@$*`sgDkl=yJNs+1-;8L#t#6 z%eV*KKj_)adOkk>?j0wL*A&PjfQGUx44lQkH4|$bKnH<`u@3q{TF&?x^CF8zF&Cgf zQ9en5ad5}K`S)dyzQ;70CpDj-BNs~32p5-rf3MeZoN>N0gqcJhB$ut(a3q5aeyY*@ zR{h!c%Bmj(>NRf2$%SU1S%S>)KGlM;FkeA48W=d(B|&z#&sj(!7^94)#U&0>WsqdQ zCElwlqoh+g=|YH_bouR9fCTU(7-%25@{+fq(T~jj{X3}4k;`fQ1|YBcDF2iSM~s8$ zz>Qkv&5-LuGBa1i1g9dlnf^}JFfveySgE@WqC1qeLZk5e|3w_^Vbg|Nj3fslK<_)L`vJh=-imajd&B(Ao$TZQ((r6r+z)8yU+Ze}C6w~=_e|b`z{2QS8D+KM z7`fqw7DthAe`q0*;+tNa71a6}yY6R^Eo;4{Ps7Dudhw&<0kDlx7APZkl7>G6b@sd zaFzI#haNW~S+*VkTdekp%N~AUK)3!kU|GSR&Vwbj-PFGB(7Rcg+L7(puo6K>E=i)P!&|xo_XrHcjXpskiIl1yBs$%@l zXwpVB?*$a!S?${>CX*|DKyL`RbQwo{s->0ajM!DM^lXOcp)3ND*&eP~Ev z7`*im^++f3;y-2{2m-MSY_Un3Edu^|;~sSeXmy4fJBU`+7PJ%42BTMUaNYtHL`Rb& zhaH4KJnRzi^Iu&|ifH{#f`_?HnYiG`Wa2-`c$*S~@TUPTS8Mm&j|n8JdUD(wiANWt zyZtIT056r+NNw+rP{1)1KYeOyJuClvk@*9vsNZ?wYz}+u~}#mSJrYCCh4W&&FGuUt8P0Pt~gd%%iMqe z9D${z(i%gW1po)4mBt8fY-w65#(x5i@D@<#I>sHhLhHO=^KQVrJAzi(JueesIEoVZ zwyOMP%Xl6=IOQj^`~@<>|58dER{5n;|E+CtHOkLzqHP0L6EwyHk{bU8$3?`}6A3r) ze>ghJuqeAO3J(o}q;w02L3ei}CEXwm(kV4VH;ANkcS?6R(%s$NHO%+C-+wMR*Tac@ z*1p#|@wV`vm?H~vrS<|;??_DSX|s6YwHipKb5FUkVy>@^FjDtw-L3rOzu4@T^SJ;F z*YwpelMhFXaw4F?oBbS_Bh~wSDEo<2AB{xnjq-tve{k(IBA%Fyv}U|o0HVtV!VQXR zqjWc+<+aUxAW5Z84l;9#MueW`dgCW*=+b-=r989s?T~<|B5+IE$tyKlwzyF0I$Kb; zK@$;_QjML|%h2(Xz3>2JT46LJE85X<+eK$hD*j)S-}56K-fmpFf20G?0c08NF7YYv z$G^S+)?b#cF(_ppq0#wmd!nD+;^JGb#q3jU_1>u@=fg=dB8N29=fUfm=l;lJd___b z=Vo@v4M1zVK+VwBWA9W3?2KKJs?Gt{X*R5xQ%@B5D*k-Jy4 z`@22$vRR+tpsQz&9hQVUk7sF{?usYoBQ4UZLC2fUPKt-*lx4cW)!CfElPIQt0Jt`9 zzj@L1W?<5sn}I^ZVEECXZ(B3m2j{V?xE4&?brK;R|JUF}fNLoG{5|aav`3%(lQHMF-}Ss2T$3S1B9p+{^xyy<}`=}FCD%xn?g=sJOG|NY&s||pq!^$ z85h|7%CQ~(Hlz#k?S)9wOFguZGP?U~xR{2eA?44?U^QE6z8?wH_Mg0R24Jf(<#>WO zBPEhJLI0Hz^%Y%~LDhO>jS%-P*G^^`k@xUVYf8PXV2Sw&O3G9oo)1J;{*H-KyyA^V9i?+;X-Jx&kAw)V zw%&=Pv^UfQs>8hn8LLlQcTHW7==xwPDF=db(%B*~3dsrkFFrZBR^tWWvW(^pb&Z*u zHdINDe{E_td{-KAaAG~qSlkSB!1M?Hx^OWmV1yt;KFpZ@{`Ds)IQ4r9x6VIfi#*uZcVYau+f(S}sBY?*B++Jp;bq=%03wFjxKf*!le+}! z0k{*Hi2BNpX)WRAXxvMS>MN`5G)Nhv?u2~vd|$#m_GGmxU=B|tiYwRF?&&Abq*BAJ z=9}^VP*5T_^bIVrkC@mShc8Pf)Tst7o(}s|{JM(fU)!A|1hG|NN}7~Uj@OO^D9Tcj zFR3cQHDYaK3SZQU=-sAC;2j(|mP(|mlH_erFSUS4hRYHn@}u#bS?OyAzlFp+s^J-O zvbb`d^Ki-0+5@K@_&bv=2x$hWHsJ<`U90caDxA`*>EqB&SPY_TlnuG#E-ys>|64L4 zEj7@nTt3*#LT_Qk@jM_$B?SDF{?z$Lc99MMpz-qkk$y?;zXv{9f0&Y z0!@+W-!Ocf4JO^?AIblj7gBJ6?oo@q+<4|I3xaOLAi+^)?-+fHgQnUX zDIYFNdshGJMWp|g|5Ql?wEJ9*MtOdsQJ7V!?o9nC85#0(BWmxnIYs{7nAp&1zf^@E zM~F0ReOad=?9GjbrFCVxy%KmMJVTK|szM=sJDb;jH+%M3$wt-tpNs;62zv>e1vdoruE_b>Bm5Ubo4ATaKJ;oQiY+a-x7I7;_{ zBzrQK4Jfg@!V$sAX*c%foT}O*21C%w<0fAscY^v`4v=YIsmr$O?OQKJqOoNOtKsq! z`|0c(jg0J&9{ymDLt~=wnCzSq#Y>^vX=9&lVj68_4mc*q!yJ!`Qtr3fPb>KMif1^a zXFb@P@)x)#7N%U_!;sa%Z2DxqCmdki`MQL~8g2goVEm;gWc?_)kpMsO?y1!w9ST3* zzx=!lTaz|pe}aVz8~^rSV2q+b{7E_cmu=ZIligV?8rEe8MeV`y zw-$Q&M8_qR44#M90>hZdHkA0BddzAB%>5B~#6L5<78Z#Rd%x z4$x@RiBVgsGs*a4fQYTWIImBU2P=no=iJiLz&}Tq`zpF|#l`EfTXrc4FP`NZ17r5u zzy}hWlvFH>vKS>3Z4mDbK*C~{Sl4T-Y1nrDRkg;oZ@1^61w6BQsuny5Sw6q$_hJ7G z2^pdO)*w7c522^<$w2rKpbBea@@Fy;cr3n+7)`4JQtF2#37Suuim%U!*)6;^32^YPNqGKf z-#n)Dd><~bDkeh6vbxpRdq5a!3fi3odKiSTKkJ_*H;kNob$pw?wS`T^xTbQgzW0`l zm9lYCQ=9KX|G1D!J+o(tIRfingkwR$9&aLoW7Z6*ZtD)|4>l!K&lvpphMFwp377xG~7v**T6mw3($-*Zy zO*0jD5o9)NSSFZLh!e&_KmvMiDf*q5<#vE17*0@$cF$7V`6rz^sy>_1-Cq%ALJJf- z#uV@^Z5k5`%oHIrjCK&M_z@YoGh1E+@>3N$} z3-#tlJgB-!!Mo{>#VIY>i)*|E6}TS~`sD;v-qGz9?6apRD=1LNj4BLsZGE$o05-XR z^ppe6wR?aWB%$=<+oC}^@S~+61|jR|E58g|AMd-(=be=rq||Q(6@O$DFcWD>u3w{I zx~sx_P%?&>K?~0#DMO>8c4L~6MODoz_~m)EjUQsrW>qD^MlAboB~M6?B8EXkisZ)7 zs2M^8&Vb*}a>O#WY*ihYh_!l&DmILq6ze4L7U%Y& z86Htb6mA276%VR{83v6mN>|Y)+Q98oOS_DdLDz@DJ9S(2O|;p&x8{-BrJMRMK(Co_ zKPSMxI`rW=T9rF0da_HamJ@NM(BRREkPNq$uAX+vvzbo<*~7tW1vfc?)749H2k-sb^H_-muJgGU?$ zd?*_a5J714PEB_ES7R$U(Jx<4T_?VE?!Cw6hsiX%mzhj3h1+9b;cdLKwmj@sJ@Ck0~4s*Z@h`A z(4hSfE-Sxp1Z2AUH8j^B&T^o^`e7IsE_e4E<%>BHxco8$Q{l>zOrIxua)KjWoUH8* zjRVY-_)PkS@ ze{E=kMmEmlWuFH(p<_oVn1S3WS$(iG@^^TNk~@=#fHZvOgpc_5MNcP#>1h|oW?#Id z2!NSW#QKg!e}yysv=+ZIm1`9g>*rFymavnP9@Zb(#Ep*~qZ$AzdH>YNzcrg*j`dVo zY$KA*$AeB?D)>3tmjCxp7GA9CFT1m@)-r`dLZ#M6;8nL0ue{6;`Gj9BNkIOeB)&OT zy?_k;AL3g#tFwP|jrKDsg6{8`=g5LHxB9?y&kX>N7tn&p4(fCgOwydK5OnY~ZD7$* zV?i?4_vuNpiAiyyjiH9aN9!yeAMZh99-L?p?{pRC&+$N#n?F?=)^CB`6a-=*Y56N#p z_v^x95YubTFHl83;9mfAjD{KngwIU>*v{1K2)-cdr{Kk4heGOHNxf`Hz4%E9rTOD2 z`_a3pX9eG*D2w9WfsKE1PW{xRNktT2h81(08cIsCsHMH^&%exA19Lzp>Z>z-8NUa~ zb7TNNijAU^Em~yx5a53@-AS^M|AChO_SzNwax+k!B*($p(4ED0u4rtEqi|h=MfAz7 zhjldWhF>Cj^dqA83K{)PSSNb5=@2g+AkL}~U|+9J|1@jr8^ko~9d#l+qDZA(Kui`4 zCdOnooo=?b1l2|-5yS+8H`&*J7(Q+#4C)m~KGwZ=UKvX3Yl({_o8xRU%!{hKp%6hW znI7h(%1%SYesNgrA`NyIGYty-cT`!tb23FP%^uY#XT9SU^;)qFjz+a&0?L+6PFrO! zL=38rAF1n%pk34aF&6vp)Tb0IZ+%HXu-5ORPZIyZ{W| zgb!zMZ10L)EnM~=F&=+q#|!pRPTvcTO0hblQMl0;em0d zC%DD*{vOUWMrd1pHoOgCg)l;y=g9?s#oO%AiVaqVhw^`rtH0>pTlyUYs&nK^9LRvW zq5Q_P5!Wl14WqvV2xuHo7H3y}JRx1DXTx>U-@cAzu@7&PL0~Z31o+b8dDNXB`-5c` zYlBnKN9Z%)a87Bo$E0g07e>e-Pn@=^Cgf z0o@oClYZO&EX^1={OB1IK-yv!Lx|Qtqo!13^Z>lyOfyBRYIedszK==o;*^n8kcIc2!MvFmcsJ*bwC! zuTy;2H{{%zy){+d?jo^Lf1rvl*&F@EUzvB*(Qzuy2FE_O`-zYaQi}mJ+^V-N6TAL> z7Ivr4t84%Gex#$9tAVV#FA=@qD>^+}gzus!uC{3Wp`v(O>+|z#Z`t>^Xbj~=EBL^zs+g2bBxSahM2igTkhU1aC zkhem*3CaWX?BUfSBYe?qODK&zL+YS~u{q>a5U#a?u0py3bITr!6TG$jkEVRdq0=V$ zJJKcY@M+2>X11tWte7m2(tav)g!cWgI-uuSOISzr_EP#PI+~e9Wpl4FzJC}P>h~$r z8B>g4G-@GB-FwD!uKU<($)>3`zbXu-`GRfy6M)w~((^Zc3pYmToGW4y0UKNc*Pe5R zrE%qXXLnHYN{n|sQgOqWPY*Y(kpui7AsO*T`&C~ta7);;tc1m{CqoI7=85zU2`~X1 z8W;9{%ose}xE_hT}T*R$5p;ohq2;v;1U!xqEVEs<#*q|3VH!wD+k^&hF9Df26+C z`<_Oob8rcoE(}0KylVwAeBDzT?LOsQA+DsIod22e0W8>0nCacomSNTC=UTp2#L#MM zUeTy}$Puqc=u~m1z-@VqlGkYxPcqzIdPQMPm4GnMhu)D{(RNX4teN%{MEQu{K*s0Ph`E?{7 zu!XVtrU;UvhXa0E!y4g)PyM>3;-*mW%ZP0gU0I1+BH1@(0IduDSUdNf1M0y+zOiY# zq66BGUHU0-4D<@3e*FB;@|=QD7>jrz@HyB=9yM4UnvZgJxOLHoU=sWJW-7$`8kJV+ zOKHh$!AXux`ErE#yH5BKm2cYDKw<>mH*~~A6`skeH_sb|sfwoW(CGij!3RAyONMxk ztn%tbMv^1H5E=-J)ZEV z{{A=SaLvEuZQ8TpCP;Le`3bT+0avn@K>Dal3x!xLuTXQw)Yg(m zRa?KZ{@v0UFa_&xEt+m*3VoJWI0xA+f2uy&!I{mRy;}Ah`8cFZ-HYh5^3i)O17NF; zqkmJ#cN7stdK%}xZ-=e%X;Ur2df+LRW#xwe{^Yd#3yV}0S6#XtF}D%Y*k9H-az!9! z!bdrd68@=v_9#>YWliMrdqo71W0H80SA?NQcke1L#>_C$)S$3P*?ZqsC_a=XW3X^GQLBNPv&cwC>YydrYn z$>pHIS46ud-CCB8%;NRJ&9V~={w@9WpIqkR$h8G=rx^D&S}OpE4}A=oEm5OWSnN1g zMATS=)B}on)XL|yS=G%oyHPyBCp0GnN zA)Rp_$cNAW7#KpVZjSF%)1chc(=9$CUv)D-7!Kb|&adLkf=sRTTK>JKo=wA=qY%_D z8X01>lMAiSyc_J;B{wzxZK8N5`GAb-U=zpz&|WS46VYA8F(# zz(?sbuYR%5UH^xcFX!lY}RMWj(B z$}-h}o)2rdp>j*CYBxy(bIr}w*Yl+vZn6fVqHG_iM8{5*Yhae7*t6$mdC!40+q}24 zN|77fC%3mm(Mdj66g_(X+vN6*`che9v&ljOdv|imm+cwx9J zyJeFIUNfVy;QXQ@8`CXZ$5J8RYS#j_18TYVMfg-|kl6xO&^f)CHWqK(utzld?5F~* zr@H^GR&TKlxu;{Jtwq|^+MEImZ)?|@SZ5cVGZ{LIZ#s8QfL$HD~E_v^IGwMqKd# zMfc6QSf-LX<+&B;Ks?4N3Lbs4CB|ah!?|yJ{-(`GkD(Q9_egfuZKUKV zD$x-Qj8(=Ml}bw{U1H1nZ>zC@)KsVZHq?otzX9|=Sc|h-RZK*>K|MUn`~c1Ok=W4| zA-&AL_m&^@MlWD~5luSnbUn?%-pzbnh^#+D)qTXb0r=v0T}voiX$O!VF@d&kLk-Tb zaeaL|HD|*~KBYS~7^m>H)s&GM67>1UCWXv!kI>Z91BWUZkK>R}-C0pX>9)A$-JE+= z?8(+}&Xu+NMfgvq&nnG;we~Cb|A&}YQ=P?gHDpMUvgEatbqAzqC8Jw=-Xw#`c=aEE z9Fz!mI*nN_OHYPyG)mG<_6p6$@2i}LMbdecJ)jg8t4EsO2c6ZnBY?%Thi{B*k(X~q zJ}?jhM74!2(h1uNz4jDr^Y$e$V)=Fa7C}d>>W}%o;BW);{)e;E6STVA-KF4LQf%Yl zehJt6TgX9Di7@>PVTO}~f>&QTdmxbDLUyinE=8~C$_I$bq0}X>Pt(=A?Y`%){_YNR z8issm$WQA$p|s`+-fgd_N6#5!jJf00VVWgv<+s!Gx2mk~djAaxu}wgg<^00nud9U7 zsGc_qOR<<^n^K$X{OW5$<7 z`W1jg-2c^aip3;3n6IyDQckOB9Xs=`YbwCuURp;9UDLt(m;{K?B6{?H^;%|u?jj8{ zRV*asjrXEmNX+`Y1g~&&kbs=<<}98=E0>&joUhO$`fpHy<==UrY=24af3fgjDk-ql z;}l+sp}ReLGJ@m2j8bspMaCx8KYO^5GT^@zO99-ZE%ycAFeGU5P2knFTU@rabw z#$|LO+34|yN26({Ai~%jAoHlte_yH`sgt>`?W)mH$SNs#ef~GF{=~_YngrObwxidk?}8H%+uI4cL$S&er_OJ;&g z-BEwVs|x9JoFv}h^h;0@`&J#ndJ0SoEBN6FKb%hB%Y4&v2auB|mkZ7L(SQafHoqq? z9t%QsR0-*T9HXniKusC1I-_M-VfX#lNk6=235=6>J13SXUq*)3<|0FlU&?1^xVsC1 zz^?oRPCy#l*n^am-dxRZAiYl}G~(*t9!)*oM|XK9 z4u;iyoqy{lqpY@kvt8$!m)jP_{}wdjBK2RbEU-NMMz;u+L(gl2<49beHEVTatczS+ zKs|;tP_6KKa?_+c+$H@&F9Ln_WPA2oRZL-Z$hq z0Y;ZrmRtMdeG2@8$xk!vpC_irSBFMs;SB1lP%g@XjAI(Xq^VpMB$r@~g}`E4%c5di zh!WKuLd3Am1m=pDVjdygZakob9JAdvsx2%=e?l}W=kGt?z>HICRIRYet z{R9j~anF*?{5D>$#ER}fz+32hP(jw*3hRabjia-Z;||8$`&pb!$p?=sUU-KpAU*QS znW^HhhA$tmx4k4I4@gLeH~gLy_M=rc-V!)f@wZ-k5d2Q0ko_W(A=(@MX`-^dMdU6S z(7~%gl}{|2^=rJNq)Ei-gLLyq8fSpUx>YAI_U230VAbWm9q2pM7=h}MnE{ly_UwFz z_3CogWjoH(aX&=14 z1o%AAZe8&FvPD@iGUr*2r&G)BLU0 zYv!>!zgMBsbaS|v&QBONqz76gpo`N(Y;9*IiuW zOI2Uq3zZ5lQM(kN?2NaW^a6ZTN{iY?%JaV`8eo!#OK0r`a;q4fNcGp=vR)cd%#r;E zTE%YO6W~C;uox@^t$2ODZ#pky@j01ib+Am@@SAkNzUt<{Y)9m>T{3d|d1to7hW_Ek zL7;O6(Vm24%#$i@m|@LTzzd+%0C(+%p9no=gv;FMP;N^I;Ow{Elg4j9TmLlpZ_y7K z^5$TX4sB2z)Zo$^nmNkg>Abn7?xnh^`9Vpzpgz3H=tq!($5{j5dJ%H96?V5kDVIPp zx{D!mANOrgUDsV#MiJxus!ktc6AUOR=A9QdvS^)>M0JaoVxVi4PF7bRdpKBC~QS(^H@vm6{e_E+S-X zD01t0&z9^RxyyAj6W~UXG>U{cZE63c`g9(J1fy@VvSco=S_# zGU!AY{=)ewqtZgcMw5IxWb=G?N))=UeRZ z{^|N1wYoS$y?X*RoeFc%?nm$+*4_Lvz_gax;w!Qq4TsD5!P1ng3pCdsb`X(2>nHcn?i0q?cx}6&5PiLcN=f3V4I;-^}f$ zSaE=T!kg{h`z!gEVzvQLirv*aH6dpY0Oe(Et5Y7m4rONjt%JFa@1Hp?mDhF#hG%7%!2+oP!}?tWOzLPX?*tNM_x zs^=#Q>n0BanskqJ>ey;v7H8@TZT=zANl?O}!Rbpb{Aw)k%+=-hDMKBV zh~IYyNa}6T76j>1$gMeVR_PzDh{;D8Ron}73G^Bbtw5-SxNjujk8nHVPQq-Sha2MQ zh7LATIcPr+$&1RMe~}IN5eN|SxbUIJk|Iay;op|zoNpX2xx%l zlQX%!g!#z92CpBl+ZF*}H90Dp{x<{@t@F<<;O_O1srIJhCP(}jb3l^v+pE`-smdw9 z>{*A};cl3)2jyV&54%IO(&*w$u97SXHRt!m5 zwsX3V;t_w07-53y8%DzX41R(pVZ4S(4*2X{d(%fhK*~Ie^(BOc8P)^T8DtK3`;sp-X|w zb_s}Fw){GM3Xnw6OHJHgX`sXxC36DC7VGbW#RHG`Xb0hthScpI&ATZLA6KBuwmjgz>hqq|8Atz9KmawIA6n1JI!Dv*)-MvCMK%uaxrE6nD z6!#>7__HN%FVRZ=hnzfoBA&8PJApIQ6=ll6u!>$NA2cRhg~&jOq)P>dht^wrE48MM zhqY&%L@R=@@jKK5gm#cAA^{lyd}rOrrF+3gmiEslw@~}cmS|_3e}~cVx^g0mA2))Q zm5h(T9Oa>4o5au2`wbZ&|HA(a4rikv$Xt!h9>%HQc`7k#2M}J$5(mj_nYOr(x^#7C zyY{YAYH>31D#IvdM0%!&OUDy2Pc=DAgC6URbYo&EmTY?lp?}FBK+1*7k}Ov-$Nd!v z80g;qeZ4;>`luZd&K>w0Nl7oD8>uz*Q*;J-iJXWrEEP~A&WX12k3tul9MK}rCfV@rRWaDgOA@!)8w?G=D8<6QemAF7C$Irl(2d2-KCp7%X-a!pSV|8k5+HQZh zva*r4X^y=!#A{}K(bTa8-PXW&@A!Xa)_{JEnYN8k;%zQ69E4sjQD@C5DnCaM*cP)lS7Q)W)O%e{=X~$ zBQJeg^-c}o0+2Cpe2 zvcQPH?@uhH=-Nt6)IXU>tgeHVj%^3Xu-J;kG-JTT4^^_b6V!gJt34Sl#vrzX;~zf; zEpNI<;S@2s_(%yu#Ni3)9Qx%p1w_EItUMn)_CgOL!h4xzMRedVUe9rML(1u`Qq61t zLp3A`4vi=jq_@*jd;9Zv&R9!ha<>XdKQv6|l(66@ZJv3DLI(%ux(Cx}jA~`GaVV-R zMHDx}qn!}=uS5NZhMz{S{89WN;_<&dX*}BEH)Ibr@S(BQ_xe{671lplyXH<{XP}t* z^GQ?zrJqJNYZejv$Mx2zpPeE`lNBdlhS7Vtg+D(0$Uwnty>%&2RtNl|+C-uldbo02 z2dApOX7c*;+w{)^V{?0e(G^%+mg-7CphzG+#B0z@uv_I%Lh)kIe1Zm2Ap3sY{N1&a z>%N;H5u}msYjF;)SxZ|f0n!Ayjq8=*t#Lbl!+@5SlK%WSWYbgJ#Q!{PCS4Ve zvr_o3+#TMb)(fCfR%s4PvfUNFa0*Ez=;5O}2v?j+~V`n+Rj@zZE_ zFasUz59dNU+DJk>@?xeR>VlT8A#V}+7Tk#~Z!ycSwS4l=AE2rzwJp{TC_eNhi3BNh z<(KxexSj$@h!V7*`6Re>|8{SqvZT`7(5p{h@P1@Fw)Ip}PKGtf#UqWc?a)(=5kL|W zA_7)(HE)S2M*b>X9qShg-q=xIT$PD7E2%L?-&uk}bJ69*;Bm1nrwbH-BkTMhF$GTN z%L@3ixBg08)eDHHV}>*25{2)^#gI0csuA7Dl?zuWGIp1gj24wFU_wWzA! Az!d~(0f_22^# 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 diff --git a/docs/media/test_example.png b/docs/media/test_example.png deleted file mode 100644 index 41667bd90cfe0b40e87815c9225d2301d1d7a7e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54791 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 O&EVQGJq diff --git a/docs/modules.html b/docs/modules.html deleted file mode 100644 index 9561e10..0000000 --- a/docs/modules.html +++ /dev/null @@ -1 +0,0 @@ -mbus-backend
                                                                                                                                                                                      diff --git a/docs/modules/app.html b/docs/modules/app.html deleted file mode 100644 index baf826b..0000000 --- a/docs/modules/app.html +++ /dev/null @@ -1 +0,0 @@ -app | mbus-backend
                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                        Module app

                                                                                                                                                                                        diff --git a/docs/modules/jobs.html b/docs/modules/jobs.html deleted file mode 100644 index 217f3e1..0000000 --- a/docs/modules/jobs.html +++ /dev/null @@ -1 +0,0 @@ -jobs | mbus-backend
                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                          Module jobs

                                                                                                                                                                                          Functions

                                                                                                                                                                                          startBackgroundJobs
                                                                                                                                                                                          diff --git a/docs/modules/raptor_McRaptorAlgorithm.html b/docs/modules/raptor_McRaptorAlgorithm.html deleted file mode 100644 index b3e9157..0000000 --- a/docs/modules/raptor_McRaptorAlgorithm.html +++ /dev/null @@ -1 +0,0 @@ -raptor/McRaptorAlgorithm | mbus-backend
                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                            Module raptor/McRaptorAlgorithm

                                                                                                                                                                                            Classes

                                                                                                                                                                                            McRaptorAlgorithm

                                                                                                                                                                                            Interfaces

                                                                                                                                                                                            Journey
                                                                                                                                                                                            JourneyLeg
                                                                                                                                                                                            diff --git a/docs/modules/raptor_McStructs.html b/docs/modules/raptor_McStructs.html deleted file mode 100644 index 77efccd..0000000 --- a/docs/modules/raptor_McStructs.html +++ /dev/null @@ -1 +0,0 @@ -raptor/McStructs | mbus-backend
                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                              Module raptor/McStructs

                                                                                                                                                                                              Classes

                                                                                                                                                                                              Bag
                                                                                                                                                                                              Label

                                                                                                                                                                                              Type Aliases

                                                                                                                                                                                              Criteria
                                                                                                                                                                                              diff --git a/docs/modules/raptor_types.html b/docs/modules/raptor_types.html deleted file mode 100644 index 432b43e..0000000 --- a/docs/modules/raptor_types.html +++ /dev/null @@ -1 +0,0 @@ -raptor/types | mbus-backend
                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                Preparing search index...
                                                                                                                                                                                                diff --git a/docs/modules/routes_api.html b/docs/modules/routes_api.html deleted file mode 100644 index 92b0831..0000000 --- a/docs/modules/routes_api.html +++ /dev/null @@ -1 +0,0 @@ -routes/api | mbus-backend
                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                  Preparing search index...
                                                                                                                                                                                                  diff --git a/docs/modules/services_graphBuilder.html b/docs/modules/services_graphBuilder.html deleted file mode 100644 index c6dd5c0..0000000 --- a/docs/modules/services_graphBuilder.html +++ /dev/null @@ -1 +0,0 @@ -services/graphBuilder | mbus-backend
                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                    Preparing search index...
                                                                                                                                                                                                    diff --git a/docs/modules/services_journey.html b/docs/modules/services_journey.html deleted file mode 100644 index 4bf332e..0000000 --- a/docs/modules/services_journey.html +++ /dev/null @@ -1 +0,0 @@ -services/journey | mbus-backend
                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                      Module services/journey

                                                                                                                                                                                                      Functions

                                                                                                                                                                                                      planJourney
                                                                                                                                                                                                      diff --git a/docs/modules/services_mbus.html b/docs/modules/services_mbus.html deleted file mode 100644 index 5c2a1c4..0000000 --- a/docs/modules/services_mbus.html +++ /dev/null @@ -1 +0,0 @@ -services/mbus | mbus-backend
                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                        Preparing search index...
                                                                                                                                                                                                        diff --git a/docs/modules/services_metadata.html b/docs/modules/services_metadata.html deleted file mode 100644 index dff1332..0000000 --- a/docs/modules/services_metadata.html +++ /dev/null @@ -1 +0,0 @@ -services/metadata | mbus-backend
                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                          Preparing search index...
                                                                                                                                                                                                          diff --git a/docs/modules/services_reminder.html b/docs/modules/services_reminder.html deleted file mode 100644 index e60ffda..0000000 --- a/docs/modules/services_reminder.html +++ /dev/null @@ -1 +0,0 @@ -services/reminder | mbus-backend
                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                            Module services/reminder

                                                                                                                                                                                                            Type Aliases

                                                                                                                                                                                                            PostThreshold
                                                                                                                                                                                                            PreThreshold

                                                                                                                                                                                                            Variables

                                                                                                                                                                                                            rideReminderSubscriptions
                                                                                                                                                                                                            testing
                                                                                                                                                                                                            universityReminderSubscriptions

                                                                                                                                                                                                            Functions

                                                                                                                                                                                                            eventsEqual
                                                                                                                                                                                                            infoToUseForRoute
                                                                                                                                                                                                            processRideReminders
                                                                                                                                                                                                            processUniversityReminders
                                                                                                                                                                                                            sendNotifToAll

                                                                                                                                                                                                            References

                                                                                                                                                                                                            baseEvent → baseEvent
                                                                                                                                                                                                            BaseEvent → BaseEvent
                                                                                                                                                                                                            delayEvent → delayEvent
                                                                                                                                                                                                            DelayEvent → DelayEvent
                                                                                                                                                                                                            fromKey → fromKey
                                                                                                                                                                                                            Key → Key
                                                                                                                                                                                                            registrationToken → registrationToken
                                                                                                                                                                                                            RegistrationToken → RegistrationToken
                                                                                                                                                                                                            sameBaseEvent → sameBaseEvent
                                                                                                                                                                                                            thresholdEvent → thresholdEvent
                                                                                                                                                                                                            ThresholdEvent → ThresholdEvent
                                                                                                                                                                                                            toKey → toKey
                                                                                                                                                                                                            diff --git a/docs/modules/services_reminderTypes.html b/docs/modules/services_reminderTypes.html deleted file mode 100644 index da54182..0000000 --- a/docs/modules/services_reminderTypes.html +++ /dev/null @@ -1 +0,0 @@ -services/reminderTypes | mbus-backend
                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                              Preparing search index...
                                                                                                                                                                                                              diff --git a/docs/modules/services_ride.html b/docs/modules/services_ride.html deleted file mode 100644 index dff55af..0000000 --- a/docs/modules/services_ride.html +++ /dev/null @@ -1 +0,0 @@ -services/ride | mbus-backend
                                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                                Preparing search index...
                                                                                                                                                                                                                diff --git a/docs/modules/state_transitState.html b/docs/modules/state_transitState.html deleted file mode 100644 index b09cede..0000000 --- a/docs/modules/state_transitState.html +++ /dev/null @@ -1 +0,0 @@ -state/transitState | mbus-backend
                                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                                  Preparing search index...
                                                                                                                                                                                                                  diff --git a/docs/modules/types.html b/docs/modules/types.html deleted file mode 100644 index 2859f15..0000000 --- a/docs/modules/types.html +++ /dev/null @@ -1 +0,0 @@ -types | mbus-backend
                                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                    Module types

                                                                                                                                                                                                                    Type Aliases

                                                                                                                                                                                                                    Route
                                                                                                                                                                                                                    diff --git a/docs/modules/walking_loadMap.html b/docs/modules/walking_loadMap.html deleted file mode 100644 index a1cc5b7..0000000 --- a/docs/modules/walking_loadMap.html +++ /dev/null @@ -1 +0,0 @@ -walking/loadMap | mbus-backend
                                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                      Module walking/loadMap

                                                                                                                                                                                                                      Functions

                                                                                                                                                                                                                      haversine
                                                                                                                                                                                                                      loadMap
                                                                                                                                                                                                                      diff --git a/docs/modules/walking_types.html b/docs/modules/walking_types.html deleted file mode 100644 index 247a6fb..0000000 --- a/docs/modules/walking_types.html +++ /dev/null @@ -1 +0,0 @@ -walking/types | mbus-backend
                                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                        Module walking/types

                                                                                                                                                                                                                        Type Aliases

                                                                                                                                                                                                                        GraphMLEdge
                                                                                                                                                                                                                        GraphMLNode
                                                                                                                                                                                                                        LandmarkDef
                                                                                                                                                                                                                        diff --git a/docs/modules/walking_walkingMap.html b/docs/modules/walking_walkingMap.html deleted file mode 100644 index bbb0db7..0000000 --- a/docs/modules/walking_walkingMap.html +++ /dev/null @@ -1 +0,0 @@ -walking/walkingMap | mbus-backend
                                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                                          Preparing search index...
                                                                                                                                                                                                                          diff --git a/docs/types/raptor_McStructs.Criteria.html b/docs/types/raptor_McStructs.Criteria.html deleted file mode 100644 index f731f5d..0000000 --- a/docs/types/raptor_McStructs.Criteria.html +++ /dev/null @@ -1,5 +0,0 @@ -Criteria | mbus-backend
                                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                            Type Alias Criteria

                                                                                                                                                                                                                            Defines the optimization metrics used to compare different journey options.

                                                                                                                                                                                                                            -
                                                                                                                                                                                                                            type Criteria = {
                                                                                                                                                                                                                                arrivalTime: number;
                                                                                                                                                                                                                                transferCount: number;
                                                                                                                                                                                                                                walkingDistance: number;
                                                                                                                                                                                                                            }
                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                            arrivalTime: number
                                                                                                                                                                                                                            transferCount: number
                                                                                                                                                                                                                            walkingDistance: number
                                                                                                                                                                                                                            diff --git a/docs/types/raptor_types.Duration.html b/docs/types/raptor_types.Duration.html deleted file mode 100644 index bd2ff41..0000000 --- a/docs/types/raptor_types.Duration.html +++ /dev/null @@ -1,2 +0,0 @@ -Duration | mbus-backend
                                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                              Type Alias Duration

                                                                                                                                                                                                                              Duration: number

                                                                                                                                                                                                                              A span of time measured in seconds.

                                                                                                                                                                                                                              -
                                                                                                                                                                                                                              diff --git a/docs/types/raptor_types.Interchange.html b/docs/types/raptor_types.Interchange.html deleted file mode 100644 index 018d219..0000000 --- a/docs/types/raptor_types.Interchange.html +++ /dev/null @@ -1,2 +0,0 @@ -Interchange | mbus-backend
                                                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                Type Alias Interchange

                                                                                                                                                                                                                                Interchange: Record<StopID, Time>

                                                                                                                                                                                                                                Map defining the minimum time required to switch vehicles at each stop.

                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                diff --git a/docs/types/raptor_types.StopID.html b/docs/types/raptor_types.StopID.html deleted file mode 100644 index eec8b94..0000000 --- a/docs/types/raptor_types.StopID.html +++ /dev/null @@ -1,2 +0,0 @@ -StopID | mbus-backend
                                                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                  Type Alias StopID

                                                                                                                                                                                                                                  StopID: string

                                                                                                                                                                                                                                  Unique identifier for a transit stop (e.g., "NRW").

                                                                                                                                                                                                                                  -
                                                                                                                                                                                                                                  diff --git a/docs/types/raptor_types.Time.html b/docs/types/raptor_types.Time.html deleted file mode 100644 index bdf5077..0000000 --- a/docs/types/raptor_types.Time.html +++ /dev/null @@ -1,3 +0,0 @@ -Time | mbus-backend
                                                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                    Type Alias Time

                                                                                                                                                                                                                                    Time: number

                                                                                                                                                                                                                                    Time represented as seconds since midnight. -Values may exceed 86400 (24 hours) for trips extending into the next day.

                                                                                                                                                                                                                                    -
                                                                                                                                                                                                                                    diff --git a/docs/types/raptor_types.TransfersByOrigin.html b/docs/types/raptor_types.TransfersByOrigin.html deleted file mode 100644 index b24eb74..0000000 --- a/docs/types/raptor_types.TransfersByOrigin.html +++ /dev/null @@ -1,2 +0,0 @@ -TransfersByOrigin | mbus-backend
                                                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                      Type Alias TransfersByOrigin

                                                                                                                                                                                                                                      TransfersByOrigin: Record<StopID, Transfer[]>

                                                                                                                                                                                                                                      Lookup map for walking transfers, indexed by the origin Stop ID.

                                                                                                                                                                                                                                      -
                                                                                                                                                                                                                                      diff --git a/docs/types/raptor_types.TripID.html b/docs/types/raptor_types.TripID.html deleted file mode 100644 index ae31e00..0000000 --- a/docs/types/raptor_types.TripID.html +++ /dev/null @@ -1,2 +0,0 @@ -TripID | mbus-backend
                                                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                        Type Alias TripID

                                                                                                                                                                                                                                        TripID: string

                                                                                                                                                                                                                                        Unique identifier for a GTFS trip.

                                                                                                                                                                                                                                        -
                                                                                                                                                                                                                                        diff --git a/docs/types/services_reminder.PostThreshold.html b/docs/types/services_reminder.PostThreshold.html deleted file mode 100644 index 2eca7ea..0000000 --- a/docs/types/services_reminder.PostThreshold.html +++ /dev/null @@ -1,7 +0,0 @@ -PostThreshold | mbus-backend
                                                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                          Type Alias PostThreshold

                                                                                                                                                                                                                                          Waiting for the bus indicated by vid to be at the stop indicated by stpid. Logic for what notification to send -is complicated by arrival times sometimes skipping DUE, see ReminderSubscriptons.process for details.

                                                                                                                                                                                                                                          -
                                                                                                                                                                                                                                          type PostThreshold = {
                                                                                                                                                                                                                                              event: BaseEvent;
                                                                                                                                                                                                                                              stage: 1;
                                                                                                                                                                                                                                              vid: string;
                                                                                                                                                                                                                                              vidPredPrev: number | null;
                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                          event: BaseEvent
                                                                                                                                                                                                                                          stage: 1
                                                                                                                                                                                                                                          vid: string
                                                                                                                                                                                                                                          vidPredPrev: number | null
                                                                                                                                                                                                                                          diff --git a/docs/types/services_reminder.PreThreshold.html b/docs/types/services_reminder.PreThreshold.html deleted file mode 100644 index 041f7fe..0000000 --- a/docs/types/services_reminder.PreThreshold.html +++ /dev/null @@ -1,15 +0,0 @@ -PreThreshold | mbus-backend
                                                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                            Type Alias PreThreshold

                                                                                                                                                                                                                                            Waiting for a prediction of the right event to have a arrival timestamp that is at or after mustBeAfter and an -arrival time less than thresh. A bus is xx minutes from the stop notification is then sent. To handle delayed and -disappeared notifications, a candidateVid is set to the soonest arriving bus that arrives after mustbeAfter.

                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                            type PreThreshold = {
                                                                                                                                                                                                                                                candidateVid: string | null;
                                                                                                                                                                                                                                                candidateVidPredPrev: number | null;
                                                                                                                                                                                                                                                event: BaseEvent;
                                                                                                                                                                                                                                                mustBeAfter: number;
                                                                                                                                                                                                                                                stage: 0;
                                                                                                                                                                                                                                                thresh: number;
                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                            candidateVid: string | null

                                                                                                                                                                                                                                            stores the bus that'll likely trigger the threshold notification, being only a candidate this can change -as things are updated and such a change won't trigger a disappeared notification

                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                            candidateVidPredPrev: number | null

                                                                                                                                                                                                                                            minutes

                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                            event: BaseEvent
                                                                                                                                                                                                                                            mustBeAfter: number

                                                                                                                                                                                                                                            unix epoch milliseconds

                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                            stage: 0
                                                                                                                                                                                                                                            thresh: number

                                                                                                                                                                                                                                            minutes

                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                            diff --git a/docs/types/services_reminderTypes.BaseEvent.html b/docs/types/services_reminderTypes.BaseEvent.html deleted file mode 100644 index 1dcbcc2..0000000 --- a/docs/types/services_reminderTypes.BaseEvent.html +++ /dev/null @@ -1 +0,0 @@ -BaseEvent | mbus-backend
                                                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                                                              Preparing search index...
                                                                                                                                                                                                                                              BaseEvent: CoreEvent & { __brand: "event" }
                                                                                                                                                                                                                                              diff --git a/docs/types/services_reminderTypes.DelayEvent.html b/docs/types/services_reminderTypes.DelayEvent.html deleted file mode 100644 index 44c549c..0000000 --- a/docs/types/services_reminderTypes.DelayEvent.html +++ /dev/null @@ -1 +0,0 @@ -DelayEvent | mbus-backend
                                                                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                                                                Preparing search index...
                                                                                                                                                                                                                                                DelayEvent: CoreEvent & {
                                                                                                                                                                                                                                                    __brand: "delayEvent";
                                                                                                                                                                                                                                                    currPred: number;
                                                                                                                                                                                                                                                    prevPred: number;
                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                diff --git a/docs/types/services_reminderTypes.Key.html b/docs/types/services_reminderTypes.Key.html deleted file mode 100644 index f07b39c..0000000 --- a/docs/types/services_reminderTypes.Key.html +++ /dev/null @@ -1 +0,0 @@ -Key | mbus-backend
                                                                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                  Type Alias Key<T>

                                                                                                                                                                                                                                                  Key: string & { __brand: "key"; __phantomData: T }

                                                                                                                                                                                                                                                  Type Parameters

                                                                                                                                                                                                                                                  • T
                                                                                                                                                                                                                                                  diff --git a/docs/types/services_reminderTypes.RegistrationToken.html b/docs/types/services_reminderTypes.RegistrationToken.html deleted file mode 100644 index a46cd40..0000000 --- a/docs/types/services_reminderTypes.RegistrationToken.html +++ /dev/null @@ -1 +0,0 @@ -RegistrationToken | mbus-backend
                                                                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                    Type Alias RegistrationToken

                                                                                                                                                                                                                                                    RegistrationToken: string & { __brand: "registrationToken" }
                                                                                                                                                                                                                                                    diff --git a/docs/types/services_reminderTypes.ThresholdEvent.html b/docs/types/services_reminderTypes.ThresholdEvent.html deleted file mode 100644 index 453a64b..0000000 --- a/docs/types/services_reminderTypes.ThresholdEvent.html +++ /dev/null @@ -1 +0,0 @@ -ThresholdEvent | mbus-backend
                                                                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                      Type Alias ThresholdEvent

                                                                                                                                                                                                                                                      ThresholdEvent: CoreEvent & { __brand: "thresholdEvent"; threshold: number }
                                                                                                                                                                                                                                                      diff --git a/docs/types/state_transitState.Prediction.html b/docs/types/state_transitState.Prediction.html deleted file mode 100644 index 9d40436..0000000 --- a/docs/types/state_transitState.Prediction.html +++ /dev/null @@ -1,2 +0,0 @@ -Prediction | mbus-backend
                                                                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                        Type Alias Prediction

                                                                                                                                                                                                                                                        Prediction: {
                                                                                                                                                                                                                                                            prdctdn: string;
                                                                                                                                                                                                                                                            prdtm: number;
                                                                                                                                                                                                                                                            rt: string;
                                                                                                                                                                                                                                                            stpid: string;
                                                                                                                                                                                                                                                            vid: string;
                                                                                                                                                                                                                                                        } & Record<string, any>

                                                                                                                                                                                                                                                        Represents a bus prediction.

                                                                                                                                                                                                                                                        -
                                                                                                                                                                                                                                                        diff --git a/docs/types/types.Route.html b/docs/types/types.Route.html deleted file mode 100644 index c373f72..0000000 --- a/docs/types/types.Route.html +++ /dev/null @@ -1,2 +0,0 @@ -Route | mbus-backend
                                                                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                          Type Alias Route

                                                                                                                                                                                                                                                          type Route = {
                                                                                                                                                                                                                                                              rt: string;
                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                          Index

                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                          rt -

                                                                                                                                                                                                                                                          Properties

                                                                                                                                                                                                                                                          rt: string
                                                                                                                                                                                                                                                          diff --git a/docs/types/walking_types.GraphMLEdge.html b/docs/types/walking_types.GraphMLEdge.html deleted file mode 100644 index 1ed522b..0000000 --- a/docs/types/walking_types.GraphMLEdge.html +++ /dev/null @@ -1,8 +0,0 @@ -GraphMLEdge | mbus-backend
                                                                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                            Type Alias GraphMLEdge

                                                                                                                                                                                                                                                            Represents a directed edge (street segment) connecting two nodes.

                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                            type GraphMLEdge = {
                                                                                                                                                                                                                                                                dist: number;
                                                                                                                                                                                                                                                                geometry?: { lat: number; lon: number }[];
                                                                                                                                                                                                                                                                to: string;
                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                            Index

                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                            Properties

                                                                                                                                                                                                                                                            dist: number

                                                                                                                                                                                                                                                            Length of the edge in meters.

                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                            geometry?: { lat: number; lon: number }[]

                                                                                                                                                                                                                                                            Detailed geometry points (WKT) for rendering curved paths.

                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                            to: string

                                                                                                                                                                                                                                                            The ID of the target node this edge leads to.

                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                            diff --git a/docs/types/walking_types.GraphMLNode.html b/docs/types/walking_types.GraphMLNode.html deleted file mode 100644 index f225f2c..0000000 --- a/docs/types/walking_types.GraphMLNode.html +++ /dev/null @@ -1,8 +0,0 @@ -GraphMLNode | mbus-backend
                                                                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                              Type Alias GraphMLNode

                                                                                                                                                                                                                                                              Represents a node in the street graph derived from GraphML.

                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                              type GraphMLNode = {
                                                                                                                                                                                                                                                                  id: string;
                                                                                                                                                                                                                                                                  lat: number;
                                                                                                                                                                                                                                                                  lon: number;
                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                              Index

                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                              id -lat -lon -

                                                                                                                                                                                                                                                              Properties

                                                                                                                                                                                                                                                              id: string

                                                                                                                                                                                                                                                              Unique identifier for the node (from OSM/GraphML).

                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                              lat: number

                                                                                                                                                                                                                                                              Latitude coordinate.

                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                              lon: number

                                                                                                                                                                                                                                                              Longitude coordinate.

                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                              diff --git a/docs/types/walking_types.LandmarkDef.html b/docs/types/walking_types.LandmarkDef.html deleted file mode 100644 index 915b411..0000000 --- a/docs/types/walking_types.LandmarkDef.html +++ /dev/null @@ -1,10 +0,0 @@ -LandmarkDef | mbus-backend
                                                                                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                Type Alias LandmarkDef

                                                                                                                                                                                                                                                                Definition for a navigation landmark used in the ALT heuristic algorithm.

                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                type LandmarkDef = {
                                                                                                                                                                                                                                                                    lat: number;
                                                                                                                                                                                                                                                                    lon: number;
                                                                                                                                                                                                                                                                    name: string;
                                                                                                                                                                                                                                                                    nodeId?: string;
                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                Index

                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                Properties

                                                                                                                                                                                                                                                                lat: number

                                                                                                                                                                                                                                                                Latitude coordinate.

                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                lon: number

                                                                                                                                                                                                                                                                Longitude coordinate.

                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                name: string

                                                                                                                                                                                                                                                                Display name of the landmark.

                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                nodeId?: string

                                                                                                                                                                                                                                                                The Graph Node ID nearest to this landmark (computed at runtime).

                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                diff --git a/docs/variables/routes_api.default.html b/docs/variables/routes_api.default.html deleted file mode 100644 index b90e1b3..0000000 --- a/docs/variables/routes_api.default.html +++ /dev/null @@ -1,3 +0,0 @@ -default | mbus-backend
                                                                                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                  Variable defaultConst

                                                                                                                                                                                                                                                                  default: Router = ...

                                                                                                                                                                                                                                                                  Express router for the MBus API v3. -Handles routes for static data, state debugging, journey planning, and startup info.

                                                                                                                                                                                                                                                                  -
                                                                                                                                                                                                                                                                  diff --git a/docs/variables/services_metadata.staticData.html b/docs/variables/services_metadata.staticData.html deleted file mode 100644 index 02a705b..0000000 --- a/docs/variables/services_metadata.staticData.html +++ /dev/null @@ -1,2 +0,0 @@ -staticData | mbus-backend
                                                                                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                    Variable staticDataConst

                                                                                                                                                                                                                                                                    staticData: any = metadata

                                                                                                                                                                                                                                                                    Raw static metadata from JSON.

                                                                                                                                                                                                                                                                    -
                                                                                                                                                                                                                                                                    diff --git a/docs/variables/services_reminder.rideReminderSubscriptions.html b/docs/variables/services_reminder.rideReminderSubscriptions.html deleted file mode 100644 index f0c65df..0000000 --- a/docs/variables/services_reminder.rideReminderSubscriptions.html +++ /dev/null @@ -1 +0,0 @@ -rideReminderSubscriptions | mbus-backend
                                                                                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                      Variable rideReminderSubscriptionsConst

                                                                                                                                                                                                                                                                      rideReminderSubscriptions: ReminderSubscriptions = ...
                                                                                                                                                                                                                                                                      diff --git a/docs/variables/services_reminder.testing.html b/docs/variables/services_reminder.testing.html deleted file mode 100644 index 2f9349e..0000000 --- a/docs/variables/services_reminder.testing.html +++ /dev/null @@ -1,2 +0,0 @@ -testing | mbus-backend
                                                                                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                        Variable testingConst

                                                                                                                                                                                                                                                                        testing: {
                                                                                                                                                                                                                                                                            eventsEqual: (e1: BaseEvent, e2: BaseEvent) => boolean;
                                                                                                                                                                                                                                                                            ReminderSubscriptions: typeof ReminderSubscriptions;
                                                                                                                                                                                                                                                                        } = ...

                                                                                                                                                                                                                                                                        exported for tests

                                                                                                                                                                                                                                                                        -

                                                                                                                                                                                                                                                                        Type Declaration

                                                                                                                                                                                                                                                                        • eventsEqual: (e1: BaseEvent, e2: BaseEvent) => boolean
                                                                                                                                                                                                                                                                        • ReminderSubscriptions: typeof ReminderSubscriptions
                                                                                                                                                                                                                                                                        diff --git a/docs/variables/services_reminder.universityReminderSubscriptions.html b/docs/variables/services_reminder.universityReminderSubscriptions.html deleted file mode 100644 index b19565d..0000000 --- a/docs/variables/services_reminder.universityReminderSubscriptions.html +++ /dev/null @@ -1 +0,0 @@ -universityReminderSubscriptions | mbus-backend
                                                                                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                          Variable universityReminderSubscriptionsConst

                                                                                                                                                                                                                                                                          universityReminderSubscriptions: ReminderSubscriptions = ...
                                                                                                                                                                                                                                                                          diff --git a/docs/variables/state_transitState.cachedGraph.html b/docs/variables/state_transitState.cachedGraph.html deleted file mode 100644 index 9b2a870..0000000 --- a/docs/variables/state_transitState.cachedGraph.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedGraph | mbus-backend
                                                                                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                            Variable cachedGraph

                                                                                                                                                                                                                                                                            cachedGraph: {
                                                                                                                                                                                                                                                                                interchange: Interchange;
                                                                                                                                                                                                                                                                                transfers: TransfersByOrigin;
                                                                                                                                                                                                                                                                                trips: Trip[];
                                                                                                                                                                                                                                                                            } = ...

                                                                                                                                                                                                                                                                            The current transit graph used for routing.

                                                                                                                                                                                                                                                                            -

                                                                                                                                                                                                                                                                            Type Declaration

                                                                                                                                                                                                                                                                            diff --git a/docs/variables/state_transitState.cachedPredsByStopId.html b/docs/variables/state_transitState.cachedPredsByStopId.html deleted file mode 100644 index 14a287b..0000000 --- a/docs/variables/state_transitState.cachedPredsByStopId.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedPredsByStopId | mbus-backend
                                                                                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                              Variable cachedPredsByStopIdConst

                                                                                                                                                                                                                                                                              cachedPredsByStopId: Record<string, Prediction[]> = {}

                                                                                                                                                                                                                                                                              Predictions indexed by stop ID.

                                                                                                                                                                                                                                                                              -
                                                                                                                                                                                                                                                                              diff --git a/docs/variables/state_transitState.cachedPredsByVid.html b/docs/variables/state_transitState.cachedPredsByVid.html deleted file mode 100644 index e2f14ae..0000000 --- a/docs/variables/state_transitState.cachedPredsByVid.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedPredsByVid | mbus-backend
                                                                                                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                Variable cachedPredsByVidConst

                                                                                                                                                                                                                                                                                cachedPredsByVid: Record<string, Prediction[]> = {}

                                                                                                                                                                                                                                                                                Predictions indexed by vehicle ID.

                                                                                                                                                                                                                                                                                -
                                                                                                                                                                                                                                                                                diff --git a/docs/variables/state_transitState.cachedRidePredsByStopId.html b/docs/variables/state_transitState.cachedRidePredsByStopId.html deleted file mode 100644 index a2d90a8..0000000 --- a/docs/variables/state_transitState.cachedRidePredsByStopId.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedRidePredsByStopId | mbus-backend
                                                                                                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                  Variable cachedRidePredsByStopIdConst

                                                                                                                                                                                                                                                                                  cachedRidePredsByStopId: Record<string, Prediction[]> = {}

                                                                                                                                                                                                                                                                                  Predictions indexed by ride stop ID.

                                                                                                                                                                                                                                                                                  -
                                                                                                                                                                                                                                                                                  diff --git a/docs/variables/state_transitState.cachedRidePredsByVid.html b/docs/variables/state_transitState.cachedRidePredsByVid.html deleted file mode 100644 index 67a79b1..0000000 --- a/docs/variables/state_transitState.cachedRidePredsByVid.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedRidePredsByVid | mbus-backend
                                                                                                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                    Variable cachedRidePredsByVidConst

                                                                                                                                                                                                                                                                                    cachedRidePredsByVid: Record<string, Prediction[]> = {}

                                                                                                                                                                                                                                                                                    Predictions indexed by ride vehicle ID.

                                                                                                                                                                                                                                                                                    -
                                                                                                                                                                                                                                                                                    diff --git a/docs/variables/state_transitState.cachedRideRoutes.html b/docs/variables/state_transitState.cachedRideRoutes.html deleted file mode 100644 index a85f23b..0000000 --- a/docs/variables/state_transitState.cachedRideRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedRideRoutes | mbus-backend
                                                                                                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                      Variable cachedRideRoutesConst

                                                                                                                                                                                                                                                                                      cachedRideRoutes: Record<string, any> = {}

                                                                                                                                                                                                                                                                                      Cache of route patterns and static data for the ride.

                                                                                                                                                                                                                                                                                      -
                                                                                                                                                                                                                                                                                      diff --git a/docs/variables/state_transitState.cachedRideStopLocations.html b/docs/variables/state_transitState.cachedRideStopLocations.html deleted file mode 100644 index 8eaa636..0000000 --- a/docs/variables/state_transitState.cachedRideStopLocations.html +++ /dev/null @@ -1 +0,0 @@ -cachedRideStopLocations | mbus-backend
                                                                                                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                        Variable cachedRideStopLocations

                                                                                                                                                                                                                                                                                        cachedRideStopLocations: Record<
                                                                                                                                                                                                                                                                                            string,
                                                                                                                                                                                                                                                                                            { lat: number; lon: number; name: string },
                                                                                                                                                                                                                                                                                        > = {}
                                                                                                                                                                                                                                                                                        diff --git a/docs/variables/state_transitState.cachedRoutes.html b/docs/variables/state_transitState.cachedRoutes.html deleted file mode 100644 index 4c54c10..0000000 --- a/docs/variables/state_transitState.cachedRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedRoutes | mbus-backend
                                                                                                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                          Variable cachedRoutesConst

                                                                                                                                                                                                                                                                                          cachedRoutes: Record<string, any> = {}

                                                                                                                                                                                                                                                                                          Cache of route patterns and static data.

                                                                                                                                                                                                                                                                                          -
                                                                                                                                                                                                                                                                                          diff --git a/docs/variables/state_transitState.cachedStopLocations.html b/docs/variables/state_transitState.cachedStopLocations.html deleted file mode 100644 index d89fc66..0000000 --- a/docs/variables/state_transitState.cachedStopLocations.html +++ /dev/null @@ -1,2 +0,0 @@ -cachedStopLocations | mbus-backend
                                                                                                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                            Variable cachedStopLocations

                                                                                                                                                                                                                                                                                            cachedStopLocations: Record<string, { lat: number; lon: number; name: string }> = {}

                                                                                                                                                                                                                                                                                            Cache of stop locations (lat/lon).

                                                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                                                            diff --git a/docs/variables/state_transitState.curBusPositions.html b/docs/variables/state_transitState.curBusPositions.html deleted file mode 100644 index 7bc30bd..0000000 --- a/docs/variables/state_transitState.curBusPositions.html +++ /dev/null @@ -1,2 +0,0 @@ -curBusPositions | mbus-backend
                                                                                                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                                                                                                              Preparing search index...

                                                                                                                                                                                                                                                                                              Variable curBusPositionsConst

                                                                                                                                                                                                                                                                                              curBusPositions: { buses: any[] } = ...

                                                                                                                                                                                                                                                                                              Current positions of all buses.

                                                                                                                                                                                                                                                                                              -

                                                                                                                                                                                                                                                                                              Type Declaration

                                                                                                                                                                                                                                                                                              • buses: any[]
                                                                                                                                                                                                                                                                                              diff --git a/docs/variables/state_transitState.curRidePositions.html b/docs/variables/state_transitState.curRidePositions.html deleted file mode 100644 index 96ca1c9..0000000 --- a/docs/variables/state_transitState.curRidePositions.html +++ /dev/null @@ -1,2 +0,0 @@ -curRidePositions | mbus-backend
                                                                                                                                                                                                                                                                                              mbus-backend
                                                                                                                                                                                                                                                                                                Preparing search index...

                                                                                                                                                                                                                                                                                                Variable curRidePositionsConst

                                                                                                                                                                                                                                                                                                curRidePositions: { buses: any[] } = ...

                                                                                                                                                                                                                                                                                                Current positions of all ride buses.

                                                                                                                                                                                                                                                                                                -

                                                                                                                                                                                                                                                                                                Type Declaration

                                                                                                                                                                                                                                                                                                • buses: any[]
                                                                                                                                                                                                                                                                                                diff --git a/docs/variables/state_transitState.rideStopIdToName.html b/docs/variables/state_transitState.rideStopIdToName.html deleted file mode 100644 index b36e20b..0000000 --- a/docs/variables/state_transitState.rideStopIdToName.html +++ /dev/null @@ -1,2 +0,0 @@ -rideStopIdToName | mbus-backend
                                                                                                                                                                                                                                                                                                mbus-backend
                                                                                                                                                                                                                                                                                                  Preparing search index...

                                                                                                                                                                                                                                                                                                  Variable rideStopIdToNameConst

                                                                                                                                                                                                                                                                                                  rideStopIdToName: Record<string, string> = {}

                                                                                                                                                                                                                                                                                                  Map of ride stop IDs to their human-readable names.

                                                                                                                                                                                                                                                                                                  -
                                                                                                                                                                                                                                                                                                  diff --git a/docs/variables/state_transitState.routeTimingCache.html b/docs/variables/state_transitState.routeTimingCache.html deleted file mode 100644 index 3a6c458..0000000 --- a/docs/variables/state_transitState.routeTimingCache.html +++ /dev/null @@ -1,2 +0,0 @@ -routeTimingCache | mbus-backend
                                                                                                                                                                                                                                                                                                  mbus-backend
                                                                                                                                                                                                                                                                                                    Preparing search index...

                                                                                                                                                                                                                                                                                                    Variable routeTimingCacheConst

                                                                                                                                                                                                                                                                                                    routeTimingCache: Record<
                                                                                                                                                                                                                                                                                                        string,
                                                                                                                                                                                                                                                                                                        Record<
                                                                                                                                                                                                                                                                                                            string,
                                                                                                                                                                                                                                                                                                            Record<string, { diff: number; rtdir: string; rtNext: string }>,
                                                                                                                                                                                                                                                                                                        >,
                                                                                                                                                                                                                                                                                                    > = ...

                                                                                                                                                                                                                                                                                                    Cache of timing differences between stops for extrapolation.

                                                                                                                                                                                                                                                                                                    -
                                                                                                                                                                                                                                                                                                    diff --git a/docs/variables/state_transitState.stopIdToName.html b/docs/variables/state_transitState.stopIdToName.html deleted file mode 100644 index 567074d..0000000 --- a/docs/variables/state_transitState.stopIdToName.html +++ /dev/null @@ -1,2 +0,0 @@ -stopIdToName | mbus-backend
                                                                                                                                                                                                                                                                                                    mbus-backend
                                                                                                                                                                                                                                                                                                      Preparing search index...

                                                                                                                                                                                                                                                                                                      Variable stopIdToNameConst

                                                                                                                                                                                                                                                                                                      stopIdToName: Record<string, string> = {}

                                                                                                                                                                                                                                                                                                      Map of stop IDs to their human-readable names.

                                                                                                                                                                                                                                                                                                      -
                                                                                                                                                                                                                                                                                                      diff --git a/docs/variables/state_transitState.tatripidToRt.html b/docs/variables/state_transitState.tatripidToRt.html deleted file mode 100644 index f36d203..0000000 --- a/docs/variables/state_transitState.tatripidToRt.html +++ /dev/null @@ -1,2 +0,0 @@ -tatripidToRt | mbus-backend
                                                                                                                                                                                                                                                                                                      mbus-backend
                                                                                                                                                                                                                                                                                                        Preparing search index...

                                                                                                                                                                                                                                                                                                        Variable tatripidToRtConst

                                                                                                                                                                                                                                                                                                        tatripidToRt: Record<string, string> = {}

                                                                                                                                                                                                                                                                                                        Map of trip IDs to route names.

                                                                                                                                                                                                                                                                                                        -
                                                                                                                                                                                                                                                                                                        diff --git a/docs/variables/state_transitState.validRideRoutes.html b/docs/variables/state_transitState.validRideRoutes.html deleted file mode 100644 index dcd6c7d..0000000 --- a/docs/variables/state_transitState.validRideRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -validRideRoutes | mbus-backend
                                                                                                                                                                                                                                                                                                        mbus-backend
                                                                                                                                                                                                                                                                                                          Preparing search index...

                                                                                                                                                                                                                                                                                                          Variable validRideRoutesConst

                                                                                                                                                                                                                                                                                                          validRideRoutes: Set<string> = ...

                                                                                                                                                                                                                                                                                                          Set of currently valid ride route IDs.

                                                                                                                                                                                                                                                                                                          -
                                                                                                                                                                                                                                                                                                          diff --git a/docs/variables/state_transitState.validRoutes.html b/docs/variables/state_transitState.validRoutes.html deleted file mode 100644 index dd1e43a..0000000 --- a/docs/variables/state_transitState.validRoutes.html +++ /dev/null @@ -1,2 +0,0 @@ -validRoutes | mbus-backend
                                                                                                                                                                                                                                                                                                          mbus-backend
                                                                                                                                                                                                                                                                                                            Preparing search index...

                                                                                                                                                                                                                                                                                                            Variable validRoutesConst

                                                                                                                                                                                                                                                                                                            validRoutes: Set<string> = ...

                                                                                                                                                                                                                                                                                                            Set of currently valid route IDs.

                                                                                                                                                                                                                                                                                                            -
                                                                                                                                                                                                                                                                                                            diff --git a/tsconfig.json b/tsconfig.json index 10ce3c8..3422bf1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es2021", "module": "esnext", - // "moduleResolution": "Node", + "moduleResolution": "bundler", "esModuleInterop": true, "resolveJsonModule": true, "forceConsistentCasingInFileNames": true, From 6a0f8c13f7be0893eb7c74b8c26ea7ee67b21059 Mon Sep 17 00:00:00 2001 From: Edward Zhang Date: Mon, 20 Jul 2026 10:02:11 -0700 Subject: [PATCH 4/4] fix(docs): remove legacy files, export more things --- .github/workflows/ci.yml | 2 +- package.json | 2 +- src/legacy/busService-reminders.ts | 683 --------------------- src/legacy/busService.ts | 751 ------------------------ src/legacy/reminderService-reminders.ts | 240 -------- src/legacy/v3-reminders.ts | 660 --------------------- src/legacy/v3.ts | 561 ------------------ src/routes/api.ts | 7 +- src/services/reminder.ts | 4 +- src/services/reminderTypes.ts | 4 +- 10 files changed, 12 insertions(+), 2902 deletions(-) delete mode 100644 src/legacy/busService-reminders.ts delete mode 100644 src/legacy/busService.ts delete mode 100644 src/legacy/reminderService-reminders.ts delete mode 100644 src/legacy/v3-reminders.ts delete mode 100644 src/legacy/v3.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7647b6..64f2ccf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: run: npm i working-directory: ${{ github.workspace }} - name: Build Docs - run: npx typedoc --entryPointStrategy expand ./src --exclude \"**/legacy/**\" --treatWarningsAsErrors + run: npx typedoc --entryPointStrategy expand ./src --treatWarningsAsErrors working-directory: ${{ github.workspace }} - name: Sync files uses: SamKirkland/FTP-Deploy-Action@v4.4.0 diff --git a/package.json b/package.json index 64c5d38..2b7b90a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "start": "tsx src/app.ts", "test": "vitest run test", "stress-test": "vitest run test/search-stress.test.ts", - "docs": "typedoc --entryPointStrategy expand ./src --exclude \"**/legacy/**\"" + "docs": "typedoc --entryPointStrategy expand ./src" }, "author": "Efe Akinci", "license": "ISC", diff --git a/src/legacy/busService-reminders.ts b/src/legacy/busService-reminders.ts deleted file mode 100644 index 1ead44c..0000000 --- a/src/legacy/busService-reminders.ts +++ /dev/null @@ -1,683 +0,0 @@ -import * as process from "node:process"; - -import axios from 'axios'; -import dotenv from "dotenv"; -import { Route } from "@/types"; -import { - Trip, - StopTime, - Transfer, - StopID, - TransfersByOrigin, - Interchange -} from "./raptor/types"; - -dotenv.config(); - -const API_KEY = process.env.MBUS_API_KEY; -if (API_KEY === undefined) { - throw new Error("MBus API key not set."); -} - -const curBusPositions: { - buses: any[] -} = { - "buses": [] -} - -const cachedRoutes: {[k: string]: any} = {}; -type Prediction = { vid: string; stpid: string } & Record; - -let cachedPredsByVid: Record = {}; -let cachedPredsByStopId: Record = {}; -// routeTimingCache: route -> fromStop -> toStop -> latest diff (minutes) -const routeTimingCache: Record>> = -{ - "CN": { - "N434NORTHBOUND": { - "N500": { - "diff": 5, - "rtdir": "SOUTHBOUND", - "rtNext": "CS" - } - }, - }, - "CS":{ - "S002SOUTHBOUND": { - "S001": { - "diff": 5, - "rtdir": "NORTHBOUND", - "rtNext": "CN" - } - } - } -}; - -const validRoutes = new Set(); -let curRouteSelections = {}; -const routes = ["BB", "CN", "CS", "CSX", "DD", "MX", "NE", "NW", "NX", "OS", "NES", "WS", "WX"]; -let cachedStopLocations: { [stopId: string]: {name : string, lat: number, lon: number } } = { - -}; - -const message = {id: "gradamatation", title: "Congrats Grads 🥳", message: "Congrats to everyone who is gradamatating! Enjoy some grad hats on the buses, and don't forget to celebrate!", buildVersion: '99'} - -let cachedGraph: { - trips: Trip[]; - transfers: TransfersByOrigin; - interchange: Interchange; -} - -let stopIdToName: Record = {}; -let tatripidToRt: Record = {}; - -const sortStopTimesByRouteSequence = (stopTimes: StopTime[]): StopTime[] => { - if (stopTimes.length <= 1) return stopTimes; - - // Sort by arrival time - return stopTimes.sort((a, b) => a.arrivalTime - b.arrivalTime); -}; - -const rebuildGraph = async () => { - try { - const predictions = await getAllBusPredictions(); - if (!predictions || predictions.length === 0) { - return; - } - - // Build stopIdToName and tatripidToRt maps - stopIdToName = {}; - tatripidToRt = {}; - predictions.forEach((trip: any) => { - if (trip.tatripid && trip.stops && trip.stops.length > 0) { - // Find first stop with rt - const firstStopWithRt = trip.stops.find((stop: any) => stop.rt); - if (firstStopWithRt && firstStopWithRt.rt) { - tatripidToRt[trip.tatripid] = firstStopWithRt.rt; - } - } - trip.stops.forEach((stop: any) => { - if (stop.stpid && stop.stpnm) { - stopIdToName[stop.stpid] = stop.stpnm; - } - }); - }); - - const now = new Date(); - const currentTime = now.getUTCHours() * 3600 + now.getUTCMinutes() * 60 + now.getUTCSeconds(); - - const transfers = cachedGraph?.transfers || {}; - const interchange = cachedGraph?.interchange || {}; - - const allStops = new Set(); - predictions.forEach((trip: any) => { - trip.stops.forEach((stop: any) => { - allStops.add(stop.stpid); - }); - }); - - allStops.forEach(stopId => { - if (!transfers[stopId]) { - transfers[stopId] = []; - } - if (!interchange[stopId]) { - interchange[stopId] = 60; // 1 minute interchange time - } - }); - - const stopPredictions: Record = {}; - predictions.forEach((trip: any) => { - trip.stops.forEach((stop: any) => { - if (!stopPredictions[stop.stpid]) { - stopPredictions[stop.stpid] = []; - } - stopPredictions[stop.stpid].push({ - stpid: stop.stpid, - prdctdn: stop.prdctdn, - tatripid: trip.tatripid - }); - }); - }); - - const trips: Trip[] = []; - interface TripPrediction { - vid: string; - stops: { - stpid: string; - prdctdn: string; - rt: string; - }[]; - } - - const tripPredictions: Record = {}; - - predictions.forEach((trip: any) => { - if (!tripPredictions[trip.tatripid]) { - tripPredictions[trip.tatripid] = { - vid: trip.vid, - stops: [] - }; - } - trip.stops.forEach((stop: any) => { - tripPredictions[trip.tatripid].stops.push({ - stpid: stop.stpid, - prdctdn: stop.prdctdn, - rt: stop.rt - }); - }); - }); - - Object.entries(tripPredictions).forEach(([tripId, preds]) => { - // Create stop times with prediction times - const stopTimes: StopTime[] = preds.stops.map(pred => ({ - stop: pred.stpid, - arrivalTime: currentTime + (parseInt(pred.prdctdn) * 60), - departureTime: currentTime + (parseInt(pred.prdctdn) * 60), - pickUp: true, - dropOff: true, - rt: pred.rt - })); - - // Sort stop times by their sequence in the route - const sortedStopTimes = sortStopTimesByRouteSequence(stopTimes); - - trips.push({ - tripId, - vid: preds.vid, - stopTimes: sortedStopTimes - }); - }); - - - cachedGraph = { - trips, - transfers, - interchange - }; - - // Add virtual stops and their interchange - const originStopId = 'VIRTUAL_ORIGIN'; - const destStopId = 'VIRTUAL_DESTINATION'; - cachedGraph.transfers[originStopId] = []; - cachedGraph.transfers[destStopId] = []; - cachedGraph.interchange[originStopId] = 60; - cachedGraph.interchange[destStopId] = 60; - const virtualOriginTrip = { - tripId: 'VIRTUAL_ORIGIN_TRIP', - vid: null, - stopTimes: [{ - stop: originStopId, - arrivalTime: 0, - departureTime: 0, - pickUp: true, - dropOff: true - }] - }; - const virtualDestTrip = { - tripId: 'VIRTUAL_DESTINATION_TRIP', - vid: null, - stopTimes: [{ - stop: destStopId, - arrivalTime: 0, - departureTime: 0, - pickUp: true, - dropOff: true - }] - }; - cachedGraph.trips.push(virtualOriginTrip); - cachedGraph.trips.push(virtualDestTrip); - - } catch (error) { - console.error('Error rebuilding graph:', error); - } -}; - -const getAllBusPredictions = async () => { - try { - // Get all unique stop IDs from cached routes - const allStopIds = new Set(); - Object.values(cachedRoutes).forEach((routePatterns: any) => { - if (Array.isArray(routePatterns)) { - routePatterns.forEach((pattern: any) => { - if (pattern.pt && Array.isArray(pattern.pt)) { - pattern.pt.forEach((point: any) => { - if (point.stpid) { - allStopIds.add(point.stpid); - } - }); - } - }); - } - }); - - const stopIdsArray = Array.from(allStopIds); - const chunks = []; - - for (let i = 0; i < stopIdsArray.length; i += 10) { - chunks.push(stopIdsArray.slice(i, i + 10)); - } - - const predictions = await Promise.all( - chunks.map(async (chunk) => { - const stopIds = chunk.join(','); - const response = await axios.get(`https://mbus.ltp.umich.edu/bustime/api/v3/getpredictions`, { - params: { - requestType: 'getpredictions', - locale: 'en', - stpid: stopIds, - rt: routes.join(','), - tmres: 's', - rtpidatafeed: 'bustime', - key: API_KEY, - format: 'json' - } - }); - return response.data; - }) - ); - - const formattedPredictions = predictions.flat().reduce((acc, predictionChunk) => { - if (predictionChunk['bustime-response'] && predictionChunk['bustime-response']['prd']) { - predictionChunk['bustime-response']['prd'].forEach((prd: any) => { - const tatripid = prd.tatripid; - const stopName = prd.stpnm; - const stopId = prd.stpid; - const rt = prd.rt; - const rtdir = prd.rtdir; - const vid = prd.vid; - let prdctdn = prd.prdctdn; - prdctdn = prdctdn === "DUE" ? "1" : prdctdn; - - let trip = acc.find((t: any) => t.tatripid === tatripid); - - if (!trip) { - if (vid) { // if no trip, go by vid - trip = acc.find((t: any) => t.vid === vid); - } - } - - if (!trip) { // if no trip, create one - trip = { tatripid, vid, stops: [] }; - acc.push(trip); - } else { // merge with existing trip - if (!trip.tatripid) { - trip.tatripid = tatripid; - } - if (!trip.vid && vid) { - trip.vid = vid; - } - } - - let stop = trip.stops.find((s: any) => s.stpnm === stopName && s.stpid === stopId); - if (!stop) { - stop = { stpnm: stopName, stpid: stopId, prdctdn: null, rt: null, rtdir : null }; - trip.stops.push(stop); - } - stop.rtdir = rtdir; - stop.rt = rt; - stop.prdctdn = prdctdn; - }); - } - return acc; - }, []); - - // Cache predictions by vid and stopId - cachedPredsByVid = {}; - cachedPredsByStopId = {}; - predictions.flat().forEach((predictionChunk) => { - const prds = predictionChunk['bustime-response']?.['prd']; - if (!prds) return; - - prds.forEach((prd: Prediction) => { - const { vid, stpid } = prd; - // stpid -> [pred, pred...] - if (!cachedPredsByStopId[stpid]) { - cachedPredsByStopId[stpid] = []; - } - cachedPredsByStopId[stpid].push(prd); // store reference - - if (!vid) return; - // vid -> [pred, pred...] - if (!cachedPredsByVid[vid]) { - cachedPredsByVid[vid] = []; - } - cachedPredsByVid[vid].push(prd); - - }); - }); - - // Cache predictions per route in routeTimingCache for extrapolation - - // Record of stop ids in order using routes - const routeInfoFilter: Record = {}; - for (const [routeName, routeList] of Object.entries(cachedRoutes as Record)) { - for (const route of routeList) { - const rtdir = route.rtdir; - const routeKey = routeName + rtdir; - if (!routeInfoFilter[routeKey]) { - routeInfoFilter[routeKey] = []; - } - for (const point of route.pt) { - if (point.typ !== "W" && point.stpid) { - routeInfoFilter[routeKey].push({ stpid: point.stpid, rtdir }); - } - } - } - } - - const stopIdToName: Record = {}; - formattedPredictions.forEach((trip: any) => { - trip.stops.forEach((stop: any) => { - if (stop.stpid && stop.stpnm) stopIdToName[stop.stpid] = stop.stpnm; - }); - }); - - // Create indices for route -> stop order - const routeStopIndexMaps = new Map>(); - for (const [routeId, stopOrder] of Object.entries(routeInfoFilter)) { - const stopIndexMap = new Map(stopOrder.map(({ stpid }, i) => [stpid, i])); - routeStopIndexMaps.set(routeId, stopIndexMap); - } - - formattedPredictions.forEach((trip: any) => { - if(trip.stops.length == 0) return; - const minPrdctdn = Math.min(...trip.stops.map((s : any) => parseInt(s.prdctdn, 10))); - const firstRoute = trip.stops.find((s: any) => parseInt(s.prdctdn, 10) === minPrdctdn)?.rt; - - if (!firstRoute) return; - // Sort by predicted time - trip.stops.sort((a: any, b: any) => { - const diffTime = parseInt(a.prdctdn, 10) - parseInt(b.prdctdn, 10); - if (diffTime !== 0) return diffTime; // primary sort - - // If not same route, put first route in front - if (a.rt + a.rtdir !== b.rt + b.rtdir) { - if (a.rt === firstRoute) return -1; - if (b.rt === firstRoute) return 1; - - return a.rt.localeCompare(b.rt); - } - // If same route, sort by stop order - const aMap = routeStopIndexMaps.get(a.rt + a.rtdir); - const bMap = routeStopIndexMaps.get(b.rt + b.rtdir); - - const aIdx = aMap?.get(a.stpid) ?? Number.MAX_SAFE_INTEGER; - const bIdx = bMap?.get(b.stpid) ?? Number.MAX_SAFE_INTEGER; - return aIdx - bIdx; - }); - // Create edges based on sorted order - for (let i = 0; i < trip.stops.length - 1; i++) { - const from = trip.stops[i]; - const to = trip.stops[i + 1]; - const diff = parseInt(to.prdctdn, 10) - parseInt(from.prdctdn, 10); - const rt = from.rt; - - const stopIndexMap = routeStopIndexMaps.get(from.rt + from.rtdir); - if (!stopIndexMap) continue; - - const fromIdx = stopIndexMap.get(from.stpid); - const toIdx = stopIndexMap.get(to.stpid); - // Ensure valid follow up stop by idx or end of idx - const isValidFollowUp = ( - fromIdx !== undefined && - toIdx !== undefined && - (toIdx === fromIdx + 1 || fromIdx === stopIndexMap.size - 1) - ); - if (!isValidFollowUp) continue; - - if (!routeTimingCache[rt]) routeTimingCache[rt] = {}; - const fromKey = from.stpid + (from.rtdir || ""); - if (!routeTimingCache[rt][fromKey]) routeTimingCache[rt][fromKey] = {}; - routeTimingCache[rt][fromKey][to.stpid] = { - diff : diff, - rtdir: to.rtdir, - rtNext: to.rt - }; - } - }); - - // Extrapolate future stops based on routeTimingCache - formattedPredictions.forEach((trip: any) => { - let stopsAdded = 0; - while (stopsAdded < 20 && trip.stops.length > 0) { - const lastStop = trip.stops[trip.stops.length - 1]; - const rt = lastStop.rt; - if (!rt) break; - - const fromKey = lastStop.stpid + (lastStop.rtdir || ""); - const nextStops = routeTimingCache[rt]?.[fromKey]; - if (!nextStops) break; - - const nextEntries = Object.entries(nextStops); - if (nextEntries.length === 0) break; - - const [nextStopId, { diff, rtdir, rtNext}] = nextEntries[0]; - const nextPrdctdn = (parseInt(lastStop.prdctdn, 10) + diff).toString(); - - trip.stops.push({ - stpnm: stopIdToName[nextStopId] || nextStopId, - stpid: nextStopId, - prdctdn: nextPrdctdn, - rt : rtNext, - rtdir : rtdir - }); - stopsAdded++; - } - }); - - return formattedPredictions; - } catch (err: unknown) { - const message = err instanceof Error ? err.message : String(err); - console.error("Error in getAllBusPredictions:", message); - return []; - } -}; - -const client = axios.create({ - baseURL: 'https://mbus.ltp.umich.edu/bustime/api/v3/', - params: { - key: API_KEY, - format: 'json' - } -}); - -const getBuses = async () => { - const getChunk = async (routesChunk: string[]) => { - try { - const res = await client.get('/getvehicles', { - params: { requestType: 'getvehicles', rt: routesChunk.join(',') }, - }); - - if ( - 'bustime-response' in res.data && - 'vehicle' in res.data['bustime-response'] - ) { - return res.data['bustime-response']['vehicle']; - } - - return []; - } catch (error) { - console.warn('getChunk failed for routes', routesChunk, error instanceof Error ? error.message : error); - return []; - } - }; - - const chunks = [] - for (let i = 0; i < routes.length; i += 10) { - chunks.push(routes.slice(i, i + 10)); - } - - let buses = await Promise.all(chunks.map(getChunk)); - buses = buses.flat(); - - return buses; -} - -const updateBusPositions = async () => { - curBusPositions.buses = await getBuses(); -} - -const addToCachedRoutes = async (rt: string) => { - try { - const res = await client.get('/getpatterns', { - params: { - requestType: 'getpatterns', - rtpidatafeed: 'bustime', - rt: rt - } - }); - - if (res.data['bustime-response'] && res.data['bustime-response']['ptr']) { - cachedRoutes[rt] = res.data['bustime-response']['ptr']; - } - } catch (e) { - console.log(`Error while getting routes: ${e}`); - } -} - -const getSelectableRoutes = () => { - axios.get(`https://mbus.ltp.umich.edu/bustime/api/v3/getroutes?requestType=getroutes&locale=en&key=${API_KEY}&format=json`).then(res => { - curRouteSelections = res.data; - validRoutes.clear(); - try { - res.data['bustime-response']['routes'].forEach((e: Route) => { - validRoutes.add(e['rt']); - addToCachedRoutes(e['rt']); - }); - } catch (e) { - if (res.data['bustime-response'].error !== undefined) { - console.log(res.data['bustime-response'].error); - } - console.log(`Failed to parse valid routes: ${e}`); - } - }) - .catch((err) => console.log(`Error while getting selectable routes: ${err}`)) - .finally(async () => { - // Update transfers - try { - if (!cachedGraph) { - cachedGraph = { - trips: [], - transfers: {}, - interchange: {} - }; - } - // Rebuild stop locations cache from cached routes - cachedStopLocations = {}; - console.log("Caching Transfers..") - Object.values(cachedRoutes).forEach((routePatterns: any) => { - if (Array.isArray(routePatterns)) { - routePatterns.forEach((pattern: any) => { - if (pattern.pt && Array.isArray(pattern.pt)) { - pattern.pt.forEach((point: any) => { - if (point.stpid && point.lat && point.lon) { - cachedStopLocations[point.stpid] = { - name: point.stpnm, - lat: parseFloat(point.lat), - lon: parseFloat(point.lon) - }; - } - }); - } - }); - } - }); - - console.log(`Number of stop locations: ${Object.keys(cachedStopLocations).length}`); - - const WALKING_SPEED_KMH = 4; - const WALKING_SPEED_MS = WALKING_SPEED_KMH * 1000 / 3600; // Convert to m/s - - const routeStops = new Set(); - Object.values(cachedRoutes).forEach((routePatterns: any) => { - if (Array.isArray(routePatterns)) { - routePatterns.forEach((pattern: any) => { - if (pattern.pt && Array.isArray(pattern.pt)) { - pattern.pt.forEach((point: any) => { - if (point.stpid) { - routeStops.add(point.stpid); - } - }); - } - }); - } - }); - - routeStops.forEach(stopId => { - cachedGraph.transfers[stopId] = []; - }); - - routeStops.forEach(stopId => { - if (!cachedGraph.interchange[stopId]) { - cachedGraph.interchange[stopId] = 60; // 1 minute interchange time - } - }); - - // Create transfers between all stops - routeStops.forEach(stopId => { - routeStops.forEach(otherStopId => { - if (stopId !== otherStopId) { - const stop1 = cachedStopLocations[stopId]; - const stop2 = cachedStopLocations[otherStopId]; - - let transferDuration: number; - - if (stop1 && stop2) { - // Compute diff with lat and lon - const latDiff = (stop2.lat - stop1.lat) * 111320; - const lonDiff = (stop2.lon - stop1.lon) * 111320 * Math.cos(stop1.lat * Math.PI / 180); - const distance = Math.sqrt(latDiff * latDiff + lonDiff * lonDiff); - let walkingTimeSeconds = distance / WALKING_SPEED_MS; - // if (distance > 1200) { - // walkingTimeSeconds *= 1.5; // penatly for too big distances - // } - transferDuration = Math.round(walkingTimeSeconds); - } else { - console.log('Invalid stop'); - transferDuration = 60000; - } - const existingTransfer = cachedGraph.transfers[stopId].find(t => t.destination === otherStopId); - - if (existingTransfer) { - existingTransfer.duration = transferDuration; - } else { - const transfer: Transfer = { - origin: stopId, - destination: otherStopId, - duration: transferDuration, - startTime: 0, - endTime: Number.MAX_SAFE_INTEGER - }; - cachedGraph.transfers[stopId].push(transfer); - } - } - }); - }); - - const totalTransfers = Object.values(cachedGraph.transfers).reduce((total, transfers) => total + transfers.length, 0); - console.log(`Total transfers in cachedGraph: ${totalTransfers}`); - } catch (error) { - console.error('Error updating transfers:', error); - } - }); -} - -export { - curBusPositions, - cachedRoutes, - cachedPredsByVid, - cachedPredsByStopId, - validRoutes, - curRouteSelections, - routes, - cachedStopLocations, - routeTimingCache, - cachedGraph, - stopIdToName, - tatripidToRt, - getAllBusPredictions, - updateBusPositions, - getSelectableRoutes, - rebuildGraph -}; - diff --git a/src/legacy/busService.ts b/src/legacy/busService.ts deleted file mode 100644 index bccae67..0000000 --- a/src/legacy/busService.ts +++ /dev/null @@ -1,751 +0,0 @@ -import * as process from "node:process"; -import * as fs from 'fs'; -import * as path from 'path'; -import * as walking from '../walking/walkingMap'; - -import axios from 'axios'; -import dotenv from "dotenv"; -import { Route } from "@/types"; -import { - Trip, - StopTime, - Transfer, - StopID, - TransfersByOrigin, - Interchange -} from "../raptor/types"; - -import { writeFileSync, readFileSync, existsSync } from "fs"; - -dotenv.config(); - -const API_KEY = process.env.MBUS_API_KEY; -if (API_KEY === undefined) { - throw new Error("MBus API key not set."); -} - -const curBusPositions: { - buses: any[] -} = { - "buses": [] -} - -const cachedRoutes: { [k: string]: any } = {}; -type Prediction = { vid: string; stpid: string } & Record; - -let cachedPredsByVid: Record = {}; -let cachedPredsByStopId: Record = {}; -// routeTimingCache: route -> fromStop -> toStop -> latest diff (minutes) -const routeTimingCache: Record>> = -{ - "CN": { - "N434NORTHBOUND": { - "N500": { - "diff": 5, - "rtdir": "SOUTHBOUND", - "rtNext": "CS" - } - }, - }, - "CS": { - "S002SOUTHBOUND": { - "S001": { - "diff": 5, - "rtdir": "NORTHBOUND", - "rtNext": "CN" - } - } - } -}; - -const validRoutes = new Set(); -let curRouteSelections = {}; -const routes = ["BB", "CN", "CS", "CSX", "DD", "MX", "NE", "NW", "NX", "OS", "NES", "WS", "WX"]; -let cachedStopLocations: { [stopId: string]: { name: string, lat: number, lon: number } } = { - -}; - -const message = { id: "gradamatation", title: "Congrats Grads 🥳", message: "Congrats to everyone who is gradamatating! Enjoy some grad hats on the buses, and don't forget to celebrate!", buildVersion: '99' } - -let cachedGraph: { - trips: Trip[]; - transfers: TransfersByOrigin; - interchange: Interchange; -} - -let stopIdToName: Record = {}; -let tatripidToRt: Record = {}; - -const sortStopTimesByRouteSequence = (stopTimes: StopTime[]): StopTime[] => { - if (stopTimes.length <= 1) return stopTimes; - - // Sort by arrival time - return stopTimes.sort((a, b) => a.arrivalTime - b.arrivalTime); -}; - -const rebuildGraph = async () => { - if (process.env.DEV_CACHE === 'true') { - if (cachedGraph && cachedGraph.trips && cachedGraph.trips.length > 0) return; - try { - const filePath = path.resolve(process.cwd(), 'saved_graph.json'); - if (fs.existsSync(filePath)) { - const data = JSON.parse(fs.readFileSync(filePath, 'utf8')); - cachedGraph = data.graph; - cachedStopLocations = data.stopLocations; - stopIdToName = data.stopNames; - cachedPredsByVid = data.predsByVid || {}; - cachedPredsByStopId = data.predsByStopId || {}; - console.log('Loaded graph and state from saved_graph.json'); - } else { - console.warn('DEV_CACHE set but saved_graph.json not found'); - } - } catch (err) { - console.error('Error loading cached graph:', err); - } - return; - } - try { - const predictions = await getAllBusPredictions(); - if (!predictions || predictions.length === 0) { - return; - } - - // Build stopIdToName and tatripidToRt maps - stopIdToName = {}; - tatripidToRt = {}; - predictions.forEach((trip: any) => { - if (trip.tatripid && trip.stops && trip.stops.length > 0) { - // Find first stop with rt - const firstStopWithRt = trip.stops.find((stop: any) => stop.rt); - if (firstStopWithRt && firstStopWithRt.rt) { - tatripidToRt[trip.tatripid] = firstStopWithRt.rt; - } - } - trip.stops.forEach((stop: any) => { - if (stop.stpid && stop.stpnm) { - stopIdToName[stop.stpid] = stop.stpnm; - } - }); - }); - - const now = new Date(); - const currentTime = now.getUTCHours() * 3600 + now.getUTCMinutes() * 60 + now.getUTCSeconds(); - - const transfers = cachedGraph?.transfers || {}; - const interchange = cachedGraph?.interchange || {}; - - const allStops = new Set(); - predictions.forEach((trip: any) => { - trip.stops.forEach((stop: any) => { - allStops.add(stop.stpid); - }); - }); - - allStops.forEach(stopId => { - if (!transfers[stopId]) { - transfers[stopId] = []; - } - if (!interchange[stopId]) { - interchange[stopId] = 30; // 30 seconds interchange time - } - }); - - const stopPredictions: Record = {}; - predictions.forEach((trip: any) => { - trip.stops.forEach((stop: any) => { - if (!stopPredictions[stop.stpid]) { - stopPredictions[stop.stpid] = []; - } - stopPredictions[stop.stpid].push({ - stpid: stop.stpid, - prdctdn: stop.prdctdn, - tatripid: trip.tatripid - }); - }); - }); - - const trips: Trip[] = []; - interface TripPrediction { - vid: string; - stops: { - stpid: string; - prdctdn: string; - rt: string; - }[]; - } - - const tripPredictions: Record = {}; - - predictions.forEach((trip: any) => { - if (!tripPredictions[trip.tatripid]) { - tripPredictions[trip.tatripid] = { - vid: trip.vid, - stops: [] - }; - } - trip.stops.forEach((stop: any) => { - tripPredictions[trip.tatripid].stops.push({ - stpid: stop.stpid, - prdctdn: stop.prdctdn, - rt: stop.rt - }); - }); - }); - - Object.entries(tripPredictions).forEach(([tripId, preds]) => { - // Create stop times with prediction times - const stopTimes: StopTime[] = preds.stops.map(pred => ({ - stop: pred.stpid, - arrivalTime: currentTime + (parseInt(pred.prdctdn) * 60), - departureTime: currentTime + (parseInt(pred.prdctdn) * 60), - pickUp: true, - dropOff: true, - rt: pred.rt - })); - - // Sort stop times by their sequence in the route - const sortedStopTimes = sortStopTimesByRouteSequence(stopTimes); - - trips.push({ - tripId, - vid: preds.vid, - stopTimes: sortedStopTimes - }); - }); - - - cachedGraph = { - trips, - transfers, - interchange - }; - - // Add virtual stops and their interchange - const originStopId = 'VIRTUAL_ORIGIN'; - const destStopId = 'VIRTUAL_DESTINATION'; - cachedGraph.transfers[originStopId] = []; - cachedGraph.transfers[destStopId] = []; - cachedGraph.interchange[originStopId] = 30; - cachedGraph.interchange[destStopId] = 30; - const virtualOriginTrip = { - tripId: 'VIRTUAL_ORIGIN_TRIP', - vid: null, - stopTimes: [{ - stop: originStopId, - arrivalTime: 0, - departureTime: 0, - pickUp: true, - dropOff: true - }] - }; - const virtualDestTrip = { - tripId: 'VIRTUAL_DESTINATION_TRIP', - vid: null, - stopTimes: [{ - stop: destStopId, - arrivalTime: 0, - departureTime: 0, - pickUp: true, - dropOff: true - }] - }; - cachedGraph.trips.push(virtualOriginTrip); - cachedGraph.trips.push(virtualDestTrip); - - } catch (error) { - console.error('Error rebuilding graph:', error); - } -}; - -const getAllBusPredictions = async () => { - try { - // Get all unique stop IDs from cached routes - const allStopIds = new Set(); - Object.values(cachedRoutes).forEach((routePatterns: any) => { - if (Array.isArray(routePatterns)) { - routePatterns.forEach((pattern: any) => { - if (pattern.pt && Array.isArray(pattern.pt)) { - pattern.pt.forEach((point: any) => { - if (point.stpid) { - allStopIds.add(point.stpid); - } - }); - } - }); - } - }); - - const stopIdsArray = Array.from(allStopIds); - const chunks = []; - - if (process.env.DEV_CACHE === 'true') { - return []; - } - - for (let i = 0; i < stopIdsArray.length; i += 10) { - chunks.push(stopIdsArray.slice(i, i + 10)); - } - - let formattedPredictions = []; - - - cachedPredsByVid = {}; - cachedPredsByStopId = {}; - - if (process.env.DEV === 'true') { - // In DEV mode, load static dummy data instead of fetching from the live API - try { - const dummyDataPath = path.resolve(process.cwd(), 'dummy_bus_data.json'); - const dummyData = fs.readFileSync(dummyDataPath, 'utf8'); - formattedPredictions = JSON.parse(dummyData); - - // Populate internal caches from the loaded dummy data - formattedPredictions.forEach((trip: any) => { - const vid = trip.vid; - trip.stops.forEach((stop: any) => { - const stpid = stop.stpid; - const prd: Prediction = { - tmstmp: new Date().toISOString(), - typ: "A", - stpnm: stop.stpnm, - stpid: stop.stpid, - vid: vid, - dstp: 0, - rt: stop.rt, - rtdd: stop.rt, - rtdir: stop.rtdir, - des: "", - prdctdn: stop.prdctdn, - tablockid: "", - tatripid: trip.tatripid, - dly: false, - prdctm: "", - zone: "" - }; - - if (!cachedPredsByStopId[stpid]) { - cachedPredsByStopId[stpid] = []; - } - cachedPredsByStopId[stpid].push(prd); - - if (vid) { - if (!cachedPredsByVid[vid]) { - cachedPredsByVid[vid] = []; - } - cachedPredsByVid[vid].push(prd); - } - }); - }); - - } catch (err) { - console.error('Error loading dummy bus data:', err); - formattedPredictions = []; - } - } else { - const predictions = await Promise.all( - chunks.map(async (chunk) => { - const stopIds = chunk.join(','); - const response = await axios.get(`https://mbus.ltp.umich.edu/bustime/api/v3/getpredictions`, { - params: { - requestType: 'getpredictions', - locale: 'en', - stpid: stopIds, - rt: routes.join(','), - tmres: 's', - rtpidatafeed: 'bustime', - key: API_KEY, - format: 'json' - } - }); - return response.data; - }) - ); - - formattedPredictions = predictions.flat().reduce((acc, predictionChunk) => { - if (predictionChunk['bustime-response'] && predictionChunk['bustime-response']['prd']) { - predictionChunk['bustime-response']['prd'].forEach((prd: any) => { - const tatripid = prd.tatripid; - const stopName = prd.stpnm; - const stopId = prd.stpid; - const rt = prd.rt; - const rtdir = prd.rtdir; - const vid = prd.vid; - let prdctdn = prd.prdctdn; - prdctdn = prdctdn === "DUE" ? "1" : prdctdn; - - let trip = acc.find((t: any) => t.tatripid === tatripid); - - if (!trip) { - if (vid) { - trip = acc.find((t: any) => t.vid === vid); - } - } - - if (!trip) { - trip = { tatripid, vid, stops: [] }; - acc.push(trip); - } else { - if (!trip.tatripid) { - trip.tatripid = tatripid; - } - if (!trip.vid && vid) { - trip.vid = vid; - } - } - - let stop = trip.stops.find((s: any) => s.stpnm === stopName && s.stpid === stopId); - if (!stop) { - stop = { stpnm: stopName, stpid: stopId, prdctdn: null, rt: null, rtdir: null }; - trip.stops.push(stop); - } - stop.rtdir = rtdir; - stop.rt = rt; - stop.prdctdn = prdctdn; - }); - } - return acc; - }, []); - - predictions.flat().forEach((predictionChunk) => { - const prds = predictionChunk['bustime-response']?.['prd']; - if (!prds) return; - - prds.forEach((prd: Prediction) => { - const { vid, stpid } = prd; - if (!cachedPredsByStopId[stpid]) { - cachedPredsByStopId[stpid] = []; - } - cachedPredsByStopId[stpid].push(prd); - - if (!vid) return; - if (!cachedPredsByVid[vid]) { - cachedPredsByVid[vid] = []; - } - cachedPredsByVid[vid].push(prd); - - }); - }); - } - - - // Cache predictions per route in routeTimingCache for extrapolation - - // Record of stop ids in order using routes - const routeInfoFilter: Record = {}; - for (const [routeName, routeList] of Object.entries(cachedRoutes as Record)) { - for (const route of routeList) { - const rtdir = route.rtdir; - const routeKey = routeName + rtdir; - if (!routeInfoFilter[routeKey]) { - routeInfoFilter[routeKey] = []; - } - for (const point of route.pt) { - if (point.typ !== "W" && point.stpid) { - routeInfoFilter[routeKey].push({ stpid: point.stpid, rtdir }); - } - } - } - } - - const stopIdToName: Record = {}; - formattedPredictions.forEach((trip: any) => { - trip.stops.forEach((stop: any) => { - if (stop.stpid && stop.stpnm) stopIdToName[stop.stpid] = stop.stpnm; - }); - }); - - // Create indices for route -> stop order - const routeStopIndexMaps = new Map>(); - for (const [routeId, stopOrder] of Object.entries(routeInfoFilter)) { - const stopIndexMap = new Map(stopOrder.map(({ stpid }, i) => [stpid, i])); - routeStopIndexMaps.set(routeId, stopIndexMap); - } - - formattedPredictions.forEach((trip: any) => { - if (trip.stops.length == 0) return; - const minPrdctdn = Math.min(...trip.stops.map((s: any) => parseInt(s.prdctdn, 10))); - const firstRoute = trip.stops.find((s: any) => parseInt(s.prdctdn, 10) === minPrdctdn)?.rt; - - if (!firstRoute) return; - // Sort by predicted time - trip.stops.sort((a: any, b: any) => { - const diffTime = parseInt(a.prdctdn, 10) - parseInt(b.prdctdn, 10); - if (diffTime !== 0) return diffTime; // primary sort - - // If not same route, put first route in front - if (a.rt + a.rtdir !== b.rt + b.rtdir) { - if (a.rt === firstRoute) return -1; - if (b.rt === firstRoute) return 1; - - return a.rt.localeCompare(b.rt); - } - // If same route, sort by stop order - const aMap = routeStopIndexMaps.get(a.rt + a.rtdir); - const bMap = routeStopIndexMaps.get(b.rt + b.rtdir); - - const aIdx = aMap?.get(a.stpid) ?? Number.MAX_SAFE_INTEGER; - const bIdx = bMap?.get(b.stpid) ?? Number.MAX_SAFE_INTEGER; - return aIdx - bIdx; - }); - // Create edges based on sorted order - for (let i = 0; i < trip.stops.length - 1; i++) { - const from = trip.stops[i]; - const to = trip.stops[i + 1]; - const diff = parseInt(to.prdctdn, 10) - parseInt(from.prdctdn, 10); - const rt = from.rt; - - const stopIndexMap = routeStopIndexMaps.get(from.rt + from.rtdir); - if (!stopIndexMap) continue; - - const fromIdx = stopIndexMap.get(from.stpid); - const toIdx = stopIndexMap.get(to.stpid); - // Ensure valid follow up stop by idx or end of idx - const isValidFollowUp = ( - fromIdx !== undefined && - toIdx !== undefined && - (toIdx === fromIdx + 1 || fromIdx === stopIndexMap.size - 1) - ); - if (!isValidFollowUp) continue; - - if (!routeTimingCache[rt]) routeTimingCache[rt] = {}; - const fromKey = from.stpid + (from.rtdir || ""); - if (!routeTimingCache[rt][fromKey]) routeTimingCache[rt][fromKey] = {}; - routeTimingCache[rt][fromKey][to.stpid] = { - diff: diff, - rtdir: to.rtdir, - rtNext: to.rt - }; - } - }); - - // Extrapolate future stops based on routeTimingCache - formattedPredictions.forEach((trip: any) => { - let stopsAdded = 0; - while (stopsAdded < 20 && trip.stops.length > 0) { - const lastStop = trip.stops[trip.stops.length - 1]; - const rt = lastStop.rt; - if (!rt) break; - - const fromKey = lastStop.stpid + (lastStop.rtdir || ""); - const nextStops = routeTimingCache[rt]?.[fromKey]; - if (!nextStops) break; - - const nextEntries = Object.entries(nextStops); - if (nextEntries.length === 0) break; - - const [nextStopId, { diff, rtdir, rtNext }] = nextEntries[0]; - const nextPrdctdn = (parseInt(lastStop.prdctdn, 10) + diff).toString(); - - trip.stops.push({ - stpnm: stopIdToName[nextStopId] || nextStopId, - stpid: nextStopId, - prdctdn: nextPrdctdn, - rt: rtNext, - rtdir: rtdir - }); - stopsAdded++; - } - }); - - return formattedPredictions; - } catch (err: unknown) { - const message = err instanceof Error ? err.message : String(err); - console.error("Error in getAllBusPredictions:", message); - return []; - } -}; - -const client = axios.create({ - baseURL: 'https://mbus.ltp.umich.edu/bustime/api/v3/', - params: { - key: API_KEY, - format: 'json' - } -}); - -const getBuses = async () => { - const getChunk = async (routesChunk: string[]) => { - try { - const res = await client.get('/getvehicles', { - params: { requestType: 'getvehicles', rt: routesChunk.join(',') }, - }); - - if ( - 'bustime-response' in res.data && - 'vehicle' in res.data['bustime-response'] - ) { - return res.data['bustime-response']['vehicle']; - } - - return []; - } catch (error) { - console.warn('getChunk failed for routes', routesChunk, error instanceof Error ? error.message : error); - return []; - } - }; - - const chunks = [] - for (let i = 0; i < routes.length; i += 10) { - chunks.push(routes.slice(i, i + 10)); - } - - let buses = await Promise.all(chunks.map(getChunk)); - buses = buses.flat(); - - return buses; -} - -const updateBusPositions = async () => { - curBusPositions.buses = await getBuses(); -} - -const addToCachedRoutes = async (rt: string) => { - try { - const res = await client.get('/getpatterns', { - params: { - requestType: 'getpatterns', - rtpidatafeed: 'bustime', - rt: rt - } - }); - - - if (res.data['bustime-response'] && res.data['bustime-response']['ptr']) { - cachedRoutes[rt] = res.data['bustime-response']['ptr']; - } - } catch (e) { - console.log(`Error while getting routes: ${e}`); - } -} - -const getSelectableRoutes = () => { - if (process.env.DEV_CACHE === 'true') return; - - axios.get(`https://mbus.ltp.umich.edu/bustime/api/v3/getroutes?requestType=getroutes&locale=en&key=${API_KEY}&format=json`).then(async res => { - curRouteSelections = res.data; - validRoutes.clear(); - try { - const promises: Promise[] = []; - res.data['bustime-response']['routes'].forEach((e: Route) => { - validRoutes.add(e['rt']); - promises.push(addToCachedRoutes(e['rt'])); - }); - await Promise.all(promises); - } catch (e) { - if (res.data['bustime-response'].error !== undefined) { - console.log(res.data['bustime-response'].error); - } - console.log(`Failed to parse valid routes: ${e}`); - } - }) - .catch((err) => console.log(`Error while getting selectable routes: ${err}`)) - .finally(async () => { - // Update transfers - try { - if (!cachedGraph) { - cachedGraph = { - trips: [], - transfers: {}, - interchange: {} - }; - } - // Rebuild stop locations cache from cached routes - cachedStopLocations = {}; - console.log("Caching Transfers..") - Object.values(cachedRoutes).forEach((routePatterns: any) => { - if (Array.isArray(routePatterns)) { - routePatterns.forEach((pattern: any) => { - if (pattern.pt && Array.isArray(pattern.pt)) { - pattern.pt.forEach((point: any) => { - if (point.stpid && point.lat && point.lon) { - cachedStopLocations[point.stpid] = { - name: point.stpnm, - lat: parseFloat(point.lat), - lon: parseFloat(point.lon) - }; - } - }); - } - }); - } - }); - - console.log(`Number of stop locations: ${Object.keys(cachedStopLocations).length}`); - walking.buildStopNodeMap(cachedStopLocations); - - const routeStops = new Set(); - Object.values(cachedRoutes).forEach((routePatterns: any) => { - if (Array.isArray(routePatterns)) { - routePatterns.forEach((pattern: any) => { - if (pattern.pt && Array.isArray(pattern.pt)) { - pattern.pt.forEach((point: any) => { - if (point.stpid) { - routeStops.add(point.stpid); - } - }); - } - }); - } - }); - - routeStops.forEach(stopId => { - cachedGraph.transfers[stopId] = []; - }); - - routeStops.forEach(stopId => { - if (!cachedGraph.interchange[stopId]) { - cachedGraph.interchange[stopId] = 30; // 30 seconds interchange time - } - }); - - // Create transfers between all stops - await walking.ensureCacheForStops(routeStops, cachedStopLocations); - - routeStops.forEach(stopId => { - routeStops.forEach(otherStopId => { - if (stopId !== otherStopId) { - - const cachedData = walking.getCachedWalk(stopId, otherStopId); - - if (cachedData) { - cachedGraph.transfers[stopId].push({ - origin: stopId, - destination: otherStopId, - duration: cachedData.duration, - startTime: 0, - endTime: Number.MAX_SAFE_INTEGER - }); - } else { - console.warn(`Unexpected missing walk data: ${stopId} -> ${otherStopId}`); - } - } - }); - }); - - const totalTransfers = Object.values(cachedGraph.transfers).reduce((total, t) => total + t.length, 0); - console.log(`Total transfers in cachedGraph: ${totalTransfers}`); - - } catch (error) { - console.error('Error updating transfers:', error); - } - }); -} - -export { - curBusPositions, - cachedRoutes, - cachedPredsByVid, - cachedPredsByStopId, - validRoutes, - curRouteSelections, - routes, - cachedStopLocations, - routeTimingCache, - cachedGraph, - stopIdToName, - tatripidToRt, - getAllBusPredictions, - updateBusPositions, - getSelectableRoutes, - rebuildGraph -}; diff --git a/src/legacy/reminderService-reminders.ts b/src/legacy/reminderService-reminders.ts deleted file mode 100644 index b997fcd..0000000 --- a/src/legacy/reminderService-reminders.ts +++ /dev/null @@ -1,240 +0,0 @@ -import dotenv from "dotenv"; -import { cachedPredsByStopId, stopIdToName } from "./busService"; -import { getMessaging } from "firebase-admin/messaging"; -import { applicationDefault, initializeApp } from "firebase-admin/app"; - -dotenv.config() - -// Initialize Firebase -initializeApp({ credential: applicationDefault() }); - -type Event = { - stpid: string, - rtid: string, - readonly __brand: "event" -} - -type RegistrationToken = string & { readonly __brand: "registration_token" } -type EventKey = string & { readonly __brand: "event_key" } - -function encodeEvent(e: Event): EventKey { - return `${e.stpid}|${e.rtid}` as EventKey; -} - -function decodeEvent(e: EventKey): Event { - const split = e.split('|'); - return { stpid: split[0], rtid: split[1] } as Event; -} - -// Subscriptions go through a pipeline, starting in the waiting for reminder -// stage. After the bus in x minutes notification is set they move to the -// waiting for bus stage, where they stay until the bus is arriving notification -// is sent. Being in the second stage is repsented by having a threshold of null. -class ReminderSubscriptions { - // a thresh of null means being in the second stage - subscriptions: Array<{ event: Event, thresh: number | null, token: RegistrationToken }> - - constructor() { - this.subscriptions = []; - } - - // addition is done to the start of the pipeline - add(event: Event, thresh: number, token: RegistrationToken) { - console.log("Adding a reminder subscription"); - this.subscriptions.push({ event, thresh, token }); - } - - // removes all subscriptions involving both `event` and `token` - remove(event: Event, token: RegistrationToken) { - console.log("Removing a reminder subscription"); - this.subscriptions = this.subscriptions - .filter((s) => s.event.rtid !== event.rtid || s.event.stpid !== event.stpid || s.token !== token); - } - - // updates the status of all registrations, returning an object representing the - // notifications that should be sent - process(arrivalTimes: Map): { - reminder: Map>, - atTheStop: Map>, - disappeared: Map>, - delayed: Map> - } { - const addHelper = (map: Map>, key: EventKey, token: RegistrationToken) => { - let tokens = map.get(key); - if (tokens === undefined) { - map.set(key, new Set()); - tokens = map.get(key)!; - } - tokens.add(token); - }; - const notifications = { - reminder: new Map(), atTheStop: new Map(), disappeared: new Map(), delayed: new Map() - }; - const newSubscriptions: typeof this.subscriptions = []; - for (const subscription of this.subscriptions) { - const key = encodeEvent(subscription.event); - const arrivalTime = arrivalTimes.get(key); - if (arrivalTime === undefined || arrivalTime.curr === null) { - addHelper(notifications.disappeared, key, subscription.token); - } else if (subscription.thresh === null && arrivalTime.curr === 0) { - addHelper(notifications.atTheStop, key, subscription.token); - } else if (arrivalTime.prev !== null && arrivalTime.curr > arrivalTime.prev) { - addHelper(notifications.delayed, key, subscription.token); - newSubscriptions.push(subscription); // keep subscription if delayed - } else if (subscription.thresh !== null && arrivalTime.prev !== null - && arrivalTime.curr <= subscription.thresh && arrivalTime.curr < arrivalTime.prev) { - addHelper(notifications.reminder, key, subscription.token); - // replace with next in pipeline, a subscription to bus at stop - newSubscriptions.push({ event: subscription.event, thresh: null, token: subscription.token }); - } else { - newSubscriptions.push(subscription); // keep subscription by default - } - } - this.subscriptions = newSubscriptions; - console.log(`Process completed with ${notifications.reminder.size}, ${notifications.atTheStop.size}, ${notifications.delayed.size}, ${notifications.disappeared.size}`); - return notifications; - } - - // removes all subscriptions involving `event` - removeAllFor(event: Event) { - this.subscriptions = this.subscriptions - .filter((s) => s.event.rtid !== event.rtid || s.event.stpid !== event.stpid); - } - - swapToken(from: RegistrationToken, to: RegistrationToken) { - this.subscriptions = this.subscriptions.map((s) => { - if (s.token === from) { - return { ...s, token: to }; - } else { - return s; - } - }); - } - - activeRemindersFor(id: RegistrationToken): Array<{ stpid: string, rtid: string, thresh: number | null }> { - return this.subscriptions - .filter((s) => s.token === id) - .map((s) => { - return {stpid: s.event.stpid, rtid: s.event.rtid, thresh: s.thresh }; - }); - } - - describe() { - console.log(`There are ${this.subscriptions.length} reminder subscriptions`); - } -} - -const reminderSubscriptions = new ReminderSubscriptions(); -const arrivalTimes: Map = new Map(); - -function processReminders() { - // move current arrival times to prev - for (const [_k, v] of arrivalTimes) { - v.prev = v.curr; - v.curr = null; - } - - const stpids = Object.keys(cachedPredsByStopId); - // determine arrival time updates for each stop - for (const stpid of stpids) { - for (const vehicle of cachedPredsByStopId[stpid]) { - const rtid = vehicle.rt; - const prediction = vehicle.prdctdn === 'DUE' ? 0 : parseInt(vehicle.prdctdn); - const key = encodeEvent({ stpid: stpid, rtid: rtid } as Event); - let time = arrivalTimes.get(key); - if (time === undefined) { - arrivalTimes.set(key, { curr: null, prev: null }); - time = arrivalTimes.get(key)!; - } - if (time.curr === null || prediction < time.curr) - time.curr = prediction; - } - } - - // send push notifications as needed - const notifications = reminderSubscriptions.process(arrivalTimes); - for (const [eventKey, tokens] of notifications.reminder) { - const event = decodeEvent(eventKey); - const stopName = stopIdToName[event.stpid] ?? event.stpid; - sendToAll( - { - notification: { - title: 'Bus Arrival Reminder', - body: `${event.rtid} is ${arrivalTimes.get(eventKey)?.curr} minute(s) away from ${stopName}` - } - }, - tokens - ); - } - for (const [eventKey, tokens] of notifications.atTheStop) { - const event = decodeEvent(eventKey); - const stopName = stopIdToName[event.stpid] ?? event.stpid; - sendToAll( - { - notification: { title: 'Bus Arriving', body: `${event.rtid} is almost at ${stopName}` }, - }, - tokens - ); - } - for (const [eventKey, tokens] of notifications.delayed) { - const event = decodeEvent(eventKey); - const stopName = stopIdToName[event.stpid] ?? event.stpid; - const arrivalTime = arrivalTimes.get(eventKey); - const delay = arrivalTime?.curr !== null && arrivalTime?.prev ? `${arrivalTime.curr - arrivalTime.prev}` : `some`; - sendToAll( - { - notification: { - title: `Bus Delayed`, - body: `The ${event.rtid} bus en route to ${stopName} got delayed by ${delay} minute(s).` - } - }, - tokens - ); - } - for (const [eventKey, tokens] of notifications.disappeared) { - const event = decodeEvent(eventKey); - const stopName = stopIdToName[event.stpid] ?? event.stpid; - sendToAll( - { - notification: { - title: `Bus Disappeared`, - body: `The ${event.rtid} bus en route to ${stopName} disappeared! Set a new reminder if desired.` - } - }, - tokens - ); - } - -} - -function sendToAll(msg: any, tokens: Set) { - console.log(`sending a message to ${tokens.size} devices`); - const group = new Set(); - for (const token of tokens) { - if (group.size === 500) { - sendToAllHelper(msg, group); - group.clear(); - } - group.add(token); - } - sendToAllHelper(msg, group); -} - -// REQUIRES: tokens.size <= 500 -function sendToAllHelper(msg: any, tokens: Set) { - const payload = { tokens: Array.from(tokens), ...msg }; - getMessaging().sendEachForMulticast(payload) - .then((res) => { - if (res.failureCount > 0) { - console.log(`${res.failureCount} messages failed to send!`); - res.responses.forEach((res, idx) => { - if (!res.success) { - console.log(`message send ${idx} failed`); - console.log(res.error); - } - }) - } - }); -} - -export { processReminders, reminderSubscriptions, Event, RegistrationToken }; diff --git a/src/legacy/v3-reminders.ts b/src/legacy/v3-reminders.ts deleted file mode 100644 index b01d078..0000000 --- a/src/legacy/v3-reminders.ts +++ /dev/null @@ -1,660 +0,0 @@ -import express from "express"; -import dotenv from "dotenv"; -import { - Transfer, - StopID, - TimetableLeg -} from "./raptor/types"; -import { RaptorAlgorithm } from "./raptor/RaptorAlgorithm"; -import { RaptorAlgorithmFactory } from "./raptor/RaptorAlgorithmFactory"; -import { DepartAfterQuery } from "./query/DepartAfterQuery"; -import { JourneyFactory } from "./results/JourneyFactory"; -import { earliestArrival, leastChanges, leastWalking } from "./results/filter/MultipleCriteriaFilter"; - -import * as metadata from "./assets/route-data.json"; -import * as valid_assets from "./assets/valid_assets.json"; -import * as path from "node:path"; -import { MaxPriorityQueue } from '@datastructures-js/priority-queue'; - - -import { - curBusPositions, - cachedPredsByStopId, - cachedRoutes, - cachedPredsByVid, - cachedStopLocations, - curRouteSelections, - stopIdToName, - tatripidToRt, - getAllBusPredictions, - routeTimingCache, - cachedGraph, - updateBusPositions, - getSelectableRoutes, - rebuildGraph -} from './busService'; -import axios from "axios"; - -// Simple Bus Color System -interface BusRoute { - routeId: string; - color: string; - image: string; -} - -class BusColorManager { - private readonly routes: BusRoute[] = [ - { routeId: "BB", color: "#2F773F", image: "bus_BB.png" }, - { routeId: "CN", color: "#643076", image: "bus_CN.png" }, - { routeId: "CS", color: "#3559B8", image: "bus_CS.png" }, - { routeId: "CSX", color: "#1C2256", image: "bus_CSX.png" }, - { routeId: "DD", color: "#A9C534", image: "bus_DD.png" }, - { routeId: "MX", color: "#5EC7DE", image: "bus_MX.png" }, - { routeId: "NE", color: "#C55188", image: "bus_NE.png" }, - { routeId: "NW", color: "#AE3636", image: "bus_NW.png" }, - { routeId: "NX", color: "#DA4343", image: "bus_NX.png" }, - { routeId: "OS", color: "#E8A43C", image: "bus_OS.png" }, - { routeId: "NES", color: "#C55188", image: "bus_NES.png" }, - { routeId: "WS", color: "#BA5231", image: "bus_WS.png" }, - { routeId: "WX", color: "#E8663E", image: "bus_WX.png" } - ]; - - public getRouteColor(routeId: string): string | null { - const route = this.routes.find(r => r.routeId === routeId); - return route ? route.color : null; - } - - public getRouteImage(routeId: string): string | null { - const route = this.routes.find(r => r.routeId === routeId); - return route ? route.image : null; - } - - public getAllRoutes(): BusRoute[] { - return [...this.routes]; - } - - public getRouteInfo(routeId: string): BusRoute | null { - return this.routes.find(r => r.routeId === routeId) || null; - } -} - -// Initialize bus color manager -const busColorManager = new BusColorManager(); - -dotenv.config(); -const router = express.Router(); -const routeImages: { [k: string]: string } = metadata.routeImages; - -setInterval(updateBusPositions, 7500); -setInterval(getSelectableRoutes, 60000); -setInterval(rebuildGraph, 10 * 1000); -setInterval(processReminders, 10 * 1000); -setInterval(() => reminderSubscriptions.describe(), 60000); -getSelectableRoutes(); -rebuildGraph(); - -import * as process from "node:process"; -import { getMessaging } from "firebase-admin/messaging"; -import { processReminders, reminderSubscriptions, Event, RegistrationToken } from "./reminderService"; - - -dotenv.config(); - -const API_KEY = process.env.MBUS_API_KEY; -router.get('/getBusPredictions1/:busId', (req, res) => { - axios.get(`https://mbus.ltp.umich.edu/bustime/api/v3/getpredictions?requestType=getpredictions&locale=en&vid=${req.params.busId}&top=4&tmres=s&rtpidatafeed=bustime&key=${API_KEY}&format=json&xtime=1626028950462`).then(apiRes => { - res.send(apiRes.data); - }).catch(err => { - console.log(err); - res.sendStatus(500); - - }); -}); - -router.get('/getBusPositions', (req, res) => { - res.send(curBusPositions); -}); - -router.get('/getVehiclePositions', (req, res) => { - res.send(curBusPositions); -}); - -router.get('/getSelectableRoutes', (req, res) => { - res.send(curRouteSelections); -}); - -router.get('/getAllRoutes', (req, res) => { - res.send({ routes: cachedRoutes }); -}); - -router.get('/getrouteCache', (req, res) => { - res.send({ routes: routeTimingCache }); -}); - -router.get('/getVehicleImage/:route', (req, res) => { - const { route } = req.params; - - const dirname = import.meta.dirname; - const assetPath = path.join(dirname, 'assets'); - const imagePath = path.join(assetPath, 'main2025'); - - if (!route || !(route in routeImages)) { - res.sendFile(path.join(assetPath, 'bus_CN.png')); - return res.sendStatus(400); - } - - res.sendFile(path.join(imagePath, routeImages[route])); -}); - -router.get('/getRouteInfoVersion', (req, res) => { - res.send(JSON.stringify({ version: metadata.metadata.version })); -}); - -router.get('/getRouteInformation', (req, res) => { - const infoToSend = { - routeIdToName: metadata.routeIdToName, - routeImages: metadata.routeImages, - metadata: metadata.metadata, - routeColors: busColorManager.getAllRoutes().map(route => ({ - routeId: route.routeId, - color: route.color, - image: route.image - })) - } - res.send(infoToSend); -}); - -router.get('/getStartupInfo', (req, res) => { - res.json({ - // updating this will disable older versions of the app - min_supported_version: "1.0.0", - why_update_message: { - title: "New Update Available", - subtitle: "Please update to the latest version for the best experience." - }, - // adding data here will show a persistant message on launch - persistant_message: { - title: "Update on missing bus predictions", - subtitle: "2/9 9:03 PM: The university has confirmed to us that they're actively working on fixing the issue with missing bus predictions. Thank you for your patience." - }, - // adding data here will show a one-time message on launch (not yet implemented) - one_time_message: { - title: "", - subtitle: "" - }, - // updating this will make bus images redownload on frontend - bus_image_version: "1", - }); -});; - -router.get('/getBusPredictions/:busId', (req, res) => { - const busId = req.params.busId; - const preds = cachedPredsByVid[busId]; - - if (!preds) { - return res.json({ - "bustime-response": { "prd": [] } - }); - } - res.json({ - "bustime-response": { "prd": preds } - }); -}); - -router.get('/getStopPredictions/:stopId', (req, res) => { - const stopId = req.params.stopId; - const preds = cachedPredsByStopId[stopId]; - - if (!preds) { - return res.json({ - "bustime-response": { "prd": [] } - }); - } - - res.json({ - "bustime-response": { "prd": preds } - }); -}); - -router.get('/getAllPredictions', async (req, res) => { - try { - const predictions = await getAllBusPredictions(); - res.send(predictions); - } catch (err) { - console.log(err); - res.sendStatus(500); - } -}); - -router.get('/getAllStops', (req, res) => { - const stopsList = Object.entries(cachedStopLocations).map(([stpid, stopInfo]) => ({ - stpid, - ...stopInfo, - })); - res.json(Object.values(stopsList)); -}); - -router.get('/getBuildingLocations', (req, res) => { - res.sendFile(path.join(import.meta.dirname, 'assets', 'building-data.json')); -}); - -router.get('/get-startup-messages', (req, res) => { - res.send(JSON.stringify(message)); -}); - -// Simple bus color endpoints -router.get('/getRouteColors', (req, res) => { - const routes = busColorManager.getAllRoutes(); - res.json({ - routes: routes.map(route => ({ - routeId: route.routeId, - color: route.color, - image: route.image - })) - }); -}); - -router.get('/getRouteColor/:routeId', (req, res) => { - const { routeId } = req.params; - const routeInfo = busColorManager.getRouteInfo(routeId); - - if (!routeInfo) { - return res.status(404).json({ error: `Route '${routeId}' not found` }); - } - - res.json({ - routeId: routeInfo.routeId, - color: routeInfo.color, - image: routeInfo.image - }); -}); - -// Simple endpoint for frontend, gets everything needed for UI -router.get('/getFrontendData', (req, res) => { - try { - const routes = busColorManager.getAllRoutes(); - - const response = { - routes: routes.map(route => ({ - routeId: route.routeId, - name: (metadata.routeIdToName as any)[route.routeId] || route.routeId, - image: route.image, - color: route.color, - imageUrl: `/mbus/api/v3/getVehicleImage/${route.routeId}` - })), - metadata: { - ...metadata.metadata, - lastUpdated: new Date().toISOString() - } - }; - - res.json(response); - } catch (error) { - res.status(500).json({ error: 'Failed to get frontend data' }); - } -}); - - -router.get('/nearest-stops', (req, res) => { - try { - const { lat, lon, k = '2' } = req.query; - - const originLat = parseFloat(lat as string); - const originLon = parseFloat(lon as string); - const numStops = parseInt(k as string); - - if (isNaN(originLat) || isNaN(originLon)) { - return res.status(400).json({ error: 'Invalid or missing lat/lon' }); - } - if (isNaN(numStops) || numStops <= 0) { - return res.status(400).json({ error: 'Parameter k must be a positive integer' }); - } - - const heap = new MaxPriorityQueue<{ stpid: string; name: string; lat: number; lon: number; distance: number }>({ - compare: (a, b) => a.distance - b.distance - }); - - for (const [stpid, stop] of Object.entries(cachedStopLocations)) { - const latDiff = (stop.lat - originLat) * 111320; - const lonDiff = (stop.lon - originLon) * 111320 * Math.cos(originLat * Math.PI / 180); - const distance = Math.sqrt(latDiff ** 2 + lonDiff ** 2); - - const stopWithDist = { - stpid, - name: stop.name, - lat: stop.lat, - lon: stop.lon, - distance - }; - - if (heap.size() < numStops) { - heap.enqueue(stopWithDist); - } else if (distance < heap.front().distance) { - heap.dequeue(); - heap.enqueue(stopWithDist); - } - } - - const nearestStops = heap.toArray().sort((a, b) => a.distance - b.distance); - res.json({ nearestStops }); - } catch (error) { - console.error('Error in /nearest-stops:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -function optimizeWalkingFastest(journey: any, cachedGraph: any): any { - if (!journey) return journey; - - const optimizedLegs: any[] = []; - const WALKING_SPEED_KMH = 4; - const WALKING_SPEED_MS = WALKING_SPEED_KMH * 1000 / 3600; - - function distanceMeters(lat1: number, lon1: number, lat2: number, lon2: number): number { - const dx = (lat2 - lat1) * 111320; - const dy = (lon2 - lon1) * 111320 * Math.cos(lat1 * Math.PI / 180); - return Math.sqrt(dx * dx + dy * dy); - } - - for (let i = 0; i < journey.legs.length; i++) { - const leg = journey.legs[i]; - - // Look for a transfer followed by a bus trip - if (leg.trip && i > 0 && "duration" in journey.legs[i - 1]) { - const transfer = journey.legs[i - 1] as Transfer; - const tripLeg = leg as TimetableLeg; - const trip = tripLeg.trip; - - const originalBoardStop = tripLeg.stopTimes[0].stop; - const boardIdx = trip.stopTimes.findIndex(st => st.stop === originalBoardStop); - const walkStartTime = transfer.startTime; - - let bestStop = originalBoardStop; - let bestIdx = boardIdx; - let bestDistance = Number.MAX_SAFE_INTEGER; - - const originLoc = cachedStopLocations[transfer.origin]; - if (!originLoc) { - optimizedLegs.push(leg); - continue; - } - - for (let j = boardIdx; j < trip.stopTimes.length; j++) { - const candidate = trip.stopTimes[j]; - const stopLoc = cachedStopLocations[candidate.stop]; - if (!stopLoc) continue; - - const dist = distanceMeters(originLoc.lat, originLoc.lon, stopLoc.lat, stopLoc.lon); - const walkArrival = walkStartTime + dist / WALKING_SPEED_MS; - const busArrival = candidate.arrivalTime - (cachedGraph.interchange[candidate.stop] ?? 0); - - if (walkArrival <= busArrival && dist < bestDistance) { - bestStop = candidate.stop; - bestIdx = j; - bestDistance = dist; - } - } - - if (bestStop !== originalBoardStop) { - console.log(`Optimized walking to ${bestStop} instead of ${originalBoardStop}, saving ${Math.round(bestDistance)} meters`); - // Update transfer - transfer.destination = bestStop; - transfer.duration = Math.round(bestDistance / WALKING_SPEED_MS); - - // Trim trip leg to start from bestStop - tripLeg.stopTimes = trip.stopTimes.slice(bestIdx); - - // Refresh trip leg duration - if (tripLeg.stopTimes.length > 1) { - const firstStop = tripLeg.stopTimes[0]; - const lastStop = tripLeg.stopTimes[tripLeg.stopTimes.length - 1]; - (tripLeg as any).duration = lastStop.arrivalTime - firstStop.departureTime; - } - } - } - - optimizedLegs.push(leg); - } - - return { ...journey, legs: optimizedLegs }; -} - -router.get('/plan-journey', async (req, res) => { - try { - const originStopId = 'VIRTUAL_ORIGIN'; - const destStopId = 'VIRTUAL_DESTINATION'; - - const { originLat, originLon, destLat, destLon, walkingPenalty: walkingPenaltyParam } = req.query; - if (!originLat || !originLon || !destLat || !destLon) { - return res.status(400).json({ error: 'Origin and destination coordinates are required' }); - } - - const now = new Date(); - const currentTime = now.getUTCHours() * 3600 + now.getUTCMinutes() * 60 + now.getUTCSeconds(); - - if (!cachedGraph || !cachedGraph.trips || cachedGraph.trips.length === 0) { - await rebuildGraph(); // try to build - if (!cachedGraph) { - return res.status(404).json({ error: 'No routes available at this time' }); - } - } - - // Clear all transfers from the virtual origin - cachedGraph.transfers[originStopId] = []; - cachedGraph.transfers[destStopId] = []; - // Clear all transfers to virtual destination - Object.keys(cachedGraph.transfers).forEach(stopId => { - cachedGraph.transfers[stopId] = cachedGraph.transfers[stopId].filter( - t => t.destination !== destStopId - ); - }); - - // Update the times for the virtual trips - const vOriginTrip = cachedGraph.trips.find(t => t.tripId === 'VIRTUAL_ORIGIN_TRIP'); - if (vOriginTrip) { - vOriginTrip.stopTimes[0].arrivalTime = currentTime; - vOriginTrip.stopTimes[0].departureTime = currentTime; - } - const vDestTrip = cachedGraph.trips.find(t => t.tripId === 'VIRTUAL_DESTINATION_TRIP'); - if (vDestTrip) { - vDestTrip.stopTimes[0].arrivalTime = currentTime; - vDestTrip.stopTimes[0].departureTime = currentTime; - } - - // Calculate transfers from origin to all real stops - const originLatNum = parseFloat(originLat as string); - const originLonNum = parseFloat(originLon as string); - const destLatNum = parseFloat(destLat as string); - const destLonNum = parseFloat(destLon as string); - - const WALKING_SPEED_KMH = 4; - const WALKING_SPEED_MS = WALKING_SPEED_KMH * 1000 / 3600; - - // Add transfers from origin to all real stops - Object.keys(cachedStopLocations).forEach(stopId => { - const stopLocation = cachedStopLocations[stopId]; - if (stopLocation) { - const latDiff = (stopLocation.lat - originLatNum) * 111320; - const lonDiff = (stopLocation.lon - originLonNum) * 111320 * Math.cos(originLatNum * Math.PI / 180); - const distance = Math.sqrt(latDiff * latDiff + lonDiff * lonDiff); - - let walkingTimeSeconds = distance / WALKING_SPEED_MS; - const transferDuration = Math.round(walkingTimeSeconds); - - const transfer: Transfer = { - origin: originStopId, - destination: stopId, - duration: transferDuration, - startTime: currentTime, - endTime: Number.MAX_SAFE_INTEGER - }; - cachedGraph.transfers[originStopId].push(transfer); - } - }); - - // Add transfers from all real stops to destination - Object.keys(cachedStopLocations).forEach(stopId => { - const stopLocation = cachedStopLocations[stopId]; - if (stopLocation) { - const latDiff = (destLatNum - stopLocation.lat) * 111320; - const lonDiff = (destLonNum - stopLocation.lon) * 111320 * Math.cos(stopLocation.lat * Math.PI / 180); - const distance = Math.sqrt(latDiff * latDiff + lonDiff * lonDiff); - - let walkingTimeSeconds = distance / WALKING_SPEED_MS; - const transferDuration = Math.round(walkingTimeSeconds); - - const transfer: Transfer = { - origin: stopId, - destination: destStopId, - duration: transferDuration, - startTime: currentTime, - endTime: Number.MAX_SAFE_INTEGER - }; - cachedGraph.transfers[stopId].push(transfer); - } - }); - - // Direct transfer from VIRTUAL_ORIGIN to VIRTUAL_DESTINATION - const directLatDiff = (destLatNum - originLatNum) * 111320; - const directLonDiff = (destLonNum - originLonNum) * 111320 * Math.cos(originLatNum * Math.PI / 180); - const directDistance = Math.sqrt(directLatDiff * directLatDiff + directLonDiff * directLonDiff); - - let directWalkingTimeSeconds = directDistance / WALKING_SPEED_MS; - - const directTransferDuration = Math.round(directWalkingTimeSeconds); - //console.log(`Walking Distance: ${directTransferDuration}`); - - const directTransfer: Transfer = { - origin: originStopId, - destination: destStopId, - duration: directTransferDuration, - startTime: currentTime, - endTime: Number.MAX_SAFE_INTEGER - }; - cachedGraph.transfers[originStopId].push(directTransfer); - - RaptorAlgorithm.setDebug(false); - const raptor = RaptorAlgorithmFactory.create(cachedGraph.trips, cachedGraph.transfers, cachedGraph.interchange); - let walkingPenalty = 1; // default no penalty - if (walkingPenaltyParam !== undefined) { - const parsed = parseFloat(walkingPenaltyParam as string); - if (!isNaN(parsed) && parsed > 0) { - walkingPenalty = parsed; - } - } - raptor.setWalkingPenalty(walkingPenalty); - - const resultsFactory = new JourneyFactory(); - const journeyPlanner = new DepartAfterQuery(raptor, resultsFactory); - const journeys = journeyPlanner.plan( - originStopId as StopID, - destStopId as StopID, - currentTime - ); - - const formatJourney = (journey: any) => { - if (!journey) return null; - return { - ...journey, - legs: journey.legs.map((leg: any) => { - const formattedLeg: any = { - ...leg, - origin_id: leg.origin, - origin: leg.origin === 'VIRTUAL_ORIGIN' ? 'Start' : (leg.origin === 'VIRTUAL_DESTINATION' ? 'End' : (stopIdToName[leg.origin] || leg.origin)), - destination_id: leg.destination, - destination: leg.destination === 'VIRTUAL_ORIGIN' ? 'Start' : (leg.destination === 'VIRTUAL_DESTINATION' ? 'End' : (stopIdToName[leg.destination] || leg.destination)) - }; - if (leg.trip && leg.trip.tripId) { - // Add duration for bus legs - if (leg.stopTimes && leg.stopTimes.length > 0) { - const firstStop = leg.stopTimes[0]; - const lastStop = leg.stopTimes[leg.stopTimes.length - 1]; - formattedLeg.duration = lastStop.arrivalTime - firstStop.departureTime; - formattedLeg.rt = firstStop.rt; - formattedLeg.vid = leg.vid; - - } - } else if (typeof leg.duration === 'number') { - // Add duration for transfer legs - formattedLeg.duration = leg.duration; - } - return formattedLeg; - }) - }; - }; - - let fastest = journeys.length > 0 ? journeys.reduce((best, j) => earliestArrival(best, j) ? j : best, journeys[0]) : null; - // if (fastest) { - // fastest = optimizeWalkingFastest(fastest, cachedGraph); - // } - const leastTransfers = journeys.length > 0 ? journeys.reduce((best, j) => leastChanges(best, j) ? j : best, journeys[0]) : null; - const leastWalk = journeys.length > 0 ? journeys.reduce((best, j) => leastWalking(best, j) ? j : best, journeys[0]) : null; - const uniqueJourneys = [fastest, leastTransfers, leastWalk] - .filter((j, i, arr) => j && arr.findIndex(x => x === j) === i) - .map(formatJourney); - res.json({ journeys: uniqueJourneys.slice(0, 3) }); - } catch (error) { - console.error('Error planning journey:', error); - res.status(500).json({ error: 'Failed to plan journey' }); - } -}); - -// Notifications / Reminders - -// Expects {token: string, stpid: string, rtid: string, thresh: number} in the body -router.post('/setReminder', (req, res) => { - const token = req.body.token as RegistrationToken; - const stpid: string = req.body.stpid; - const rtid: string = req.body.rtid; - const thresh: number = req.body.thresh; - reminderSubscriptions.add({ stpid, rtid } as Event, thresh, token); - res.sendStatus(200); -}); - -// Expects {token: string, stpid: string, rtid: string} in the body -router.post('/unsetReminder', (req, res) => { - const token = req.body.token as RegistrationToken; - const stpid: string = req.body.stpid; - const rtid: string = req.body.rtid; - reminderSubscriptions.remove({ stpid, rtid } as Event, token); - res.sendStatus(200); -}); - -// Expects {oldTok: string, newTok: string} in the body -// Upon responding with 200, future calls to /setReminder, /unsetReminder, and /activeReminders -// will need the new token -router.post('/swapToken', (req, res) => { - const oldTok = req.body.oldTok as RegistrationToken; - const newTok = req.body.newTok as RegistrationToken; - reminderSubscriptions.swapToken(oldTok, newTok); - res.sendStatus(200); -}); - -// Responds with { reminders: Array<{ stpid: string, rtid: string, thresh: number | null }> } -router.get('/activeReminders/:registrationToken', (req, res) => { - const token = req.params.registrationToken as RegistrationToken; - res.send({ reminders: reminderSubscriptions.activeRemindersFor(token) }); - res.status(200); -}); - -// testing purposes -router.post('/notifyMeLater', (req, res) => { - console.log("got request"); - const registrationToken = req.body.token; - if (registrationToken === undefined) { - console.log("got request with no token"); - console.log(req.body); - res.send("registration token missing"); - res.status(400); - return; - } - setTimeout(() => { - console.log("sending push notification.."); - getMessaging() - .send({ notification: { title: "hi", body: "hello world!" }, token: registrationToken }) - .catch((e) => console.log("Failed to send message: ", e)); - }, 10000); - res.sendStatus(200); -}); - -export default router; diff --git a/src/legacy/v3.ts b/src/legacy/v3.ts deleted file mode 100644 index 8de143a..0000000 --- a/src/legacy/v3.ts +++ /dev/null @@ -1,561 +0,0 @@ - -import * as walking from '../walking/walkingMap'; -import * as metadata from "../assets/route-data.json"; -import * as path from "node:path"; -import * as fs from 'fs'; - -import express from "express"; -import dotenv from "dotenv"; -import axios from "axios"; - -import { McRaptorAlgorithm, Journey, JourneyLeg } from "../raptor/McRaptorAlgorithm"; -import { MaxPriorityQueue } from '@datastructures-js/priority-queue'; - -import { - curBusPositions, - cachedPredsByStopId, - cachedRoutes, - cachedPredsByVid, - cachedStopLocations, - curRouteSelections, - stopIdToName, - tatripidToRt, - getAllBusPredictions, - routeTimingCache, - cachedGraph, - updateBusPositions, - getSelectableRoutes, - rebuildGraph, -} from './busService'; - -// Simple Bus Color System -interface BusRoute { - routeId: string; - color: string; - image: string; -} - -class BusColorManager { - private readonly routes: BusRoute[] = [ - { routeId: "BB", color: "#2F773F", image: "bus_BB.png" }, - { routeId: "CN", color: "#643076", image: "bus_CN.png" }, - { routeId: "CS", color: "#3559B8", image: "bus_CS.png" }, - { routeId: "CSX", color: "#1C2256", image: "bus_CSX.png" }, - { routeId: "DD", color: "#A9C534", image: "bus_DD.png" }, - { routeId: "MX", color: "#5EC7DE", image: "bus_MX.png" }, - { routeId: "NE", color: "#C55188", image: "bus_NE.png" }, - { routeId: "NW", color: "#AE3636", image: "bus_NW.png" }, - { routeId: "NX", color: "#DA4343", image: "bus_NX.png" }, - { routeId: "OS", color: "#E8A43C", image: "bus_OS.png" }, - { routeId: "NES", color: "#C55188", image: "bus_NES.png" }, - { routeId: "WS", color: "#BA5231", image: "bus_WS.png" }, - { routeId: "WX", color: "#E8663E", image: "bus_WX.png" } - ]; - - public getRouteColor(routeId: string): string | null { - const route = this.routes.find(r => r.routeId === routeId); - return route ? route.color : null; - } - - public getRouteImage(routeId: string): string | null { - const route = this.routes.find(r => r.routeId === routeId); - return route ? route.image : null; - } - - public getAllRoutes(): BusRoute[] { - return [...this.routes]; - } - - public getRouteInfo(routeId: string): BusRoute | null { - return this.routes.find(r => r.routeId === routeId) || null; - } -} - - -// Initialize bus color manager -const busColorManager = new BusColorManager(); - -dotenv.config(); -const router = express.Router(); -const routeImages: { [k: string]: string } = metadata.routeImages; - -setInterval(updateBusPositions, 7500); -setInterval(getSelectableRoutes, 60000); -setInterval(rebuildGraph, 10 * 1000); -getSelectableRoutes(); -rebuildGraph(); - -import * as process from "node:process"; - -const message = { - id: "gradamatation", - title: "Congrats Grads 🥳", - message: - "Congrats to everyone who is gradamatating! Enjoy some grad hats on the buses, and don't forget to celebrate!", - buildVersion: "99", -}; - -dotenv.config(); - -const API_KEY = process.env.MBUS_API_KEY; -router.get('/getBusPredictions1/:busId', (req, res) => { - axios.get(`https://mbus.ltp.umich.edu/bustime/api/v3/getpredictions?requestType=getpredictions&locale=en&vid=${req.params.busId}&top=4&tmres=s&rtpidatafeed=bustime&key=${API_KEY}&format=json&xtime=1626028950462`).then(apiRes => { - res.send(apiRes.data); - }).catch(err => { - console.log(err); - res.sendStatus(500); - - }); -}); - -router.get('/getBusPositions', (req, res) => { - res.send(curBusPositions); -}); - -router.get('/getVehiclePositions', (req, res) => { - res.send(curBusPositions); -}); - -router.get('/getSelectableRoutes', (req, res) => { - res.send(curRouteSelections); -}); - -router.get('/getAllRoutes', (req, res) => { - res.send({ routes: cachedRoutes }); -}); - -router.get('/getrouteCache', (req, res) => { - res.send({ routes: routeTimingCache }); -}); - -router.get('/getVehicleImage/:route', (req, res) => { - const { route } = req.params; - - const dirname = import.meta.dirname; - const assetPath = path.join(dirname, 'assets'); - const imagePath = path.join(assetPath, 'main2025'); - - if (!route || !(route in routeImages)) { - res.status(400).sendFile(path.join(imagePath, 'bus_CN.png')); - return; - } - res.sendFile(path.join(imagePath, routeImages[route]), (err) => { - if (err) { - console.error(`Error sending requested image for route ${route}: ${err.message}`); - if (!res.headersSent) res.status(404).send('Image file not found on server.'); - } - }); -}); - -router.get('/getRouteInfoVersion', (req, res) => { - res.send(JSON.stringify({ version: metadata.metadata.version })); -}); - -router.get('/getRouteInformation', (req, res) => { - const infoToSend = { - routeIdToName: metadata.routeIdToName, - routeImages: metadata.routeImages, - metadata: metadata.metadata, - routeColors: busColorManager.getAllRoutes().map(route => ({ - routeId: route.routeId, - color: route.color, - image: route.image - })) - } - res.send(infoToSend); -}); - -router.get('/getStartupInfo', (req, res) => { - res.json({ - // updating this will disable older versions of the app - min_supported_version: "1.0.0", - why_update_message: { - title: "New Update Available", - subtitle: "Please update to the latest version for the best experience." - }, - // adding data here will show a persistant message on launch - persistant_message: { - title: "", - subtitle: "" - }, - // adding data here will show a one-time message on launch (not yet implemented) - one_time_message: { - title: "", - subtitle: "" - }, - // updating this will make bus images redownload on frontend - bus_image_version: "1", - }); -});; - -router.get('/getBusPredictions/:busId', (req, res) => { - const busId = req.params.busId; - const preds = cachedPredsByVid[busId]; - - if (!preds) { - return res.json({ - "bustime-response": { "prd": [] } - }); - } - res.json({ - "bustime-response": { "prd": preds } - }); -}); - -router.get('/getStopPredictions/:stopId', (req, res) => { - const stopId = req.params.stopId; - const preds = cachedPredsByStopId[stopId]; - - if (!preds) { - return res.json({ - "bustime-response": { "prd": [] } - }); - } - - res.json({ - "bustime-response": { "prd": preds } - }); -}); - -router.get('/getAllPredictions', async (req, res) => { - try { - const predictions = await getAllBusPredictions(); - res.send(predictions); - } catch (err) { - console.log(err); - res.sendStatus(500); - } -}); - -router.get('/getAllStops', (req, res) => { - const stopsList = Object.entries(cachedStopLocations).map(([stpid, stopInfo]) => ({ - stpid, - ...stopInfo, - })); - res.json(Object.values(stopsList)); -}); - -router.get('/getBuildingLocations', (req, res) => { - res.sendFile(path.join(import.meta.dirname, 'assets', 'building-data.json')); -}); - -router.get('/get-startup-messages', (req, res) => { - res.send(JSON.stringify(message)); -}); - -// Simple bus color endpoints -router.get('/getRouteColors', (req, res) => { - const routes = busColorManager.getAllRoutes(); - res.json({ - routes: routes.map(route => ({ - routeId: route.routeId, - color: route.color, - image: route.image - })) - }); -}); - -router.get('/getRouteColor/:routeId', (req, res) => { - const { routeId } = req.params; - const routeInfo = busColorManager.getRouteInfo(routeId); - - if (!routeInfo) { - return res.status(404).json({ error: `Route '${routeId}' not found` }); - } - - res.json({ - routeId: routeInfo.routeId, - color: routeInfo.color, - image: routeInfo.image - }); -}); - -// Simple endpoint for frontend, gets everything needed for UI -router.get('/getFrontendData', (req, res) => { - try { - const routes = busColorManager.getAllRoutes(); - - const response = { - routes: routes.map(route => ({ - routeId: route.routeId, - name: (metadata.routeIdToName as any)[route.routeId] || route.routeId, - image: route.image, - color: route.color, - imageUrl: `/mbus/api/v3/getVehicleImage/${route.routeId}` - })), - metadata: { - ...metadata.metadata, - lastUpdated: new Date().toISOString() - } - }; - - res.json(response); - } catch (error) { - res.status(500).json({ error: 'Failed to get frontend data' }); - } -}); - - -router.get('/nearest-stops', (req, res) => { - try { - const { lat, lon, k = '2' } = req.query; - - const originLat = parseFloat(lat as string); - const originLon = parseFloat(lon as string); - const numStops = parseInt(k as string); - - if (isNaN(originLat) || isNaN(originLon)) { - return res.status(400).json({ error: 'Invalid or missing lat/lon' }); - } - if (isNaN(numStops) || numStops <= 0) { - return res.status(400).json({ error: 'Parameter k must be a positive integer' }); - } - - const heap = new MaxPriorityQueue<{ stpid: string; name: string; lat: number; lon: number; distance: number }>({ - compare: (a, b) => a.distance - b.distance - }); - - for (const [stpid, stop] of Object.entries(cachedStopLocations)) { - const latDiff = (stop.lat - originLat) * 111320; - const lonDiff = (stop.lon - originLon) * 111320 * Math.cos(originLat * Math.PI / 180); - const distance = Math.sqrt(latDiff ** 2 + lonDiff ** 2); - - const stopWithDist = { - stpid, - name: stop.name, - lat: stop.lat, - lon: stop.lon, - distance - }; - - if (heap.size() < numStops) { - heap.enqueue(stopWithDist); - } else if (distance < heap.front()!.distance) { - heap.dequeue(); - heap.enqueue(stopWithDist); - } - } - - const nearestStops = heap.toArray().sort((a, b) => a.distance - b.distance); - res.json({ nearestStops }); - } catch (error) { - console.error('Error in /nearest-stops:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -router.get('/plan-journey', async (req, res) => { - try { - const originStopId = 'VIRTUAL_ORIGIN'; - const destStopId = 'VIRTUAL_DESTINATION'; - - const { originLat, originLon, destLat, destLon, walkingPenalty: walkingPenaltyParam} = req.query; - if (!originLat || !originLon || !destLat || !destLon) { - return res.status(400).json({ error: 'Origin and destination coordinates are required' }); - } - - const oLat = parseFloat(originLat as string); - const oLon = parseFloat(originLon as string); - const dLat = parseFloat(destLat as string); - const dLon = parseFloat(destLon as string); - - const now = new Date(); - const currentTime = now.getUTCHours() * 3600 + now.getUTCMinutes() * 60 + now.getUTCSeconds(); - - if (!cachedGraph || !cachedGraph.trips || cachedGraph.trips.length === 0) { - await rebuildGraph(); - if (!cachedGraph) { - return res.status(404).json({ error: 'No routes available at this time' }); - } - } - - // Clear all transfers for virtual stops - cachedGraph.transfers[originStopId] = []; - cachedGraph.transfers[destStopId] = []; - Object.keys(cachedGraph.transfers).forEach(stopId => { - cachedGraph.transfers[stopId] = cachedGraph.transfers[stopId].filter( - t => t.destination !== destStopId - ); - }); - - const vOriginTrip = cachedGraph.trips.find(t => t.tripId === 'VIRTUAL_ORIGIN_TRIP'); - if (vOriginTrip) { - vOriginTrip.stopTimes[0].arrivalTime = currentTime; - vOriginTrip.stopTimes[0].departureTime = currentTime; - } - const vDestTrip = cachedGraph.trips.find(t => t.tripId === 'VIRTUAL_DESTINATION_TRIP'); - if (vDestTrip) { - vDestTrip.stopTimes[0].arrivalTime = currentTime; - vDestTrip.stopTimes[0].departureTime = currentTime; - } - - // Get walking times from origin to all stops - // Get walking times from all stops to dest - const walksFromOrigin = walking.getWalkingDistancesFrom(oLat, oLon, dLat, dLon); - const walksToDest = walking.getWalkingDistancesFrom(dLat, dLon); - - walksFromOrigin.forEach(walk => { - if (walk.stopId === "DIRECT_WALK") { - cachedGraph.transfers[originStopId].push({ - origin: originStopId, - destination: destStopId, - duration: walk.duration, - startTime: currentTime, - endTime: Number.MAX_SAFE_INTEGER - }); - } else { - cachedGraph.transfers[originStopId].push({ - origin: originStopId, - destination: walk.stopId, - duration: walk.duration, - startTime: currentTime, - endTime: Number.MAX_SAFE_INTEGER - }); - } - }); - - walksToDest.forEach(walk => { - cachedGraph.transfers[walk.stopId].push({ - origin: walk.stopId, - destination: destStopId, - duration: walk.duration, - startTime: currentTime, - endTime: Number.MAX_SAFE_INTEGER - }); - }); - - const mcRaptor = new McRaptorAlgorithm(cachedGraph.trips, cachedGraph.transfers, cachedGraph.interchange); - - let walkingPenalty = 1; - if (walkingPenaltyParam !== undefined) { - const parsed = parseFloat(walkingPenaltyParam as string); - if (!isNaN(parsed) && parsed > 0) { - walkingPenalty = parsed; - } - } - mcRaptor.setWalkingPenalty(walkingPenalty); - - let rangeInSeconds = 60*45; - const { range } = req.query; - if (range !== undefined) { - const parsedRange = parseInt(range as string); - if (!isNaN(parsedRange) && parsedRange > 0) { - rangeInSeconds = parsedRange * 60; - } - } - - let journeys: Journey[]; - if(range !== undefined) { - journeys = mcRaptor.getOptimizedJourneysInRange(originStopId, destStopId, currentTime, rangeInSeconds); - } else { - journeys = mcRaptor.getOptimizedJourneys(originStopId, destStopId, currentTime); - } - const processLeg = async (leg: JourneyLeg) => { - const isWalk = !leg.trip; - - const formattedLeg: any = { - origin_id: leg.origin, - origin: leg.origin === 'VIRTUAL_ORIGIN' ? 'Start' : (leg.origin === 'VIRTUAL_DESTINATION' ? 'End' : (stopIdToName[leg.origin] || leg.origin)), - destination_id: leg.destination, - destination: leg.destination === 'VIRTUAL_DESTINATION' ? 'End' : (stopIdToName[leg.destination] || leg.destination), - destinationName: leg.destination === 'VIRTUAL_DESTINATION' ? 'End' : (stopIdToName[leg.destination] || leg.destination), - startTime: Math.round(leg.startTime), - endTime: Math.round(leg.endTime), - duration: Math.round(leg.duration), - mode: isWalk ? 'walk' : 'bus', - originID: leg.originID, - destinationID: leg.destinationID, - stopTimes: leg.stopTimes, - trip: leg.trip, - rt: leg.rt - }; - - if (leg.trip) { - formattedLeg.tripId = leg.trip.tripId; - formattedLeg.vid = leg.trip.vid; - if (!formattedLeg.rt) { - const firstStop = leg.trip.stopTimes[0]; - formattedLeg.rt = firstStop.rt || tatripidToRt[leg.trip.tripId] || 'UNKNOWN'; - } - } - - if (isWalk) { - const cached = walking.getCachedWalk(leg.origin, leg.destination); - - if (cached) { - Object.assign(formattedLeg, cached); - } else { - const l1 = leg.origin === 'VIRTUAL_ORIGIN' ? { lat: oLat, lon: oLon } : cachedStopLocations[leg.origin]; - const l2 = leg.destination === 'VIRTUAL_DESTINATION' ? { lat: dLat, lon: dLon } : cachedStopLocations[leg.destination]; - - if (l1 && l2) { - try { - const data = await walking.getWalkingResponse(l1.lat, l1.lon, l2.lat, l2.lon); - data.duration = Math.round(data.duration); - Object.assign(formattedLeg, data); - } catch (e) { - formattedLeg.path_coords = []; - } - } - } - } - - return formattedLeg; - }; - - const processJourneys = async (journeys: Journey[]) => { - return Promise.all(journeys.map(async (journey: Journey) => { - if (!journey) return null; - - const legs = await Promise.all(journey.legs.map(processLeg)); - - return { - legs, - departureTime: journey.criteria.arrivalTime - (legs.reduce((acc, leg) => acc + leg.duration, 0)), - arrivalTime: journey.criteria.arrivalTime, - criteria: journey.criteria - }; - })); - }; - const processedList = await processJourneys(journeys); - const sortedJourneys = processedList - .filter((j: any) => j !== null) - .sort((a: any, b: any) => - a.arrivalTime - b.arrivalTime || - a.criteria.walkingDistance - b.criteria.walkingDistance - ); - res.json({ - journeys: sortedJourneys - }); - - } catch (error) { - console.error('Error planning journey:', error); - res.status(500).json({ error: 'Failed to plan journey' }); - } -}); - - -router.get('/save-graph', async (req, res) => { - if (process.env.DEV_SAVE !== 'true') { - return res.status(403).json({ error: 'Endpoint only available in DEV mode' }); - } - - try { - const filePath = path.resolve(process.cwd(), 'saved_graph.json'); - const fullState = { - graph: cachedGraph, - stopLocations: cachedStopLocations, - stopNames: stopIdToName, - predsByVid: cachedPredsByVid, - predsByStopId: cachedPredsByStopId - }; - const data = JSON.stringify(fullState, null, 2); - fs.writeFileSync(filePath, data); - res.json({ message: `Graph and state saved to ${filePath}` }); - } catch (error) { - console.error('Error saving graph:', error); - res.status(500).json({ error: 'Failed to save graph' }); - } -}); - -export default router; diff --git a/src/routes/api.ts b/src/routes/api.ts index 8f24271..cc03750 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -567,7 +567,12 @@ export function swapToken(req: express.Request, res: express.Response) { } router.post('/swapToken', swapToken); -type ActiveReminderInfo = { stpid: string, rtid: string, thresh: number | null, eta: number | null }; +export interface ActiveReminderInfo { + stpid: string + rtid: string + thresh: number | null + eta: number | null +}; /** * @param req - Express request, token is path encoded diff --git a/src/services/reminder.ts b/src/services/reminder.ts index a274244..8b87c78 100644 --- a/src/services/reminder.ts +++ b/src/services/reminder.ts @@ -61,7 +61,7 @@ function prdctdnToNum(prdctdn: string): number { } /** result of ReminderSubscriptons.process */ -type RemindersToTrigger = { +export type RemindersToTrigger = { /** can be sent in bulk based off of route, stop, and threshold (or route, stop, and prdctdn) */ reminder: Map, Set>, /** can be sent in bulk based off of what route and stop */ @@ -74,7 +74,7 @@ type RemindersToTrigger = { }; /** Subscriptions go through a pipeline, see types above for details. */ -class ReminderSubscriptions { +export class ReminderSubscriptions { subscriptions: Array<{ token: RegistrationToken, subscription: PreThreshold | PostThreshold }> diff --git a/src/services/reminderTypes.ts b/src/services/reminderTypes.ts index eae8a53..5f4f54c 100644 --- a/src/services/reminderTypes.ts +++ b/src/services/reminderTypes.ts @@ -13,8 +13,8 @@ export function fromKey(key: Key): T { return JSON.parse(key); } -/** internal */ -type CoreEvent = { +/** @internal */ +export type CoreEvent = { stpid: string, rtid: string, }
                                                                                                                                                                                                                                                                                                            mbus-backend
                                                                                                                                                                                                                                                                                                              Preparing search index...