{"id":40154331,"url":"https://github.com/johnsyweb/crashcourse","last_synced_at":"2026-01-19T15:33:48.490Z","repository":{"id":291215830,"uuid":"976960979","full_name":"johnsyweb/crashcourse","owner":"johnsyweb","description":"Simulate and analyse your event course for accessibility and enjoyment.","archived":false,"fork":false,"pushed_at":"2026-01-14T02:39:49.000Z","size":2163,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-14T05:51:26.502Z","etag":null,"topics":["react","running","simulation","typescript"],"latest_commit_sha":null,"homepage":"https://www.johnsy.com/crashcourse/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnsyweb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-03T05:21:15.000Z","updated_at":"2026-01-14T02:39:46.000Z","dependencies_parsed_at":"2025-06-12T15:38:46.797Z","dependency_job_id":"e991ece3-45b5-4da1-ab64-bd97652c0d2d","html_url":"https://github.com/johnsyweb/crashcourse","commit_stats":null,"previous_names":["johnsyweb/crashcourse"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/johnsyweb/crashcourse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsyweb%2Fcrashcourse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsyweb%2Fcrashcourse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsyweb%2Fcrashcourse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsyweb%2Fcrashcourse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnsyweb","download_url":"https://codeload.github.com/johnsyweb/crashcourse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsyweb%2Fcrashcourse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28573017,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T14:39:55.009Z","status":"ssl_error","status_checked_at":"2026-01-19T14:39:01.217Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","running","simulation","typescript"],"created_at":"2026-01-19T15:33:48.329Z","updated_at":"2026-01-19T15:33:48.468Z","avatar_url":"https://github.com/johnsyweb.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Crashcourse\n\nHow accessible is this 5km course? Will participants and the public be able to enjoy the space together? Let's find out!\n\n## What\n\n1. Upload a course GPS data file (supported formats: `.gpx`, `.kml`).\n2. See the course overlaid on OpenStreetMap.\n3. Given a default path width, adjust it and specify narrower and wider sections.\n4. Run simulations of walkers, joggers, and runners of varying paces and numbers following this course and highlight any areas of congestion. Add in some public path users with prams and bikes for good measure.\n5. Tweak your course for accessibility, following the visualisations.\n6. Share your course with others via a shareable URL that includes all course data, metadata, and lap detection parameters.\n\n## Developing\n\nTo set up the development environment:\n\n1. Clone the repository:\n\n   ```bash\n   git clone johnsyweb/crashcourse\n   cd crashcourse\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   pnpm install\n   ```\n\n3. Start the development server:\n\n   ```bash\n   pnpm run dev\n   ```\n\n4. Open your browser and navigate to the provided local development URL.\n\n## Contributing\n\nWe welcome contributions! To contribute:\n\n1. Fork the repository and create your branch:\n\n   ```bash\n   git checkout -b feature/your-feature-name\n   ```\n\n2. Make your changes and commit them using Commitizen for conventional commits:\n\n   ```bash\n   pnpm commit\n   ```\n\n3. Push to your fork:\n\n   ```bash\n   git push origin feature/your-feature-name\n   ```\n\n4. Open a pull request on the main repository.\n\nPlease ensure your code follows the project's coding standards and includes tests where applicable.\n\n## Components and Responsibilities\n\n### CourseSimulationApp\n\nThe main coordinator for the application flow. It handles the switching between the course data import and simulation stages, maintaining the state of the GPS course points.\n\n### CourseDataImporter\n\nHandles the importing and processing of GPS course data. It manages the file selection interface and handles the parsing of GPS files through the GPXFile component.\n\n### CourseSimulation\n\nManages the visualisation and interactive simulation of the course. It coordinates between the Map, Course, and Simulator components to provide a coherent simulation experience.\n\n### FileUploadSection\n\nA reusable component for the file upload interface, allowing users to select GPS files.\n\n### GPXFile\n\nA specialized component that handles parsing and processing of GPX files. Features include:\n\n- Parsing XML data from GPX files\n- Extracting track points with coordinates\n- Error handling for malformed or incomplete GPS data\n- Providing structured data (start/endpoints, track points) to parent components\n\n### Course\n\nA model representing an event course, defined by a series of geographical points. Features include:\n\n- Calculating the total course length using turf.js for accurate geodesic calculations\n- Providing access to start and finish points\n- Finding coordinates at any specific distance along the course\n- Determining the distance of a given position relative to the course\n- Calculating the left and right edges of the course\n- Identifying the narrowest and widest parts of the course and their widths\n- Modeling course width based on parallel paths and intersections\n- Supporting dynamic width calculations at any point along the course\n\n### CourseDisplay\n\nA visualisation component for rendering a course on a map. Features include:\n\n- Rendering the course path as a polyline\n- Displaying start and finish markers\n- Optional kilometre markers along the course\n- Customisable line styling\n- Marking the narrowest and widest points of the course with annotations\n\n### Map\n\nA reusable component that renders a Leaflet map with the ability to:\n\n- Display geographical data using OpenStreetMap tiles\n- Automatically fit map bounds to show all GPS points\n- Accept children components like course paths and participant markers\n- Customize initial center position and zoom level\n\n### Simulator\n\nControls the simulation of participants' movement along a course. Features include:\n\n- Start/stop/reset controls for the simulation\n- Dynamic updating of participant positions based on elapsed time\n- Real-time feedback on course length, width information, and participant count\n- Integration with ElapsedTime for timing control\n- Display of course width statistics (narrowest and widest points)\n\n### ElapsedTime\n\nA reusable timer component that displays and controls elapsed time. Features include:\n\n- Start/stop/reset functionality with both button and keyboard controls (P, S, R keys)\n- Visual display of elapsed time in minutes and seconds\n- Callback support to notify parent components of time changes\n\n### Participant\n\nA model representing a participant in the simulation. Features include:\n\n- Tracking position along a course based on clock ticks, pace, and tick duration\n- Calculating cumulative distance travelled\n- Supporting different paces (specified as minutes:seconds per kilometre)\n- Reset capability to return to starting position\n- Built to work directly with the Course class for efficient distance calculations and position determination\n\n### FitBounds\n\nA utility component that automatically adjusts the map view to fit all GPS points within the visible area.\n\n### Course Sharing\n\nShareable course functionality that allows users to share courses via URL. Features include:\n\n- Encodes course data (points, metadata, lap detection parameters) into a base64-encoded URL parameter\n- Automatically loads course data from URL when app starts\n- Generates shareable links that work across browsers\n- Includes complete course configuration including lap detection settings\n- Versioned data format for future compatibility\n\n### Component Relationships\n\n```mermaid\ngraph TD\n    App[App] --\u003e CSA[CourseSimulationApp]\n    CSA --\u003e CDI[CourseDataImporter]\n    CDI --\u003e FUS[FileUploadSection]\n    CDI --\u003e GPX[GPXFile]\n    CSA --\u003e CS[CourseSimulation]\n    CS --\u003e M[Map]\n    M --\u003e FB[FitBounds]\n    M --\u003e CD[CourseDisplay]\n    M --\u003e PD[ParticipantDisplay]\n    CS --\u003e C[Course]\n    C --\u003e CD\n    CS --\u003e S[Simulator]\n    S --\u003e ET[ElapsedTime]\n    CS --\u003e P[Participant]\n    P -.uses.-\u003e C\n    PD --\u003e P\n\n    style ET stroke:#4CAF50,stroke-width:2px\n    style GPX stroke:#4CAF50,stroke-width:2px\n    style C stroke:#4CAF50,stroke-width:2px\n    style CD stroke:#4CAF50,stroke-width:2px\n    style P stroke:#4CAF50,stroke-width:2px\n    style M stroke:#4CAF50,stroke-width:2px\n    style S stroke:#4CAF50,stroke-width:2px\n    style FB stroke:#4CAF50,stroke-width:2px\n    style App fill:#f9f9f9,stroke:#333,stroke-width:1px\n    style CSA fill:#e3f2fd,stroke:#333,stroke-width:1px\n    style CDI fill:#e8f5e9,stroke:#333,stroke-width:1px\n    style CS fill:#fff8e1,stroke:#333,stroke-width:1px\n```\n\n### Assets\n\nContains static assets such as icons for markers used in the map visualization.\n\n## Licence\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnsyweb%2Fcrashcourse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnsyweb%2Fcrashcourse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnsyweb%2Fcrashcourse/lists"}