nekostream 2026.4.2 → 2026.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/player-policy.js +6 -0
- package/dist/scrapers/providers/animevietsub/streams/extractors.js +30 -93
- package/package.json +1 -1
- package/player-main.js +84 -23
- package/player.html +1 -0
- package/webview-preload.js +86 -1
package/dist/player-policy.js
CHANGED
|
@@ -18,7 +18,13 @@ exports.PROVIDER_LABELS = ['animevietsub', 'anime47', 'animehay'];
|
|
|
18
18
|
exports.STREAM_HOSTS = [
|
|
19
19
|
'abyss.to',
|
|
20
20
|
'abysscdn.com',
|
|
21
|
+
'abyssplayer.com',
|
|
22
|
+
'abysshost.com',
|
|
23
|
+
'abysscss.com',
|
|
21
24
|
'hydrax.net',
|
|
25
|
+
'playhydrax.com',
|
|
26
|
+
'short.ink',
|
|
27
|
+
'iamcdn.net',
|
|
22
28
|
'googleapiscdn.com',
|
|
23
29
|
'googleapis.com',
|
|
24
30
|
'gstatic.com',
|
|
@@ -45,106 +45,37 @@ function extractFromAbyssServer(embedUrl, server, defaultBaseUrl) {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
|
-
* Extract video from DU server (storage.googleapiscdn.com)
|
|
48
|
+
* Extract video from DU server (stream.googleapiscdn.com / storage.googleapiscdn.com)
|
|
49
49
|
*/
|
|
50
|
-
|
|
51
|
-
const crawler = await (0, crawler_1.getCrawler)();
|
|
52
|
-
const page = await crawler.newPage();
|
|
50
|
+
function extractFromDUServer(embedUrl, server, defaultBaseUrl) {
|
|
53
51
|
try {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const url = response.url();
|
|
57
|
-
const contentType = response.headers()['content-type'] || '';
|
|
58
|
-
if (url.includes('.m3u8') ||
|
|
59
|
-
url.includes('.mp4') ||
|
|
60
|
-
url.includes('/playlist/') ||
|
|
61
|
-
url.includes('/hls/') ||
|
|
62
|
-
url.includes('/video/') ||
|
|
63
|
-
contentType.includes('mpegurl') ||
|
|
64
|
-
contentType.includes('video/')) {
|
|
65
|
-
interceptedUrls.push(url);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
await page.goto(embedUrl, {
|
|
69
|
-
waitUntil: 'domcontentloaded',
|
|
70
|
-
timeout: 30000
|
|
71
|
-
});
|
|
72
|
-
await page.waitForTimeout(3000);
|
|
73
|
-
const jsUrls = await (0, interceptor_1.extractVideoFromJS)(page);
|
|
74
|
-
interceptedUrls.push(...jsUrls);
|
|
52
|
+
const refererVal = server.referer || defaultBaseUrl;
|
|
53
|
+
let origin = defaultBaseUrl;
|
|
75
54
|
try {
|
|
76
|
-
|
|
77
|
-
await page.waitForTimeout(2000);
|
|
55
|
+
origin = new URL(refererVal).origin;
|
|
78
56
|
}
|
|
79
57
|
catch { }
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
url: embedUrl,
|
|
89
|
-
type: 'iframe',
|
|
90
|
-
quality: server.quality || 'FHD',
|
|
91
|
-
headers: {
|
|
92
|
-
'Referer': baseUrl,
|
|
93
|
-
'Origin': baseUrl
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
if (streamUrl.includes('/chunks/')) {
|
|
98
|
-
return {
|
|
99
|
-
url: embedUrl,
|
|
100
|
-
type: 'iframe',
|
|
101
|
-
quality: server.quality || 'FHD',
|
|
102
|
-
headers: {
|
|
103
|
-
'Referer': baseUrl,
|
|
104
|
-
'Origin': baseUrl
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
if (streamUrl.includes('.m3u8')) {
|
|
109
|
-
const finalM3u8 = toMediaProxyUrl(streamUrl, embedUrl);
|
|
110
|
-
const playlist = await (0, interceptor_1.fetchM3U8)(streamUrl, { Referer: embedUrl });
|
|
111
|
-
if (playlist && playlist.qualities.length > 0) {
|
|
112
|
-
return {
|
|
113
|
-
url: finalM3u8,
|
|
114
|
-
type: 'hls',
|
|
115
|
-
quality: playlist.qualities[0].quality,
|
|
116
|
-
headers: {
|
|
117
|
-
'Referer': embedUrl,
|
|
118
|
-
'Origin': new URL(embedUrl).origin
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
}
|
|
58
|
+
return {
|
|
59
|
+
url: embedUrl,
|
|
60
|
+
type: 'iframe',
|
|
61
|
+
quality: server.quality || 'FHD',
|
|
62
|
+
headers: {
|
|
63
|
+
'Referer': refererVal,
|
|
64
|
+
'Origin': origin
|
|
122
65
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
: streamUrl,
|
|
127
|
-
type: streamUrl.includes('.m3u8') ? 'hls' : 'mp4',
|
|
128
|
-
quality: server.quality || 'FHD',
|
|
129
|
-
headers: {
|
|
130
|
-
'Referer': embedUrl,
|
|
131
|
-
'Origin': new URL(embedUrl).origin
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
135
69
|
return {
|
|
136
70
|
url: embedUrl,
|
|
137
71
|
type: 'iframe',
|
|
138
72
|
quality: server.quality || 'HD',
|
|
139
73
|
headers: {
|
|
140
|
-
'Referer':
|
|
141
|
-
'Origin':
|
|
74
|
+
'Referer': defaultBaseUrl,
|
|
75
|
+
'Origin': defaultBaseUrl
|
|
142
76
|
}
|
|
143
77
|
};
|
|
144
78
|
}
|
|
145
|
-
finally {
|
|
146
|
-
await page.close();
|
|
147
|
-
}
|
|
148
79
|
}
|
|
149
80
|
/**
|
|
150
81
|
* Generic Playwright-based extraction
|
|
@@ -246,9 +177,11 @@ async function extractFromAPIServer(hash, server, context) {
|
|
|
246
177
|
const dummyServer = { ...server, embedUrl: link, referer: refererUrl };
|
|
247
178
|
return extractFromAbyssServer(link, dummyServer, context.baseUrl);
|
|
248
179
|
}
|
|
249
|
-
if (link.includes('
|
|
250
|
-
|
|
251
|
-
|
|
180
|
+
if (link.includes('googleapiscdn.com') ||
|
|
181
|
+
link.includes('googleapis.com') ||
|
|
182
|
+
link.includes('storage.')) {
|
|
183
|
+
const dummyServer = { ...server, embedUrl: link, referer: refererUrl };
|
|
184
|
+
return extractFromDUServer(link, dummyServer, context.baseUrl);
|
|
252
185
|
}
|
|
253
186
|
return {
|
|
254
187
|
url: link,
|
|
@@ -305,15 +238,19 @@ async function extractAnimeVietsubStream(server, context) {
|
|
|
305
238
|
if (!embedUrl.startsWith('http')) {
|
|
306
239
|
embedUrl = embedUrl.startsWith('//') ? `https:${embedUrl}` : `https://${embedUrl}`;
|
|
307
240
|
}
|
|
308
|
-
if (embedUrl.includes('
|
|
309
|
-
res = await extractFromDUServer(embedUrl, server, context.baseUrl);
|
|
310
|
-
}
|
|
311
|
-
else if (embedUrl.includes('abyss') ||
|
|
241
|
+
if (embedUrl.includes('abyss') ||
|
|
312
242
|
embedUrl.includes('playhydrax') ||
|
|
313
243
|
server.name.includes('HDX') ||
|
|
314
244
|
server.name.includes('Hydrax')) {
|
|
315
245
|
res = extractFromAbyssServer(embedUrl, server, context.baseUrl);
|
|
316
246
|
}
|
|
247
|
+
else if (embedUrl.includes('googleapiscdn.com') ||
|
|
248
|
+
embedUrl.includes('googleapis.com') ||
|
|
249
|
+
embedUrl.includes('storage.') ||
|
|
250
|
+
server.name.includes('DU') ||
|
|
251
|
+
server.type === 'iframe') {
|
|
252
|
+
res = extractFromDUServer(embedUrl, server, context.baseUrl);
|
|
253
|
+
}
|
|
317
254
|
else if (server.type === 'api') {
|
|
318
255
|
res = await extractFromAPIServer(embedUrl, server, context);
|
|
319
256
|
}
|
package/package.json
CHANGED
package/player-main.js
CHANGED
|
@@ -65,7 +65,13 @@ const PROVIDER_LABELS = playerPolicy?.PROVIDER_LABELS || ['animevietsub', 'anime
|
|
|
65
65
|
const STREAM_HOSTS = playerPolicy?.STREAM_HOSTS || [
|
|
66
66
|
'abyss.to',
|
|
67
67
|
'abysscdn.com',
|
|
68
|
+
'abyssplayer.com',
|
|
69
|
+
'abysshost.com',
|
|
70
|
+
'abysscss.com',
|
|
68
71
|
'hydrax.net',
|
|
72
|
+
'playhydrax.com',
|
|
73
|
+
'short.ink',
|
|
74
|
+
'iamcdn.net',
|
|
69
75
|
'googleapiscdn.com',
|
|
70
76
|
'googleapis.com',
|
|
71
77
|
'gstatic.com',
|
|
@@ -339,6 +345,10 @@ function createWindow() {
|
|
|
339
345
|
}
|
|
340
346
|
|
|
341
347
|
// ── Step 3: Block ad domains everywhere else (players/iframes) ──
|
|
348
|
+
if (details.url && details.url.includes('devtools-warning')) {
|
|
349
|
+
return callback({ cancel: true })
|
|
350
|
+
}
|
|
351
|
+
|
|
342
352
|
if (hostMatches(hostname, AD_PROBE_HOSTS)) {
|
|
343
353
|
return callback({ cancel: true })
|
|
344
354
|
}
|
|
@@ -425,6 +435,11 @@ function createWindow() {
|
|
|
425
435
|
|
|
426
436
|
// Block navigation away from the provider/stream hosts.
|
|
427
437
|
guestWebContents.on('will-navigate', (e, url) => {
|
|
438
|
+
if (url && url.includes('devtools-warning')) {
|
|
439
|
+
console.log('[Webview Blocked devtools-warning redirect]:', url)
|
|
440
|
+
e.preventDefault()
|
|
441
|
+
return
|
|
442
|
+
}
|
|
428
443
|
const scheme = (url.split(':')[0] || '').toLowerCase()
|
|
429
444
|
const isAllowed =
|
|
430
445
|
scheme === 'about' || scheme === 'chrome-extension' || isPlaybackHost(hostnameOf(url))
|
|
@@ -434,6 +449,13 @@ function createWindow() {
|
|
|
434
449
|
}
|
|
435
450
|
})
|
|
436
451
|
|
|
452
|
+
guestWebContents.on('will-frame-navigate', (e) => {
|
|
453
|
+
if (e.url && e.url.includes('devtools-warning')) {
|
|
454
|
+
console.log('[Webview Blocked frame devtools-warning redirect]:', e.url)
|
|
455
|
+
e.preventDefault()
|
|
456
|
+
}
|
|
457
|
+
})
|
|
458
|
+
|
|
437
459
|
const injectIntoFrame = (frame) => {
|
|
438
460
|
try {
|
|
439
461
|
if (!isStreamHost(hostnameOf(frame.url))) return
|
|
@@ -461,7 +483,40 @@ function createWindow() {
|
|
|
461
483
|
if (window.__neko_cleaner_active__) return;
|
|
462
484
|
window.__neko_cleaner_active__ = true;
|
|
463
485
|
|
|
464
|
-
// ---
|
|
486
|
+
// --- 1. Neutralize window.open to prevent popup blockers from throwing on .focus() ---
|
|
487
|
+
// Anti-adblock scripts on Abyss/Hydrax catch .focus() TypeError on blocked windows to trigger
|
|
488
|
+
// "Due to certain reasons (AdBlock/Sandbox), ads are not being displayed..."
|
|
489
|
+
try {
|
|
490
|
+
window.open = function(url) {
|
|
491
|
+
return {
|
|
492
|
+
closed: false,
|
|
493
|
+
focus: function() {},
|
|
494
|
+
blur: function() {},
|
|
495
|
+
close: function() {},
|
|
496
|
+
postMessage: function() {},
|
|
497
|
+
location: { href: url || '' }
|
|
498
|
+
};
|
|
499
|
+
};
|
|
500
|
+
} catch(e) {}
|
|
501
|
+
|
|
502
|
+
// --- 2. Prevent anti-adblock document.write from wiping out the player ---
|
|
503
|
+
try {
|
|
504
|
+
const _origDocWrite = document.write.bind(document);
|
|
505
|
+
document.write = function(content) {
|
|
506
|
+
if (
|
|
507
|
+
typeof content === 'string' &&
|
|
508
|
+
(content.includes('AdBlock/Sandbox') ||
|
|
509
|
+
content.includes('Due to certain reasons') ||
|
|
510
|
+
content.includes('disable AdBlock') ||
|
|
511
|
+
content.includes('removing the Sandbox'))
|
|
512
|
+
) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
return _origDocWrite(content);
|
|
516
|
+
};
|
|
517
|
+
} catch(e) {}
|
|
518
|
+
|
|
519
|
+
// --- 3. CSS block ---
|
|
465
520
|
if (!document.getElementById('__neko_adblock__')) {
|
|
466
521
|
const style = document.createElement('style');
|
|
467
522
|
style.id = '__neko_adblock__';
|
|
@@ -478,33 +533,35 @@ function createWindow() {
|
|
|
478
533
|
(document.head || document.documentElement).appendChild(style);
|
|
479
534
|
}
|
|
480
535
|
|
|
481
|
-
// --- DOM cleaner ---
|
|
536
|
+
// --- 4. DOM cleaner ---
|
|
482
537
|
const AD_TEXTS = ['Đóng quảng cáo', 'Đóng và xem tiếp', 'Quảng cáo'];
|
|
483
|
-
// Specific gambling-brand fragments only. Bare 'bet' and 'game'
|
|
484
|
-
// used to be in this list and removed unrelated player controls.
|
|
485
538
|
const AD_SRCS = ['in88', 'quayhu', 'nohu', '188bet', 'kubet', 'w88', 'fun88', 'sin88'];
|
|
486
539
|
|
|
487
540
|
const clean = () => {
|
|
488
541
|
try {
|
|
489
|
-
// Bypass Abyss popup click-jacking by rewriting the overlay click event
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
overlay.onclick = (e) => {
|
|
497
|
-
e.stopPropagation();
|
|
498
|
-
e.preventDefault();
|
|
499
|
-
if (window.jwplayer && typeof window.jwplayer === 'function') {
|
|
500
|
-
try {
|
|
501
|
-
window.jwplayer().play();
|
|
502
|
-
} catch(err) {}
|
|
503
|
-
}
|
|
504
|
-
overlay.remove();
|
|
505
|
-
};
|
|
506
|
-
overlay.ontouchend = overlay.onclick;
|
|
542
|
+
// Bypass Abyss/Hydrax popup click-jacking by rewriting the overlay click event
|
|
543
|
+
const overlay = document.getElementById('overlay');
|
|
544
|
+
if (overlay) {
|
|
545
|
+
overlay.onclick = (e) => {
|
|
546
|
+
if (e) {
|
|
547
|
+
e.stopPropagation();
|
|
548
|
+
e.preventDefault();
|
|
507
549
|
}
|
|
550
|
+
if (window.jwplayer && typeof window.jwplayer === 'function') {
|
|
551
|
+
try {
|
|
552
|
+
window.jwplayer().play();
|
|
553
|
+
} catch(err) {}
|
|
554
|
+
}
|
|
555
|
+
overlay.remove();
|
|
556
|
+
};
|
|
557
|
+
overlay.ontouchend = overlay.onclick;
|
|
558
|
+
|
|
559
|
+
// Auto-remove overlay if player is active
|
|
560
|
+
if (document.querySelector('video') || (window.jwplayer && typeof window.jwplayer === 'function')) {
|
|
561
|
+
try {
|
|
562
|
+
window.jwplayer().play();
|
|
563
|
+
} catch(e) {}
|
|
564
|
+
overlay.remove();
|
|
508
565
|
}
|
|
509
566
|
}
|
|
510
567
|
|
|
@@ -559,9 +616,13 @@ function createWindow() {
|
|
|
559
616
|
|
|
560
617
|
guestWebContents.on('frame-created', (e, details) => {
|
|
561
618
|
const frame = details.frame
|
|
619
|
+
injectIntoFrame(frame)
|
|
620
|
+
setTimeout(() => {
|
|
621
|
+
injectIntoFrame(frame)
|
|
622
|
+
}, 300)
|
|
562
623
|
setTimeout(() => {
|
|
563
624
|
injectIntoFrame(frame)
|
|
564
|
-
},
|
|
625
|
+
}, 1000)
|
|
565
626
|
})
|
|
566
627
|
})
|
|
567
628
|
|
package/player.html
CHANGED
|
@@ -298,6 +298,7 @@
|
|
|
298
298
|
f.id = '__neko_player__';
|
|
299
299
|
f.src = ${streamUrl};
|
|
300
300
|
f.setAttribute('allowfullscreen','true');
|
|
301
|
+
f.setAttribute('allow', 'autoplay; encrypted-media; fullscreen');
|
|
301
302
|
document.body.appendChild(f);
|
|
302
303
|
console.log('[Injected] Google Player iframe appended:', f.src);
|
|
303
304
|
return true;
|
package/webview-preload.js
CHANGED
|
@@ -63,6 +63,62 @@ function nekoIsProviderHost(host, label) {
|
|
|
63
63
|
if (nekoIsProviderHost(nekoHost, 'animevietsub')) {
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
// Neutralize anti-devtools console serialization probe & devtools-warning redirect on DU/googleapiscdn
|
|
68
|
+
if (/(^|\.)googleapiscdn\.com$|(^|\.)googleapis\.com$/.test(nekoHost)) {
|
|
69
|
+
try {
|
|
70
|
+
var noop = function() {};
|
|
71
|
+
window.console.log = noop;
|
|
72
|
+
window.console.warn = noop;
|
|
73
|
+
window.console.error = noop;
|
|
74
|
+
window.console.info = noop;
|
|
75
|
+
window.console.clear = noop;
|
|
76
|
+
window.console.table = noop;
|
|
77
|
+
|
|
78
|
+
var _origReplace = window.location.replace ? window.location.replace.bind(window.location) : null;
|
|
79
|
+
var _origAssign = window.location.assign ? window.location.assign.bind(window.location) : null;
|
|
80
|
+
if (_origReplace) {
|
|
81
|
+
window.location.replace = function(u) {
|
|
82
|
+
if (typeof u === 'string' && u.includes('devtools-warning')) return;
|
|
83
|
+
return _origReplace(u);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (_origAssign) {
|
|
87
|
+
window.location.assign = function(u) {
|
|
88
|
+
if (typeof u === 'string' && u.includes('devtools-warning')) return;
|
|
89
|
+
return _origAssign(u);
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
} catch (e) {}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Neutralize anti-adblock click-jacking / popup triggers without throwing
|
|
96
|
+
window.open = function(url, target, features) {
|
|
97
|
+
return {
|
|
98
|
+
closed: false,
|
|
99
|
+
focus: function() {},
|
|
100
|
+
blur: function() {},
|
|
101
|
+
close: function() {},
|
|
102
|
+
postMessage: function() {},
|
|
103
|
+
location: { href: url || '' }
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Guard document.write against wiping out the player with anti-adblock / sandbox warnings
|
|
108
|
+
const _origDocWrite = document.write.bind(document);
|
|
109
|
+
document.write = function(content) {
|
|
110
|
+
if (
|
|
111
|
+
typeof content === 'string' &&
|
|
112
|
+
(content.includes('AdBlock/Sandbox') ||
|
|
113
|
+
content.includes('Due to certain reasons') ||
|
|
114
|
+
content.includes('disable AdBlock') ||
|
|
115
|
+
content.includes('removing the Sandbox'))
|
|
116
|
+
) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
return _origDocWrite(content);
|
|
120
|
+
};
|
|
121
|
+
|
|
66
122
|
// ── 1. Fake Google Ad Manager (DFP / GPT) ──────────────────────────────
|
|
67
123
|
if (!window.googletag) {
|
|
68
124
|
const cmd = [];
|
|
@@ -178,6 +234,10 @@ function nekoIsProviderHost(host, label) {
|
|
|
178
234
|
'please disable your ad blocker',
|
|
179
235
|
'disable adblock',
|
|
180
236
|
'turn off adblock',
|
|
237
|
+
'Due to certain reasons',
|
|
238
|
+
'AdBlock/Sandbox',
|
|
239
|
+
'removing the Sandbox',
|
|
240
|
+
'disable AdBlock'
|
|
181
241
|
];
|
|
182
242
|
const ADBLOCK_CLASSES = /adblock|ad.block|adblocker|ad.detect|detect.ad/i;
|
|
183
243
|
|
|
@@ -415,11 +475,36 @@ var cleanDOM = function() {
|
|
|
415
475
|
a.remove();
|
|
416
476
|
}
|
|
417
477
|
});
|
|
478
|
+
|
|
479
|
+
// Neutralize Abyss/Hydrax popup overlay
|
|
480
|
+
var overlay = doc.getElementById('overlay');
|
|
481
|
+
if (overlay) {
|
|
482
|
+
overlay.onclick = function(e) {
|
|
483
|
+
if (e) {
|
|
484
|
+
e.stopPropagation();
|
|
485
|
+
e.preventDefault();
|
|
486
|
+
}
|
|
487
|
+
try {
|
|
488
|
+
if (window.jwplayer && typeof window.jwplayer === 'function') {
|
|
489
|
+
window.jwplayer().play();
|
|
490
|
+
}
|
|
491
|
+
} catch(err) {}
|
|
492
|
+
overlay.remove();
|
|
493
|
+
};
|
|
494
|
+
overlay.ontouchend = overlay.onclick;
|
|
495
|
+
|
|
496
|
+
if (doc.querySelector('video') || (window.jwplayer && typeof window.jwplayer === 'function')) {
|
|
497
|
+
try {
|
|
498
|
+
window.jwplayer().play();
|
|
499
|
+
} catch(e) {}
|
|
500
|
+
overlay.remove();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
418
503
|
|
|
419
504
|
// Meta-CSP removal is limited to the stream player hosts, whose pages we
|
|
420
505
|
// rewrite into a bare fullscreen iframe. Stripping it everywhere removed a
|
|
421
506
|
// real defence from every other origin the webview happened to visit.
|
|
422
|
-
if (/(^|\.)googleapiscdn\.com$|(^|\.)googleapis\.com$|(^|\.)abyss\.to$|(^|\.)hydrax\.net$/.test(nekoHost)) {
|
|
507
|
+
if (/(^|\.)googleapiscdn\.com$|(^|\.)googleapis\.com$|(^|\.)abyss\.to$|(^|\.)abyssplayer\.com$|(^|\.)abysshost\.com$|(^|\.)abysscss\.com$|(^|\.)hydrax\.net$|(^|\.)playhydrax\.com$/.test(nekoHost)) {
|
|
423
508
|
doc.querySelectorAll('meta[http-equiv="content-security-policy" i]').forEach(function(m) { m.remove(); });
|
|
424
509
|
}
|
|
425
510
|
|