nDate) && planDate > maxDate)) ? plan.updated_at : max;
}
return max;
}, '')
: null;
// Use cached if old array is empty/has no timestamps, or cached is newer
// Parse dates for comparison to handle format differences (+00:00 vs .000Z)
const cachedDate = new Date(cachedData.cached_at);
const maxDate = maxUpdatedAt ? new Date(maxUpdatedAt) : null;
const useCached = !maxUpdatedAt || (cachedDate && !isNaN(cachedDate) && (!maxDate || cachedDate > maxDate));
if (useCached) {
if (Array.isArray(cachedData.plans)) {
window._RestockRocketConfig.sellingPlans = cachedData.plans;
// Only use disabled_plan_ids when using cached plans
window._RestockRocketConfig.disabledSellingPlanIds = cachedData.disabled_plan_ids || [];
console.debug('[RR] Using selling plans from cachedSellingPlans (cached_at: ' + cachedData.cached_at + ')');
}
} else {
g.obfuscateInventoryQuantity = false;window._RestockRocketConfig.product = {"id":15720157053311,"title":"CUBE TOURING HYBRID ONE 600 COAL\/CHROME","handle":"cube-touring-hybrid-one-600-coal-chrome","description":"\u003cdiv\u003eWhether you're popping to the shops or exploring further afield, the Touring Hybrid ONE has everything you need. The powerful Bosch Performance motor with Smart System and Purion 200 display, 600Wh battery and easy-to-use Shimano Cues 9-speed gears make light work of any journey. There's a suspension fork, for a more comfortable ride even on rougher roads. We fitted strong Shimano hydraulic disc brakes so you can stop safely, whatever the weather. A choice of frame styles and sizes means there's a great-handling, great-looking Touring Hybrid that's perfect for you. And a full complement of accessories – Semi Integrated Carrier 2.0, mudguards, lights and kickstand – means you're all set for any eventuality.\u003cbr\u003e\u003cbr\u003e\u003cstrong\u003eFrame description\u003c\/strong
ProjektRide Merchandise
d\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eFork\u003c\/th\u003e\n\u003ctd\u003eSR Suntour X32 NLO, Tapered, 15x110mm, 100mm\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eHeadset\u003c\/th\u003e\n\u003ctd\u003eACROS AZF-1035, ICR (Integrated Cable Routing), Top Zero-Stack 1 1\/2\" (ZS 56mm), Bottom Zero-Stack 1 1\/2\" (ZS 56mm), HIC\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eStem\u003c\/th\u003e\n\u003ctd\u003eCUBE Comfort Stem Pro, 31.8mm, Adjustable\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eHandlebar\u003c\/th\u003e\n\u003ctd\u003eCUBE Comfort Trail Bar, 700mm\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eGrips\u003c\/th\u003e\n\u003ctd\u003eACID Travel Comfort\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eRear derailleur\u003c\/th\u003e\n\u003ctd\u003eShimano Cues RD-U4000-GS, 9-Speed\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eShifters\u003c\/th\u003e\n\u003ctd\u003eShima
no Cues SL-U4010- Rapidfire-Plus\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eBrakes\u003c\/th\u003e\n\u003ctd\u003eShimano BR-MT200, Hydr. Disc Brake (180)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eCrankset\u003c\/th\u003e\n\u003ctd\u003eACID Trekking Hybrid, 40T\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eCrankset chainring sizes\u003c\/th\u003e\n\u003ctd\u003e40T\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eCassette\u003c\/th\u003e\n\u003ctd\u003eShimano Cues CS-LG300, 11-46T\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eNumber of gears\u003c\/th\u003e\n\u003ctd\u003e9\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eChain\u003c\/th\u003e\n\u003ctd\u003eKMC eGlide\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eWheelset\u003c\/th\u003e\n\u003ctd\u003eACID Pro 25, 32\/32 Spokes, 15x110mm\/12x148mm, Tubeless Ready\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u
h Performance motor and 600Wh PowerTube battery are so neatly integrated into the design, you'll barely notice they're there – apart from the extra help at the pedals, of course. And Efficient Comfort Geometry is designed around a 100mm-travel suspension fork for smooth and confidence-inspiring steering, even on rough roads.\u003c\/div\u003e\u003ch3\u003eSpecification\u003c\/h3\u003e\u003ctable\u003e\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eFrame\u003c\/th\u003e\n\u003ctd\u003eAluminium Superlite, Gravity Casting Technology, Efficient Comfort Geometry, Boost148, UDH™, Fully Integrated Battery, SIC 2.0, Advanced Internal Cable Routing, Integrated Seatclamp\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eFork\u003c\/th\u003e\n\u003ctd\u003eSR Suntour X32 NLO, Tapered, 15x110mm, 100mm\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eHeadset\u003c\/th\u003e\n\u003ctd\u003eACROS AZF-1035, ICR (Integrated Cable Routing), Top Zero-Stack 1 1\/2\" (ZS 56mm), Bottom Zero-Stac
k 1 1\/2\" (ZS 56mm), HIC\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eStem\u003c\/th\u003e\n\u003ctd\u003eCUBE Comfort Stem Pro, 31.8mm, Adjustable\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eHandlebar\u003c\/th\u003e\n\u003ctd\u003eCUBE Comfort Trail Bar, 700mm\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eGrips\u003c\/th\u003e\n\u003ctd\u003eACID Travel Comfort\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eRear derailleur\u003c\/th\u003e\n\u003ctd\u003eShimano Cues RD-U4000-GS, 9-Speed\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eShifters\u003c\/th\u003e\n\u003ctd\u003eShimano Cues SL-U4010- Rapidfire-Plus\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eBrakes\u003c\/th\u003e\n\u003ctd\u003eShimano BR-MT200, Hydr. Disc Brake (180)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eCrankset\u003c\/th\u003e\n\u003ctd\u003eACID Trekking Hybrid, 40T\u003c\/td\u003e\n\u003c\/tr\u003e
indow._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
// Canary override (STOQ-1287): prefer the Render host emitted into the
// metafield-cached settings (api_host) when present, mirroring the same
// override in assets/js/api.js. cachedSettings is populated above. Falls
// back to the build-baked host for shops without the use_render_api_host
// toggle (or environments where THEME_EXTENSION_API_HOST is unset), so the
// setting.json + fetchEmbedConfig calls below route to the same host as the
// rest of the extension's API traffic instead of staying on the baked host.
window._RestockRocketConfig.host = (window._RestockRocketConfig.cachedSettings && window._RestockRocketConfig.cachedSettings.api_host) || 'https://app.restockrocket.io'
// Deployed extension build number, read from the CDN asset host Shopify generates:
// https://cdn.shopify.com/extensions/
Color<
uuid>/
<handle>-Cleaners, Degreasers and Lubrication
<version>/assets/...
// Trailing digits (e.g. ".../restockrocket-1-521/assets/" -> "521"). Kept numeric to
// match ParseStoqData, so funnel app_version lines up with the order-attribution
// app_version. Reflects the ACTUAL deployed build. This is the SINGLE source of the
// parsed version — preorder.js getAppVersion() reads it back off config rather than
// re-parsing, so the regex lives in exactly one place.
try {
const _stoqVersionMatch = window._RestockRocketConfig.scriptHost.match(/(\d+)\/?(?:assets\/?)?$/);
window._RestockRocketConfig.appVersion = (_stoqVersionMatch && _stoqVersionMatch[1]) || '';
} catch (e) {
window._RestockRocketConfig.appVersion = '';
}
const SETTINGS_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds
const LIQUID_CACHE_MAX_AGE = 15 * 60; // 15 minutes in seconds
// Calculate Liquid cache freshness once at initialization
const liquidRenderedAt = window._RestockRocketConfig.liquidRenderedAt;
// Validate timestamp and calculate ca
che age
if (!liquidRenderedAt || typeof liquidRenderedAt !== 'number' || isNaN(liquidRenderedAt)) {
console.debug('STOQ - Invalid or missing liquidRenderedAt timestamp, assuming fresh');
window._RestockRocketConfig.isLiquidCacheFresh = true;
window._RestockRocketConfig.liquidCacheAge = null;
} else {
const now = Math.floor(Date.now() / 1000); // Current time in seconds
const liquidCacheAge = now - liquidRenderedAt; // Age in seconds
// Surfaced into funnel events: a stale cache means the app rendered with
// outdated inventory/selling-plan data — a real "had the opportunity but
// failed" cause. Negative (client clock ahead) clamps to 0.
window._RestockRocketConfig.liquidCacheAge = Math.max(0, liquidCacheAge);
// Handle client clock ahead of server
if (liquidCacheAge
(vidEl && vidEl.value) || _sqTrack.selected_variant_id || '';
// The enabled STOQ selling plan the clicked variant belongs to (if any), found once and
// reused for in_enabled_plan / enrolled_plan_id / enrolled_plan_provider below.
var _sqVidNum = Number(variantId);
var _sqPlan = null;
// Array.isArray guard (not `|| []`) so a truthy non-array sellingPlans can't throw and
// silently drop the whole publish.
var _sqPlans = Array.isArray(_sqTrack.sellingPlans) ? _sqTrack.sellingPlans : [];
_sqPlans.forEach(function (pl) {
if (!_sqPlan && pl && pl.enabled && Array.isArray(pl.variant_ids) &&
pl.variant_ids.indexOf(_sqVidNum) !== -1) { _sqPlan = pl; }
});
Shopify?.analytics?.publish?.('stoq_accelerated_checkout_clicked', {
variant_id: variantId,
product_id: (_sqTrack.product && _sqTrack.product.id) || '',
channel: channel,
market_id: _sqTrac
k.marketId || '',
country_code: _sqTrack.countryIsoCode || '',
page_type: _sqTrack.pageType || '',
cart_token: _sqTrack.cartToken || '',
page_url: (window.location && window.location.href) || '',
properties: {
// Mirror the bundle's own preorder check (preorder.js checkInventoryProvider-
// WithCachedFallback): the live set config.preorderVariantIds (refreshed after
// page load by loadVariantInventoryData) OR the Liquid-injected
// cachedPreorderVariantIds — always present, so it covers clicks before the
// bundle loads (why this tracker is inline). ORing both (not preferring one)
// matches the bundle and is correct even if the live set is an empty array. Both
// hold integer ids; the click-time id comes off a DOM input (.value → string) or
// selected_variant_id, so coerce with Number for a like-typed compare.
is_preord
er_variant: (function () {
var vid = Number(variantId);
var has = function (a) { return Array.isArray(a) && a.indexOf(vid) !== -1; };
return has(_sqTrack.preorderVariantIds) ||
has(_sqTrack.cachedPreorderVariantIds &&
_sqTrack.cachedPreorderVariantIds.preorder_variant_ids);
})(),
// Narrow, authoritative preorder signal: enrolled in an ENABLED STOQ selling plan
// (is_preorder_variant above is the broad OOS+continue heuristic — non-STOQ too).
in_enabled_plan: !!_sqPlan,
// In-stock preorder signal: enrolled but currently IN STOCK (in the inStockVariantIds
// set, not the OOS preorderVariantIds set). Same live-OR-cached pattern as
// is_preorder_variant. is_preorder_variant OR is_instock_variant = "should sell via
// the plan" regardless of stock, so an in-stock preorder bypass is detectable too.
is_
instock_variant: (function () {
var has = function (a) { return Array.isArray(a) && a.indexOf(_sqVidNum) !== -1; };
return has(_sqTrack.inStockVariantIds) ||
has(_sqTrack.cachedInStockVariantIds &&
_sqTrack.cachedInStockVariantIds.in_stock_variant_ids);
})(),
// The enrolled plan's Shopify selling-plan id + inventory_provider (stoq = STOQ tracks
// the OOS count; shopify = in-stock preorder). Tells order-debug what kind of preorder
// the Buy Now bypassed, without a downstream lookup.
enrolled_plan_id: (_sqPlan && (_sqPlan.shopify_selling_plan_id || _sqPlan.shopify_selling_plan_group_id)) || '',
enrolled_plan_provider: (_sqPlan && _sqPlan.inventory_provider) || '',
block_enabled: !!(_sqTrack.cachedSettings && _sqTrack.cachedSettings.block_accelerated_checkout),
gate_armed: !!_sqTrack.acceleratedGateArmed,
gate_active
return settings;
}
console.debug(`STOQ - Applying translations for normalized locale: ${normalizedLocale} (original: ${window._RestockRocketConfig.locale})`);
const translatedFields = translations[normalizedLocale];
if (translatedFields && typeof translatedFields === 'object') {
Object.keys(translatedFields).forEach(function(key) {
const value = translatedFields[key];
if (value !== null && value !== undefined && value !== '') {
settings[key] = value;
}
});
} else {
console.debug('STOQ - No translated fields found for locale:', normalizedLocale);
}
delete settings.translations;
return settings;
} catch (e) {
console.debug('STOQ - error applying translations:', e);
return settings;
}
}
// Setup event listener for cart selling plan updates
// This must be called before any scripts are loaded to avoid race conditions
function setupCartSellingPlanUpdater(settings) {
Handlebars
Can charge without removing battery via compatible mounts
StemsCan charge battery directly off the bike with adapters sold separately
Fast charging time, up to 80 percent charge in 2 hours consult dealer manual for accuratefull charging times for the battery you are using
Grips & Bar-Tape
Requires SMBCC16 power cable (sold separately)
Please get in touch with a member of the team either by phone (
01313745324Åland Islands (EUR€)
) or email (
Åland Islands (EUR€)
[email protected]
) where on of the team will be more than happy to help.
ProjektRide Bike Shop EdinburghAlbania (ALLL)
Albania (ALLL)
Algeria (DZDد.ج)
If the item is showing in stock, we aim to post the product within 24 hours. Please allow 5 working days to receive the item.
Postage is free on orders over £50. Orders under £50, our postage charge is £3.99.Andorra (EUR€)
We also have a physical store, if you are local please pop in -
Andorra (EUR€)
The goal for the new OneUp Carbon Handlebars was to make the best feeling bar possible, something that would let us ride harder for longer.
The solution is our patent pending oval shape which combines the best ride characteristics of 31.8mm and 35mm bar standards into one package. This is the most comfortable bar we’ve ever ridden, period. It's strong, lightweight minimizes arm pump and vibration and maximizes steering response. 35 done right.
Almost every other carbon bar on the market copies the simple tapered profile of an Aluminum bar. With carbon you can take advantage of more complex shapes to get a better performing product, so that's what we did. If you actually care about bar compliance, then you don't make a regular 35mm diameter bar. Sure you can try to "optimize" the flex slightly with layup, but geometry is king and you're fighting a losing battle.
The OneUp bar profile minimizes the length of the 35 diameter clamping area as this is the stiffest portior.n of any 35 diameter bar. The 35mm clamp diameter quickly changes to a flattened, oval shape in the transition zone and then to a standard 22.2mm clamp diameter for the control zone.
We bench marked the OneUp bar against the most popular carbon bars on the market as well as foam filled aluminum bars. The results were, on average, a 21% increase in vertical compliance (comfort) coupled with a 28% increase in steering stiffness (responsiveness). These are more than just marginal gains.
Until now the 35mm diameter standard has had a bad reputation and rightly so. This is 35 Dia. done right.
Geometry:
800mm Wide / 35mm Dia. / Sweep 8° Back 5° Up
Weight
: 20mm Rise (220g) 35mm Rise (225g)
Max Stem Clamp Width
: 65mm
Max Stem Clamp Torque:
6Nm
Max Lever Clamp Torque
: 5NmClose
Minimum Trim width
: 740mm
Colour
: Black. Decal kits: Available in Red, Green, Blue, Orange, Purple & White