{"id":13821982,"url":"https://github.com/thomaschampagne/elevate","last_synced_at":"2025-12-17T06:49:05.816Z","repository":{"id":21735067,"uuid":"25056806","full_name":"thomaschampagne/elevate","owner":"thomaschampagne","description":"A sport app to \"Elevate\" your training experience and goals! Track your fitness and progressions over time. Analyse deeper your activities. And more...","archived":false,"fork":false,"pushed_at":"2025-08-25T16:36:24.000Z","size":53990,"stargazers_count":1353,"open_issues_count":162,"forks_count":185,"subscribers_count":47,"default_branch":"develop","last_synced_at":"2025-08-25T18:28:35.725Z","etag":null,"topics":["angular","chrome","cycling","electron","running","strava","swim","webextension"],"latest_commit_sha":null,"homepage":"https://thomaschampagne.github.io/elevate-docs/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomaschampagne.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}},"created_at":"2014-10-10T23:24:52.000Z","updated_at":"2025-08-25T16:35:01.000Z","dependencies_parsed_at":"2023-01-12T03:45:54.674Z","dependency_job_id":"8ccdfcaa-3e65-45bd-99bc-38f81d105f7d","html_url":"https://github.com/thomaschampagne/elevate","commit_stats":null,"previous_names":[],"tags_count":184,"template":false,"template_full_name":null,"purl":"pkg:github/thomaschampagne/elevate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaschampagne%2Felevate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaschampagne%2Felevate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaschampagne%2Felevate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaschampagne%2Felevate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomaschampagne","download_url":"https://codeload.github.com/thomaschampagne/elevate/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaschampagne%2Felevate/sbom","scorecard":{"id":882297,"data":{"date":"2025-08-11","repo":{"name":"github.com/thomaschampagne/elevate","commit":"9ddddb43e2f0c60bf7823820605c25ed887ee80c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/26 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:16","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:17","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: resources/settings.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'develop'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 7.2.1 not signed: https://api.github.com/repos/thomaschampagne/elevate/releases/183255552","Warn: release artifact 7.2.0 not signed: https://api.github.com/repos/thomaschampagne/elevate/releases/169669419","Warn: release artifact 7.1.0 not signed: https://api.github.com/repos/thomaschampagne/elevate/releases/153579404","Warn: release artifact 7.0.0-beta.5 not signed: https://api.github.com/repos/thomaschampagne/elevate/releases/67770313","Warn: release artifact 7.0.0-beta.4 not signed: https://api.github.com/repos/thomaschampagne/elevate/releases/64578228","Warn: release artifact 7.2.1 does not have provenance: https://api.github.com/repos/thomaschampagne/elevate/releases/183255552","Warn: release artifact 7.2.0 does not have provenance: https://api.github.com/repos/thomaschampagne/elevate/releases/169669419","Warn: release artifact 7.1.0 does not have provenance: https://api.github.com/repos/thomaschampagne/elevate/releases/153579404","Warn: release artifact 7.0.0-beta.5 does not have provenance: https://api.github.com/repos/thomaschampagne/elevate/releases/67770313","Warn: release artifact 7.0.0-beta.4 does not have provenance: https://api.github.com/repos/thomaschampagne/elevate/releases/64578228"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"SAST","score":8,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 3 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/thomaschampagne/elevate/codeql.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/thomaschampagne/elevate/codeql.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/thomaschampagne/elevate/codeql.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/thomaschampagne/elevate/codeql.yml/develop?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating node to node@sha256:d2b6b5aedb5b729f68ee1129e0f5a5d4713d93f82448249e82241876d8e8d86e","Warn: npmCommand not pinned by hash: Dockerfile:6","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":0,"reason":"64 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-593m-55hh-j8gv","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-36jr-mh4h-2g58","Warn: Project is vulnerable to: GHSA-p2jh-44qj-pf2v","Warn: Project is vulnerable to: GHSA-p7v2-p9m8-qqg7","Warn: Project is vulnerable to: GHSA-7x97-j373-85x5","Warn: Project is vulnerable to: GHSA-7m48-wc93-9g85","Warn: Project is vulnerable to: GHSA-qqvq-6xgj-jw8g","Warn: Project is vulnerable to: GHSA-6r2x-8pq8-9489","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-4www-5p9h-95mh","Warn: Project is vulnerable to: GHSA-9gqv-wp59-fq42","Warn: Project is vulnerable to: GHSA-3wc5-fcw2-2329","Warn: Project is vulnerable to: GHSA-64fm-8hw2-v72w","Warn: Project is vulnerable to: GHSA-f98w-7cxr-ff2h","Warn: Project is vulnerable to: GHSA-cg87-wmx4-v546","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-776f-qx25-q3cc","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-8hc4-vh64-cxmj","Warn: Project is vulnerable to: GHSA-jr5f-v2jv-69x6","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-9jxc-qjr9-vjxq","Warn: Project is vulnerable to: GHSA-x3cc-x39p-42qx","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T08:40:06.306Z","repository_id":21735067,"created_at":"2025-08-24T08:40:06.306Z","updated_at":"2025-08-24T08:40:06.306Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27778826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-17T02:00:08.291Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["angular","chrome","cycling","electron","running","strava","swim","webextension"],"created_at":"2024-08-04T08:01:37.033Z","updated_at":"2025-12-17T06:49:05.803Z","avatar_url":"https://github.com/thomaschampagne.png","language":"TypeScript","readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"./resources/elevate_logo.svg\" alt=\"Markdownify\" width=\"300\"\u003e\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003e✨ A sport app to \"Elevate\" your training experience and goals! Track your fitness and progressions over time. Analyse deeper your activities. And more...\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#screenshots-and-features\"\u003eScreenshots\u003c/a\u003e •\n  \u003ca href=\"#desktop-app\"\u003eDesktop App\u003c/a\u003e •\n  \u003ca href=\"#web-extension\"\u003eWeb Extension (For Strava)\u003c/a\u003e •\n  \u003ca href=\"#development\"\u003eDevelopment\u003c/a\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/fitness-chart.png\" alt=\"fitness-chart\" /\u003e\n\u003c/p\u003e\n\n\u003c!-- toc --\u003e\n- [Screenshots And Features](#screenshots-and-features)\n- [Install](#install)\n  - [Desktop App](#desktop-app)\n    - [Download \\\u0026 Install](#download--install)\n    - [Build from sources](#build-from-sources)\n  - [Web extension](#web-extension)\n    - [Download for _Chrome, Chromium, Edge (from 2020), Brave, Opera, Vivaldi, Yandex, ..._](#download-for-chrome-chromium-edge-from-2020-brave-opera-vivaldi-yandex-)\n    - [From the sources](#from-the-sources)\n- [Star History](#star-history)\n- [Development](#development)\n  - [Global solution structure](#global-solution-structure)\n    - [App-core project](#app-core-project)\n    - [Desktop project](#desktop-project)\n    - [Web-extension project](#web-extension-project)\n  - [Environments setup](#environments-setup)\n    - [Install requirements](#install-requirements)\n    - [Clone the git-flow based project](#clone-the-git-flow-based-project)\n    - [Desktop development environment](#desktop-development-environment)\n    - [Web extension development environment](#web-extension-development-environment)\n  - [Build with docker](#build-with-docker)\n    - [Desktop app](#desktop-app-1)\n    - [Web extension](#web-extension-1)\n- [Appendix](#appendix)\n  - [Add a new desktop migration for a next release](#add-a-new-desktop-migration-for-a-next-release)\n  - [Sign application](#sign-application)\n    - [Self-sign with OpenSSL for windows build](#self-sign-with-openssl-for-windows-build)\n  - [Publish to github releases](#publish-to-github-releases)\n  - [Use custom browser for unit-testing (web-extension only)](#use-custom-browser-for-unit-testing-web-extension-only)\n  - [Desktop: Debug the calculated watts against real power](#desktop-debug-the-calculated-watts-against-real-power)\n\n\u003c!-- tocstop --\u003e\n\n## Screenshots And Features\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/fitness-chart.png\" alt=\"fitness-chart\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eTrack your long-term fitness trend and performance improvements visually.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/activities.png\" alt=\"activities\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eBrowse and filter your recorded rides with summary statistics for each activity.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/activity-main.png\" alt=\"activity-main\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eReview in-depth ride details including map and core metrics for every session.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/activity-stats.png\" alt=\"activity-stats\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eView essential ride stats including averages and highlight metrics for each activity.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/activity-peaks.png\" alt=\"activity-peaks\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eSee peak values for power, heart rate, speed, and cadence across your ride.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/activity-zones.png\" alt=\"activity-zones\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eExplore how much time was spent in various heart rate, power, and cadence zones during a ride.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/activity-splits.png\" alt=\"activity-splits\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eAnalyze best splits and key segment statistics like fastest speeds and highest cadence.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/year-progress-ytd.png\" alt=\"year-progress-ytd\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eMonitor your yearly progression with cumulative activity and training volume charts.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/year-progress-rolling-volume.png\" alt=\"year-progress-rolling-volume\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eVisualize rolling training volume and track period-over-period improvements.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/athlete-settings.png\" alt=\"athlete-settings\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eAdjust personal data, physical metrics, and measurement preferences over time.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/zones-settings-hr.png\" alt=\"zones-settings-hr\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eCustomize your training zones for heart rate, power, and cadence.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.screenshots/connectors.png\" alt=\"connectors\" /\u003e\n  \u003cbr\u003e\n  \u003cem\u003eManage integrations with external services and sync activities easily.\u003c/em\u003e\n\u003c/p\u003e\n\n## Install\n\n### Desktop App\n\n#### Download \u0026 Install\n\n- [For Windows](https://thomaschampagne.github.io/elevate-docs/Download-%26-Install/Windows/)\n- [For macOS](https://thomaschampagne.github.io/elevate-docs/Download-%26-Install/macOS/)\n- For Linux: not shipped yet\n\n#### Build from sources\n\nGo to chapter [Environment setup](#environments-setup).\n\n### Web extension\n\n#### Download for _Chrome, Chromium, Edge (from 2020), Brave, Opera, Vivaldi, Yandex, ..._\n\nGo to [Chrome Web Store](https://chromewebstore.google.com/detail/elevate-for-strava/dhiaggccakkgdfcadnklkbljcgicpckn)\n\n#### From the sources\n\nGo to chapter [Environment setup](#environments-setup).\n\n## Star History\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://api.star-history.com/svg?repos=thomaschampagne/elevate\u0026type=Date)](https://www.star-history.com/#thomaschampagne/elevate\u0026Date\" alt=\"Star History\" /\u003e\n\u003c/p\u003e\n\n## Development\n\nThis section covers the environment setup to develop and build both desktop app and web extension.\n\n### Global solution structure\n\nThe solution is cut in 3 folders/projects: the `appcore`, the `desktop` \u0026 `webextension`\n\n#### App-core project\n\nContains the _Elevate App_ shared and loaded by both `desktop` and `webextension`projects. Appcore contains core features like _fitness trend, year progressions, athlete settings..._\n\nThe `Appcore` main technology stack is:\n\n- [Typescript](https://www.typescriptlang.org/) as programming language.\n- [Angular](https://angular.io/) as frontend (build with [@angular/cli](https://cli.angular.io/)).\n- [Angular Material](https://material.angular.io/) for material designed components.\n- [Metrics Graphics](https://www.metricsgraphicsjs.org/), [Plotly](https://plotly.com/javascript/) \u0026 [D3](https://d3js.org/) for charting.\n- [LokiJS](https://https://github.com/techfort/LokiJS) as in-memory NoSQL database persisted in IndexedDB.\n- [Jest](https://jestjs.io/) as Javascript test runner (instead of \"stock\" karma one).\n\n#### Desktop project\n\nHolds the container behaviour to provide a cross-platform desktop app under _Windows, Linux \u0026 MacOS_. It contains desktop specific features like _connectors synchronization_ (to fetch athlete activities from external).\n\nThe `Desktop` main technology stack is:\n\n- [Typescript](https://www.typescriptlang.org/) as programming language.\n- [Jest](https://jestjs.io/) as Javascript test runner.\n- [Electron](https://electronjs.org/) as cross-platform desktop container.\n- [Electron-builder](https://www.electron.build/) to build, sign and publish installers per platform. Also handle app updates process (via `electron-updater`).\n- [Rollup.js](https://rollupjs.org/guide/en/) to load \u0026 bundle modules.\n- [Vue.js](https://vuejs.org/) for splash-screen update window.\n\n#### Web-extension project\n\nContains the web extension behaviour that acts directly on _strava.com_ website. This includes _extended stats on activities \u0026 segments efforts, best splits, etc..._\n\n### Environments setup\n\n#### Install requirements\n\nYou will need to install [NodeJS](https://nodejs.org) (v15+) to build both desktop and chrome web extension.\n\n#### Clone the [git-flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) based project\n\n```bash\ngit clone https://github.com/thomaschampagne/elevate.git\n```\n\nor\n\n```bash\ngit clone git@github.com:thomaschampagne/elevate.git\n```\n\nThe new mono-repo including the desktop app and the web extension is on `develop-new` branch at the moment. So checkout/track this branch to build the desktop app:\n\n```bash\ncd ./elevate\ngit checkout --track origin/develop-new\n```\n\nThen install npm dependencies:\n\n```bash\nnpm install\n```\n\nRun solution tests (`appcore` + `desktop` + `webextension`):\n\n```bash\nnpm test\n```\n\n(_Should be executed with success for any pull request submission_).\n\n#### Desktop development environment\n\nAll commands displayed in this section will be executed in `./desktop/` folder. So:\n\n```bash\ncd ./desktop/\n```\n\n- Run in development:\n\n```bash\nnpm start\n```\n\n\u003e This npm task will create a `./desktop/dist` output folder and re-compile both `appcore` and `desktop` projects on any code changes\n\nTo open the desktop app, open another terminal, then run:\n\n```bash\nnpm run launch:dev:app\n```\n\n- Run unit tests:\n\n```bash\nnpm test\n```\n\n- Generate production installers and publish them per platforms:\n\nFirst switch to desktop directory with `cd desktop/`\n\n- Build `Windows` `x64` `.exe`:\n\n  ```bash\n  npm run build:publish:windows\n  ```\n\n- Build `Linux` `x64` `.deb`:\n\n  ```bash\n  npm run build:publish:linux\n  ```\n\n- Build `MacOS` `x64` `.dmg` :\n\n  ```bash\n  npm run build:publish:macos\n  ```\n\n\u003e Output installers will be located in `./desktop/package/`\n\u003e The build targets are defined in `./desktop/package.json` (`build` key section). See [https://www.electron.build](https://www.electron.build) for more info.\n\n- (Optional) To sign the production installers read the [how to sign appendix](#sign-application)\n\n- (Optional) To publish the production installers on github read the [how to publish on github appendix](#publish-to-github-releases)\n\n- Clean outputs:\n\n```bash\nnpm run clean\n```\n\n#### Web extension development environment\n\n_To develop the web extension, you need a Chrome based browser such as Chrome, Chromium, Edge (from 2020), Brave, Opera, Vivaldi, Yandex, ..._\n\nAll commands displayed in this section will be executed in `./webextension/` folder. So:\n\n```bash\ncd ./webextension/\n```\n\n- Run in development:\n\n```bash\nnpm start\n```\n\n\u003e This npm task will create a `./webextension/dist` output folder and re-compile both `appcore` and `webextension` projects on any code changes\n\n- To load the web extension into your chrome based browser:\n\n  - Open new tab and type `chrome://extensions`, then enter.\n  - Tick `Developer Mode` checkbox.\n  - Click `Load Unpacked Extension` button, then choose `./webextension/dist` directory (this is where you have the `manifest.json` file)\n  - Make sure to disable other instances of elevate. You can re-enable them back from same tab.\n  - Open strava.com OR click on the Elevate icon in the browser toolbar.\n\n- Run unit tests\n\n```bash\nnpm test\n```\n\n- Production package\n\nYou can package the extension with the following command\n\n```bash\nnpm run package\n```\n\n\u003e Output release will be located in `./webextension/package/`\n\n- Clean outputs:\n\n```bash\nnpm run clean\n```\n\n### Build with docker\n\n#### Desktop app\n\n@TODO\n\n#### Web extension\n\nCreate docker your image from `Dockerfile`\n\n```bash\ndocker build . -t elevate-chrome-builder\n```\n\nRun a docker production build through a container. Replace `/path/to/your/directory/` with a folder on your host to fetch the packaged build when done.\n\n```bash\ndocker run --rm --name elevate-chrome-build -v /path/to/your/directory/:/package elevate-chrome-builder\n```\n\n## Appendix\n\n### Add a new desktop migration for a next release\n\nRegister your new migration in below file\n\n```bash\n./appcore/src/app/desktop/migration/desktop-registered-migrations.ts\n```\n\n**Tip:** to emulate a version upgrade, you may downgrade the `version` property inside `ipc.storage.json` file (user app data folder)\n\n### Sign application\n\n#### Self-sign with OpenSSL for windows build\n\n- Create \u0026 edit a `code_sign.cnf` openssl config:\n\n```bash\n[req]\ndistinguished_name = req_distinguished_name\nx509_extensions = v3_req\nprompt = no\n[req_distinguished_name]\ncountryName             = FR\nstateOrProvinceName     = Rhone Alpes\nlocalityName            = Grenoble\norganizationName        = Elevate\ncommonName              = Elevate Sports App\nemailAddress            = you@email.com\n\n[v3_req]\nbasicConstraints        = CA:FALSE\nkeyUsage                = critical,digitalSignature\nextendedKeyUsage        = critical,codeSigning\n```\n\n- Generate private key and certificate with a `passphrase`\n\n```bash\nopenssl req -x509 -newkey rsa:4096 -sha256 -keyout code_sign.key -out code_sign.crt -days 3650 -config code_sign.cnf\n```  \n\n- Create `.pxf` file from the private key and certificate previously generated. `.pxf` file will be used to sign app under windows.\n\n```bash\nopenssl pkcs12 -export -legacy -name \"elevate-sports-app\" -out code_sign.pfx -inkey code_sign.key -in code_sign.crt\n```\n\n- Convert `.pxf` file to `base64`\n\n```bash\nbase64 code_sign.pfx -w 0\n```\n\n- Create/edit `electron-builder.env` file under `./desktop/` folder, and add following keys:\n\n```bash\nCSC_LINK=\nCSC_KEY_PASSWORD=\n```\n\n- Assign the `base64` previously generated to the key `CSC_LINK`\n\n- Assign the `passphrase` previously used to the key `CSC_KEY_PASSWORD`\n\n- Then run packaging for windows:\n\n```bash\nnpm run package:windows\n```\n\n### Publish to github releases\n\n- Generate a github personal access token at [https://github.com/settings/tokens/new](https://github.com/settings/tokens/new)\n\n- Tick `write:packages` scope. The `repo` and `read:packages` scopes should be automatically ticked too. Leave them ticked.\n\n- Enter a `Note` for your token, then click `Generate token`. Keep this token safe. If lost you will have to re-generate one.\n\n- Create/edit `electron-builder.env` file under `./desktop/` folder, and add following key:\n\n```bash\nGH_TOKEN=\n```\n\n- Assign the generated token to the key `GH_TOKEN`.\n\n- Open `./desktop/package.json` file and go to the key `build.publish`.\n\n- Edit the `owner` and `repo` variables to match with your target github repository.\n\n_Note: To publish a new version on github, a github `draft release` has to exist on the remote target repo.\nThe github `draft release` value should match the `version` value of `./desktop/package.json` file.\nNew version must be compliant with [semver convention](https://semver.org/) and higher than previous version if exists.\nYou can use this [semver compare tool](https://semvercompare.azurewebsites.net/) that your new version is higher than your previous one._\n\n- Open [https://github.com/your_owner/your_repo/releases](https://github.com/your_owner/your_repo/releases) and click `Draft a new release`.\n\n- Enter the semver version to draft and click `Save draft`.\n\n_Note: You may already pushed a git tag matching your version. If not, the git tag will be created on publish._\n\n- Run packaging to publish installer:\n\n```bash\nnpm run publish:win\n```\n\nor\n\n```bash\nnpm run publish:mac\n```\n\n- Open [https://github.com/your_owner/your_repo/releases/edit/your_version](https://github.com/your_owner/your_repo/releases/edit/your_version): Some files should have been uploaded on the github draft release.\n\n- You can update the uploaded files draft with a new packaging process. Once ready, click `Publish release`: users will receive the update.\n\n### Use custom browser for unit-testing (web-extension only)\n\nCreate a `browsers.karma.conf.js` file in `webextension` folder.\n\nTo run unit test in a headless **chromium** instead of **chrome**, inject below javascript code:\n\n```javascript\nmodule.exports = {\n    browsers: [\n        \"HeadlessChrome\"\n    ],\n    customLaunchers: {\n        HeadlessChrome: {\n            base: \"Chromium\",\n            flags: [\n                \"--no-sandbox\",\n                // See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md\n                \"--headless\",\n                \"--disable-gpu\",\n                // Without a remote debugging port, Google Chrome exits immediately.\n                \" --remote-debugging-port=9222\"\n            ]\n        }\n    }\n};\n```\n\n### Desktop: Debug the calculated watts against real power\n\n\u003e This works in development build only\n\n- Create a new local storage key named `DEBUG_EST_VS_REAL_WATTS` and set it to `true`\n- Reload application and go to activities performed with a real power meter (cycling or running)\n","funding_links":[],"categories":["TypeScript","📊 Statistics","Awesome health \u0026 fitness Free/Open Source projects","Strava \u0026 Garmin Tools"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomaschampagne%2Felevate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomaschampagne%2Felevate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomaschampagne%2Felevate/lists"}