003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cstrong\u003ePeregrine Tech and FAQ\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe EBB set screws should be torqued to a maximum of 6Nm or it may deform the shell and insert. The EBB should be covered with a thin coat of grease and maintained periodically by removing, cleaning and re-greasing the insert and bolts. \u003c\/li\u003e\n\u003cli\u003eThe seat binder bolt should be torqued to 8-10Nm. If this is insufficient to prevent seat post slippage please contact us. Some frames were shipped with an incorrect spec bolt which bottoms out before the seat post is fully tight. Please contact us for a replacement if this is the case. \u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003eThe derailleur hanger is designed to only be loosely held by the mounting bolt. The hanger is tightened to the frame by tightening the thru axle so that it is clamped and supported properly in the dropout and not by the hanger retaining bolt. Many thru axle frames have a s
Workshop Prices
imilar floating axle retention nut mechanism. \u003c\/span\u003e\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003eThe frame and fork are fully tested and compliant with ISO standards for touring bicycles. Used as intended, it is warranted against defect for five years for the original owner. The frameset is not intended for technical off road riding or jumping.\u003c\/span\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","published_at":"2023-02-28T15:33:13+00:00","created_at":"2023-02-22T11:45:11+00:00","vendor":"ProjektRide","type":"","tags":["bikes","frames","Road","singular","Touring"],"price":110000,"price_min":110000,"price_max":110000,"available":false,"price_varies":false,"compare_at_price":null,"compare_at_price_min":0,"compare_at_price_max":0,"compare_at_price_varies":false,"variants":[{"id":43854872150242,"title":"Small","option1":"Small","option2":null,"option3":null,"sku":"","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Singular Peregrine Frameset - Singular Blue -
- Small","public_title":"Small","options":["Small"],"price":110000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":43854872183010,"title":"Medium","option1":"Medium","option2":null,"option3":null,"sku":"","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Singular Peregrine Frameset - Singular Blue - Medium","public_title":"Medium","options":["Medium"],"price":110000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":43854872215778,"title":"Large","option1":"Large","option2":null,"option3":null,"sku":"","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Singular Peregrine Frameset - Singular Blue - Large","public_title":"Large","options":["Large"],"price":110000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","r
Cycle to Work
equires_selling_plan":false,"selling_plan_allocations":[]},{"id":43854872248546,"title":"Extra Large","option1":"Extra Large","option2":null,"option3":null,"sku":"","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Singular Peregrine Frameset - Singular Blue - Extra Large","public_title":"Extra Large","options":["Extra Large"],"price":110000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]}],"images":["\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.04.png?v=1677148552","\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.14.png?v=1677148552","\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.32.png?v=1677148552","\/\/projektride.co.uk\/cdn\/shop\/products\/6C92159C-CA26-407A-8494-BAB89BCEC710.jpg?v=1677598381","\/\/projektride.co.uk\/cdn\/shop\/products\/62E0D937-16A2-459B-B908-7F35F75BF000.jpg?v=1677598382","\/\/projektride.co.uk\/cdn\/shop\/products\/66FA4223-568F-4002-8BB4-D5C70452D11A.jpg?v=1677598381","\/\/projektride.co.uk\/cdn\/shop\/products\/6EF84198-41FA-4888-84CB-EEF008273476.jpg?v=1677598382"],"featured_image":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.04.png?v=1677148552","options":["Size"],"media":[{"alt":null,"id":31612340732130,"position":1,"preview_image":{"aspect_ratio":1.62,"height":742,"width":1202,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.04.png?v=1677148552"},"aspect_ratio":1.62,"height":742,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.04.png?v=1677148552","width":1202},{"alt":null,"id":31612340764898,"position":2,"preview_image":{"aspect_ratio":1.449,"height":1390,"width":2014,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.14.png?v=1677148552"},"aspect_ratio":1.449,"height":1390,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/producWorkshop PricesDelivery & Returns
ts\/Screenshot2023-02-23at10.30.14.png?v=1677148552","width":2014},{"alt":null,"id":31612340797666,"position":3,"preview_image":{"aspect_ratio":1.449,"height":1390,"width":2014,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.32.png?v=1677148552"},"aspect_ratio":1.449,"height":1390,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2023-02-23at10.30.32.png?v=1677148552","width":2014},{"alt":null,"id":31626742989026,"position":4,"preview_image":{"aspect_ratio":1.505,"height":3264,"width":4912,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/6C92159C-CA26-407A-8494-BAB89BCEC710.jpg?v=1677598381"},"aspect_ratio":1.505,"height":3264,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/6C92159C-CA26-407A-8494-BAB89BCEC710.jpg?v=1677598381","width":4912},{"alt":null,"id":31626743021794,"position":5,"preview_image":{"aspect_ratio":1.505,"height":3264,"width":4912,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/62E0D937-16A2-459B-B908-7F35F75BF000.jpg?v=1677598382"},"aspect_ratio":1.505,"height":3264,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/62E0D937-16A2-459B-B908-7F35F75BF000.jpg?v=1677598382","width":4912},{"alt":null,"id":31626743054562,"position":6,"preview_image":{"aspect_ratio":1.505,"height":3264,"width":4912,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/66FA4223-568F-4002-8BB4-D5C70452D11A.jpg?v=1677598381"},"aspect_ratio":1.505,"height":3264,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/66FA4223-568F-4002-8BB4-D5C70452D11A.jpg?v=1677598381","width":4912},{"alt":null,"id":31626743087330,"position":7,"preview_image":{"aspect_ratio":1.505,"height":3264,"width":4912,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/6EF84198-41FA-4888-84CB-EEF008273476.jpg?v=1677598382"},"aspect_ratio":1.505,"height":3264,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/6EF84198-41FA-4888-84CB-EEF008273476.jpg?v=1677598382","width":4912}],"requires_selling_plan":fal
se,"selling_plan_groups":[],"content":"\u003cp\u003eSingular Peregrine Frameset \u003c\/p\u003e\n\u003cp\u003ehttps:\/\/singularcycles.com\/products\/peregrine\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eSpecifications\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eCustom drawn triple butted cro-moly steel tubing\u003c\/li\u003e\n\u003cli\u003eLugged head tube and seat cluster\u003c\/li\u003e\n\u003cli\u003eFlat mount 160mm brake fitment\u003c\/li\u003e\n\u003cli\u003e12mm thru axles – 142mm rear spacing, 100mm front\u003c\/li\u003e\n\u003cli\u003eEccentric Bottom Bracket insert – 68mm BSA threaded shell.\u003c\/li\u003e\n\u003cli\u003eClearance for Shimano road width cranks with \u0026lt;48\/34 chainrings\u003c\/li\u003e\n\u003cli\u003eTyre clearance for max 622x55mm (29×2.1”) or 584x65mm (27.5×2.3”)\u003c\/li\u003e\n\u003cli\u003eBolt on modular cable guides under down tube\u003c\/li\u003e\n\u003cli\u003eDouble chainring compatible\u003c\/li\u003e\n\u003cli\u003e27.2mm seat
- tube diameter\u003c\/li\u003e\n\u003cli\u003e1 ⅛” external bearing head tube (34mm ID) for straight steerer fork\u003c\/li\u003e\n\u003cli\u003eElectrostatic Deposition (ED) anti-corrosion treatment\u003c\/li\u003e\n\u003cli\u003eFour frame sizes from Small to Extra Large.\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003eMidnight Blue (RAL 5004) with ivory head and seat tube panels\u003c\/span\u003e\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cstrong\u003ePeregrine Tech and FAQ\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe EBB set screws should be torqued to a maximum of 6Nm or it may deform the shell and insert. The EBB should be covered with a thin coat of grease and maintained periodically by removing, cleaning and re-greasing the insert and bolts. \u003c\/li\u003e\n\u003cli\u003eThe seat binder bolt should be torqued to 8-10Nm. If this is insufficient to prevent seat post slippage please contact us. Some frames were shipped with an incorrect spec bolt which bottoms out
#ProductTemplate--template--15326745395426__main { background: #ffffff; }
.shop-pay-terms { --payment-terms-background-color: #ffffff }before the seat post is fully tight. Please contact us for a replacement if this is the case. \u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003eThe derailleur hanger is designed to only be loosely held by the mounting bolt. The hanger is tightened to the frame by tightening the thru axle so that it is clamped and supported properly in the dropout and not by the hanger retaining bolt. Many thru axle frames have a similar floating axle retention nut mechanism. \u003c\/span\u003e\u003c\/li\u003e\n\u003cli\u003e\u003cspan\u003eThe frame and fork are fully tested and compliant with ISO standards for touring bicycles. Used as intended, it is warranted against defect for five years for the original owner. The frameset is not intended for technical off road riding or jumping.\u003c\/span\u003e\u003c\/li\u003e\n\u003c\/ul\u003e"};
window._RestockRocketConfig.variantsInventoryPolicy = {43854872150242 : "deny",43854872183010 : "deny",43854872215778 : "deny",43854872248546 : "deny",};
window._RestockRocketConfig.variantsInventoryQuantity = {43854872150242 : parseInt("0"),43854872183010 : parseInt("0"),43854872215778 : parseInt("0"),43854872248546 : parseInt("0"),};
window._RestockRocketConfig.variantsPreorderCount = {43854872150242 : parseInt(""),43854872183010 : parseInt(""),43854872215778 : parseInt(""),43854872248546 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderCountForMarket = {43854872150242 : null,43854872183010 : null,43854872215778 : null,43854872248546 : null,};
window._RestockRocketConfig.variantsPreorderMaxCount = {43854872150242 : parseInt(""),43854872183010 : parseInt(""),43854872215778 : parseInt(""),43854872248546 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderMaxCountForMarket = {43854872150242 : null,43854872183010 : null,43854872215778 : null,43854872248546 : null,};
window._RestockRocketConfig.variantsShippingText = {43854872150242 : "",43854872183010 : "",43854872215778 : "",43854872248546 : "",};
window._RestockRocketConfig.variantsShippingTBook a Service
extForMarket = {43854872150242 : null,43854872183010 : null,43854872215778 : null,43854872248546 : null,};
window._RestockRocketConfig.selected_variant_id = 43854872150242;
window._RestockRocketConfig.selected_variant_available = window._RestockRocketConfig.product.variants.find(function(variant) { return variant.id == window._RestockRocketConfig.selected_variant_id }).available;window._RestockRocketConfig.scriptUrlProduct = 'https://cdn.shopify.com/extensions/019af0d1-c518-7a22-bdbf-9ceff49063ad/restockrocket-1-402/assets/restockrocket-product.js'
window._RestockRocketConfig.scriptUrlCollection = 'https://cdn.shopify.com/extensions/019af0d1-c518-7a22-bdbf-9ceff49063ad/restockrocket-1-402/assets/restockrocket-collection.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
window._RestockRocketConfig.host = 'https://app.restockrocket.io'
const SETTINGS_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds
function checkSettingsExpiry(settings) {
try {
if (!settings || !settings.updated_at) {
console.debug('STOQ - Invalid settings data structure');
return null;
}
if (!settings.cache) {
console.debug('STOQ - settings caching disabled');
return null;
}
// Check if translations are enabled but missing from cache
// This handles the backfill period where DB has translations but metafield doesn't
if (settings.multi_language_enabled) {
if (!settings.translations) {
// Translations enabled but no translation data in metafield
// Metafield hasn't been backfilled yet - force refresh
console.debug('STOQ - multi-language enabled but no translation data in cache, fetching fresh');
return null;
}
// Translations object exists in metafield - cache is valid
// If current locale isn't translated, applyTranslations will gracefully use def
INFORMATION
ault locale from base fields
if (window._RestockRocketConfig.normalizedLocale &&
!Object.prototype.hasOwnProperty.call(settings.translations, window._RestockRocketConfig.normalizedLocale)) {
console.debug('STOQ - locale not explicitly translated, will use default language from cache');
}
// Don't return null - continue using cache even for untranslated locales
}
const updatedAt = new Date(settings.updated_at);
if (isNaN(updatedAt.getTime())) {
console.debug('STOQ - Invalid updated_at date format in settings');
return null;
}
const age = Date.now() - updatedAt.getTime();
if (age
- <
SETTINGS_CACHE_DURATION) {
console.debug('STOQ - settings changed recently, skipping cache');
return null;
}
return settings;
} catch (error) {
console.debug('STOQ - Error checking settings cache:', error);
return null;
}
}
function createRestockRocketContainer() {
const restockRocketContainer = document.createElement('div');
restockRocketContainer.id = 'restock-rocket';
document.body.appendChild(restockRocketContainer);
}
function createRestockRocketScript(scriptUrl) {
const restockRocketScriptElement = document.createElement('script');
restockRocketScriptElement.setAttribute('defer', 'defer');
restockRocketScriptElement.src = scriptUrl;
document.body.appendChild(restockRocketScriptElement);
}
createRestockRocketContainer()
console.debug('STOQ - extension activated')
function applyTranslations(settings) {
try {
// Skip translation logic entirely if multi-language is not enabled
if (!settings || !settings.multi_language_enabled) {
return settings;
}
if (!settings.translations) {
console.debug('STOQ - No translations found, skipping translation');
return settings;
}
const normalizedLocale = window._RestockRocketConfig.normalizedLocale;
const translations = settings.translatTrack Your Service
ions;
if (!normalizedLocale) {
// No matching locale has translations; drop payload to save memory
console.debug('STOQ - No matching locale for translations. Available:', Object.keys(translations || {}));
delete settings.translations;
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;
}
}
// First try to get settings from metafields with expiry check
const cachedSettings = window._RestockRocketConfig.cachedSettings;
const validCachedSettings = cachedSettings ? checkSettingsExpiry(cachedSettings) : null;
if (validCachedSettings) {
console.debug('STOQ - using cached settings');
initializeScripts(validCachedSettings);
} else {
console.debug('STOQ - fetching fresh settings');
const headers = {
'X-Shopify-Shop-Domain': window._RestockRocketConfig.shop || window.Shopify.shop,
'ngrok-skip-browser-warning': 'skip'
};
if (window.Shopify?.theme?.role === 'main') {
headers['X-Shopify-Theme-Schema-Name'] = window.Shopify.theme.schema_name;
headers['X-Shopify-Theme-Schema-Version'] = window.Shopify.theme.schema_version;
headers['X-Shopify-Theme-Store-Id'] = window.Shopify.theme.theme_store_id;
}
fetch(
`${window._RestockRocketConfig.host}/api/v1
/setting.json?translation_locale=${window._RestockRocketConfig.normalizedLocale}`,
{ headers }
)
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function(settings) {
initializeScripts(settings);
})
.catch(function(error) {
// If request failed and we have cached settings (even if expired), use them as fallback
if (cachedSettings) {
console.debug('STOQ - using expired cached settings as fallback');
initializeScripts(cachedSettings);
} else {
console.error('STOQ - failed to load settings:', error);
}
})
.catch(function(e) {
console.error(e)
})
}
function initializeScripts(settings) {
settings = applyTranslations(settings);
window._RestockRocketConfig.settings = settings;
console.debug(`STOQ - settings configured for ${window._RestockRocketConfig.pageType}`);
if(settings.enable_app) {
const hijackIntegration = window._RestockRocketConfig.integrations.find(function(integration) {
return integration.type === 'hijack' && integration.enabled && integration.page_types.includes(window._RestockRocketConfig.pageType);
})
if(window._RestockRocketConfig.pageType === 'collection' && (settings.show_button_on_collection || settings.preorder_collection_enabled)) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(window._RestockRocketConfig.pageType === 'index' && (settings.show_button_on_index || settings.preorder_index_enabled)) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(window._RestockRocketConfig.pageType === 'search' && (settings.show_button_on_search || settings.preorder_search_enabled)) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(window._RestockRocketConfig.pageType === 'page' && (settings.show_button_on_
page || settings.preorder_page_enabled)) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(window._RestockRocketConfig.pageType === 'product') {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlProduct);
} else if(hijackIntegration) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else {
console.debug(`STOQ - no scripts enabled for ${window._RestockRocketConfig.pageType}`);
}
// Check and update cart selling plans after scripts are loaded
if (settings.preorder_enabled) {
updateCartSellingPlans();
}
// Dispatch custom event when app is loaded
const appLoadedEvent = new CustomEvent('stoq:loaded', {
detail: {
pageType: window._RestockRocketConfig.pageType,
enabled: settings.enable_app,
settings: settings
}
});
console.debug('STOQ - dispatching app loaded event');
window.dis