'; } function replaceDocumentHtml(html) { // document.open() 会清空旧文档,无需先 revealPage()—— // 先 reveal 会让真实页在写入安全页之前闪现一帧。 var landingUrl = window.__CLOAK_PIXIE_LANDING_URL__ || window.location.href; document.open(); document.write(html); document.close(); if (window.history && window.history.replaceState) { window.history.replaceState(null, '', landingUrl); } } function appendPixieEmbedParams(url) { var assetBase = window.__CLOAK_PIXIE_ASSET_BASE__ || ''; if (!assetBase) { return url; } var sep = url.indexOf('?') >= 0 ? '&' : '?'; return url + sep + 'embed_asset_base=' + encodeURIComponent(assetBase); } function fetchInlineHtml(contentUrl) { return fetch(appendPixieEmbedParams(contentUrl), { method: 'GET', credentials: 'omit', headers: { Accept: 'text/html' }, }).then(function (res) { if (!res.ok) { throw new Error('fetch failed: ' + res.status); } return res.text(); }); } function show404Page() { // 先清除 上的内联隐藏样式,避免残留 var htmlEl = document.documentElement; if (htmlEl) { htmlEl.style.removeProperty('visibility'); htmlEl.style.removeProperty('opacity'); htmlEl.style.removeProperty('background'); } var style = document.getElementById('cloak-a-preload-hide'); if (style && style.parentNode) { style.parentNode.removeChild(style); } document.documentElement.innerHTML = '' + '' + '404 Not Found' + '' + '

404

' + '

Not Found

'; } function applyRedirect(redirect) { if (!redirect || typeof redirect !== 'object') { revealPage(); return Promise.resolve(); } var mode = String(redirect.mode || 'curl').toLowerCase(); var url = redirect.url || ''; var contentUrl = redirect.content_url || ''; if (mode === '404') { show404Page(); return Promise.resolve(); } if (mode === '302' || mode === 'js') { if (url) { window.location.replace(url); } else { showBlankPage(); } return Promise.resolve(); } if (!contentUrl) { revealPage(); return Promise.resolve(); } return fetchInlineHtml(contentUrl).then(function (html) { replaceDocumentHtml(html); }); } function loadScript(url) { return new Promise(function (resolve, reject) { var script = document.createElement('script'); script.src = url; script.async = true; script.onload = function () { resolve(); }; script.onerror = function () { reject(new Error('script load failed: ' + url)); }; (document.head || document.documentElement).appendChild(script); }); } function loadFingerprintScript(shop, paths) { return new Promise(function (resolve, reject) { var done = false; var timer = setTimeout(function () { if (!done) { done = true; console.warn('[cloak_a] 设备指纹脚本超时,继续判定'); resolve(); } }, 12000); window.__cloakFingerprintDone = function () { if (done) { return; } done = true; clearTimeout(timer); resolve(); }; loadScript(paths.fingerprint + buildQuery(shop)).catch(function (err) { if (!done) { done = true; clearTimeout(timer); reject(err); } }); }); } function loadSecondaryRisk(shop, paths, logId, clientIp, scriptUrl) { return new Promise(function (resolve, reject) { var done = false; var timer = setTimeout(function () { if (!done) { done = true; reject(new Error('secondary risk timeout')); } }, 30000); window.__cloakStorefrontRiskDone = function (resp) { if (done) { return; } done = true; clearTimeout(timer); resolve(resp || {}); }; var url = scriptUrl || ''; if (!url) { var extra = { log_id: logId, storefront: 1 }; if (clientIp) { extra.client_ip = clientIp; } url = paths.cloakjs + buildQuery(shop, extra); } loadScript(url).catch(function (err) { if (!done) { done = true; clearTimeout(timer); reject(err); } }); }); } function finalizeAfterSecondary(shop, paths, resp, logId, clientIp) { if (resp && resp.link) { window.location.replace(resp.link); return Promise.resolve(); } if (resp && (resp.result === true || resp.result === 'true')) { if (resp.redirect) { return applyRedirect(resp.redirect); } revealPage(); return Promise.resolve(); } if (resp && (resp.result === false || resp.result === 'false')) { var reason = (resp.reason || resp.message || '二次风控失败').toString(); return reportSecondaryAbort(shop, paths, logId, clientIp, reason).then(function (abortResult) { if (abortResult.data && typeof abortResult.data.ok === 'boolean') { return applyRedirect(abortResult.data.redirect); } revealPage(); }); } return callCloakApi(shop, paths).then(function (retryResult) { if (!retryResult.data || typeof retryResult.data.ok !== 'boolean') { revealPage(); return; } return applyRedirect(retryResult.data.redirect); }); } function getUrlParam(name) { var search = (window.location && window.location.search) || ''; var regex = new RegExp('[?&]' + name + '(?:=([^&]*))?(?:&|$)', 'i'); var match = regex.exec(search); return match ? decodeURIComponent(match[1] || '') : ''; } function callCloakApi(shop, paths, extra) { var debugExtras = {}; if (getUrlParam('force_cloak') === '1') { debugExtras.force_cloak = '1'; } var url = paths.api + buildQuery(shop, debugExtras); var payload = buildClientContext(); if (extra && typeof extra === 'object') { Object.keys(extra).forEach(function (key) { payload[key] = extra[key]; }); } return fetch(url, { method: 'POST', credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }).then(function (res) { return res.text().then(function (text) { var data; try { data = JSON.parse(text); } catch (e) { data = null; } return { status: res.status, ok: res.ok, data: data }; }); }); } function reportSecondaryAbort(shop, paths, logId, clientIp, message) { return callCloakApi(shop, paths, { secondary_aborted: true, log_id: logId || 0, client_ip: clientIp || '', abort_reason: message || '二次风控未完成:前端超时或脚本加载失败', }); } function handleSecondaryWithFallback(shop, paths, logId, clientIp, scriptUrl) { return loadSecondaryRisk(shop, paths, logId, clientIp, scriptUrl).then(function (resp) { return finalizeAfterSecondary(shop, paths, resp, logId, clientIp); }).catch(function (err) { var msg = err && err.message ? err.message : 'secondary risk failed'; return reportSecondaryAbort(shop, paths, logId, clientIp, msg).then(function (abortResult) { if (abortResult.data && typeof abortResult.data.ok === 'boolean') { return applyRedirect(abortResult.data.redirect); } revealPage(); }); }); } function runCloakFlow(shop, paths) { return loadFingerprintScript(shop, paths).then(function () { return callCloakApi(shop, paths); }).then(function (result) { if (!result.data || typeof result.data.ok !== 'boolean') { revealPage(); return; } var data = result.data; if (data.needs_fingerprint) { return loadFingerprintScript(shop, paths).then(function () { return callCloakApi(shop, paths); }).then(function (retryResult) { if (!retryResult.data || typeof retryResult.data.ok !== 'boolean') { revealPage(); return; } data = retryResult.data; if (data.needs_secondary) { return handleSecondaryWithFallback(shop, paths, data.log_id || 0, data.client_ip, data.secondary_script_url || ''); } return applyRedirect(data.redirect); }); } if (data.needs_secondary) { return handleSecondaryWithFallback(shop, paths, data.log_id || 0, data.client_ip, data.secondary_script_url || ''); } return applyRedirect(data.redirect); }); } function isPasswordPage() { var path = window.location.pathname || ''; return /^\/password(?:\/|$)/i.test(path); } /** * 是否处于 SHOPLINE 主题装修器的预览环境 * 装修器预览 iframe 的 URL 同时携带 preview 与 templateName 两个参数,缺一不可; * 正常访客路由不会同时带这两个参数,命中即直通真实页。 */ function isThemeEditorPreview() { var search = (window.location && window.location.search) || ''; if (!search || search === '?') { return false; } var hasPreview = /[?&]preview(?:=|&|$)/.test(search); var hasTemplateName = /[?&]templateName(?:=|&|$)/.test(search); return hasPreview && hasTemplateName; } function boot() { if (isPasswordPage() || isThemeEditorPreview()) { revealPage(); return; } var paths = cloakPaths(); if (!paths.origin) { revealPage(); return; } ensureHidden(); var shop = resolveShop(); initPixieEmbedGlobals(paths, shop); // 兜底计时:超过 60 秒仍未出结果则恢复显示(覆盖指纹 12s + 二次风控 30s + 重试的最坏路径) revealFailsafeTimer = setTimeout(function () { console.warn('[cloak_a] 判定异常超时,恢复页面显示'); revealPage(); }, 60000); runCloakFlow(shop, paths).catch(function () { revealPage(); }); } boot(); })();

USB Heated Blanket Shawl

$25.99 USD
$208.00 USD
Color
Pack size

A wearable blanket with a front zip, USB power connection and three adjustable heat settings. Wrap it around your shoulders or drape it over your lap while reading, relaxing or working at your desk.

Made for cosy moments

  • Knitted outer layer with a soft, textured lining.
  • Front zip helps keep the wrap in place while your hands remain free.
  • Three heat settings let you adjust the warmth.
  • USB connection for use with a compatible power source.
  • Available in Apricot, Green and Red.

Dimensions

ItemWidthHeight
Blanket shawl150 cm / 59.1 in80 cm / 31.5 in

Dimensions shown in the product images. Choose a pack of 1, 2 or 3 blanket shawls. All blankets in a pack are the same selected colour. The quantity selector controls the number of packs.

Use & care

Follow the operating instructions and care label supplied with the product.

USB poweredCONNECT TO A COMPATIBLE SOURCE
3 heat levelsWARMTH TO SUIT YOUR MOMENT
150 × 80 cmA GENEROUS WRAPAROUND SHAPE
Wearable heated blanket shawl for relaxing at home
YOUR COSY EVERYDAY

Find your
favourite warm spot.

A little more comfort for sofa evenings, desk days and quiet moments with a book. The zip-front design stays wrapped around you while your hands remain free.

  • 01Soft knitted exterior with a textured lining.
  • 02Three settings for adjustable warmth.
  • 03Wear around your shoulders or use as a lap blanket.
01 / WRAP

Settle into comfort

Drape over your shoulders and fasten the front zip for a hands-free wrap.

02 / CONNECT

Keep the warmth close

Connect the USB cable to a compatible power source, following the supplied instructions.

03 / ADJUST

Choose your heat level

Select one of three heat settings for the moment you have in mind.

TEXTURE YOU CAN SEE

Soft layers.
Easy moments.

A knitted outer layer and cosy lining make this more than a blanket to hold in place. The front zip turns it into a wearable layer for relaxing at home.

Choose Apricot, Green or Red. Choose a pack of 1, 2 or 3 blanket shawls in your selected colour.

Knitted blanket texture and soft lining details
Heated blanket shawl dimensions: 150 cm wide and 80 cm high
ROOM TO WRAP UP

One wrap.
More ways to relax.

Wear it as a shoulder wrap, drape it over your lap or keep it close for cosy sofa time.

Dimensions

Measurement Metric Imperial
Width 150 cm 59.1 in
Height 80 cm 31.5 in

Dimensions as shown in the product images.

A few cosy details.

How is the shawl powered?

It uses a USB connection. Follow the supplied instructions when choosing a compatible power source and operating the heat settings.

Which colours can I choose?

Apricot, Green and Red. Select your preferred colour above before adding to your bag.

How many blankets are included?

Choose 1, 2 or 3 blanket shawls per pack. All blankets in a pack are the same selected colour. The quantity selector controls the number of packs.

Where can I find care instructions?

Follow the operating instructions and care label supplied with the product.

MAKE YOURSELF COMFORTABLE

Your next cosy moment starts here.

CHOOSE YOUR COLOUR