NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Strava route planner for all // @namespace xsanda // @description Use the Strava route planner // @version 0.3.0 // @include https://www.strava.com/routes/new* // @include https://www.strava.com/routes/*/edit* // @include https://www.strava.com/athletes/*/training/log // @include https://www.strava.com/athlete/heatmaps* // @require https://openuserjs.org/src/libs/xsanda/Run_code_as_client.js // @updateURL https://openuserjs.org/meta/xsanda/Strava_route_planner_for_all.meta.js // @downloadURL https://openuserjs.org/install/xsanda/Strava_route_planner_for_all.user.js // @run-at document-start // @grant none // @license MIT // ==/UserScript== /* jshint esversion: 6 */ /* globals Waiter */ runAsClient(() => { console.log('Trying to enable premium route editor'); const addSetHandler = (object, property, didSet) => { let value = object[property]; Object.defineProperty(object, property, { set: (newValue) => didSet(value = newValue), get: () => value, }); if (value) { didSet(value); } } addSetHandler(window, '__NEXT_DATA__', data => { if (!data.props) return; data.props.currentAthletePreload.is_subscriber = true; if (data.props.currentAthletePreload.features) { for (const key of Object.keys(data.props.currentAthletePreload.features)) { data.props.currentAthletePreload.features[key] = true; } } if (data.props.pageProps.metadata) data.props.pageProps.metadata.is_paywalled = false; console.log("Premium route editor enabled"); }); setTimeout(function(open, send) { const requests = new WeakMap(); window.XMLHttpRequest.prototype.open = function() { requests.set(this, [...arguments]); open.apply(this, arguments); }; window.XMLHttpRequest.prototype.send = function(data) { const [method, path] = requests.get(this) if (method === 'POST' && path === "https://www.strava.com/frontend/routes") { const parsedData = JSON.parse(data); parsedData.original_route_id ??= "1"; data = JSON.stringify(parsedData); } send.call(this, data); }; }, 1000, window.XMLHttpRequest.prototype.open, window.XMLHttpRequest.prototype.send); });