@mlikiowa/nanaeo 1.0.1702966759079 → 1.0.1702967739786

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. package/2022/08/04/NewBlog/index.html +3473 -0
  2. package/2022/08/13/GaussWave/index.html +3407 -0
  3. package/about/index.html +3236 -0
  4. package/archives/2022/08/index.html +3411 -0
  5. package/archives/2022/index.html +3411 -0
  6. package/archives/index.html +3308 -0
  7. package/asset/Sotheby.ttf +0 -0
  8. package/asset/backimg.png +0 -0
  9. package/atom.xml +171 -0
  10. package/categories/DevLog/index.html +3351 -0
  11. package/categories/SiteLog/index.html +3351 -0
  12. package/categories/index.html +3174 -0
  13. package/category/devlog/atom.xml +58 -0
  14. package/category/devlog/feed.json +19 -0
  15. package/category/devlog/rss.xml +62 -0
  16. package/category/sitelog/atom.xml +125 -0
  17. package/category/sitelog/feed.json +20 -0
  18. package/category/sitelog/rss.xml +129 -0
  19. package/content.json +1 -0
  20. package/css/Readme.html +9 -0
  21. package/css/first.css +1504 -0
  22. package/css/style.css +7106 -0
  23. package/favicon.ico +0 -0
  24. package/feed.json +31 -0
  25. package/friends/index.html +3661 -0
  26. package/index.html +3421 -0
  27. package/js/app.js +1223 -0
  28. package/js/plugins/aplayer.js +186 -0
  29. package/js/plugins/parallax.js +191 -0
  30. package/js/plugins/rightMenu.js +577 -0
  31. package/js/plugins/rightMenus.js +618 -0
  32. package/js/plugins/tags/contributors.js +92 -0
  33. package/js/plugins/tags/friends.js +93 -0
  34. package/js/plugins/tags/sites.js +96 -0
  35. package/js/search/hexo.js +192 -0
  36. package/package.json +1 -1
  37. package/rss.xml +175 -0
  38. package/tag/devlog/atom.xml +58 -0
  39. package/tag/devlog/feed.json +19 -0
  40. package/tag/devlog/rss.xml +62 -0
  41. package/tag/gauss/atom.xml +58 -0
  42. package/tag/gauss/feed.json +19 -0
  43. package/tag/gauss/rss.xml +62 -0
  44. package/tag/hexo/atom.xml +125 -0
  45. package/tag/hexo/feed.json +20 -0
  46. package/tag/hexo/rss.xml +129 -0
  47. package/tag/hexothemes/atom.xml +125 -0
  48. package/tag/hexothemes/feed.json +20 -0
  49. package/tag/hexothemes/rss.xml +129 -0
  50. package/tag/sitelog/atom.xml +125 -0
  51. package/tag/sitelog/feed.json +20 -0
  52. package/tag/sitelog/rss.xml +129 -0
  53. package/tags/DevLog/index.html +3351 -0
  54. package/tags/Gauss/index.html +3351 -0
  55. package/tags/Hexo/index.html +3351 -0
  56. package/tags/HexoThemes/index.html +3351 -0
  57. package/tags/SiteLog/index.html +3351 -0
  58. package/tags/index.html +3159 -0
  59. package/volantis-sw.js +797 -0
package/volantis-sw.js ADDED
@@ -0,0 +1,797 @@
1
+ // 全站打包上传 npm,sw 并发请求 cdn
2
+ const prefix = 'volantis-community';
3
+ const cacheSuffixVersion = '00000018-0.37026152433586423';
4
+ const CACHE_NAME = prefix + '-v' + cacheSuffixVersion;
5
+ const PreCachlist = [
6
+ "/css/style.css",
7
+ "/js/app.js",
8
+ "/js/search/hexo.js",
9
+ ];
10
+ let NPMMirror = true;
11
+ const NPMPackage = "@mlikiowa/nanaeo";
12
+ let NPMPackageVersion = "1.0.1702967656417";
13
+ let debug = true;
14
+ // location.hostname == 'localhost' && (debug = true) && (NPMMirror = false);
15
+ const handleFetch = async (event) => {
16
+ const url = event.request.url;
17
+ if (/nocache/.test(url)) {
18
+ return NetworkOnly(event)
19
+ } else if (/@latest/.test(url)) {
20
+ return CacheFirst(event)
21
+ } else if (/cdnjs\.cloudflare\.com/.test(url)) {
22
+ return CacheAlways(event)
23
+ } else if (/music\.126\.net/.test(url)) {
24
+ return CacheAlways(event)
25
+ } else if (/qqmusic\.qq\.com/.test(url)) {
26
+ return CacheAlways(event)
27
+ } else if (/jsdelivr\.net/.test(url)) {
28
+ return CacheAlways(event)
29
+ } else if (/npm\.elemecdn\.com/.test(url)) {
30
+ return CacheAlways(event)
31
+ } else if (/unpkg\.com/.test(url)) {
32
+ return CacheAlways(event)
33
+ } else if (/.*\.(?:png|jpg|jpeg|svg|gif|webp|ico|eot|ttf|woff|woff2|mp3)$/.test(url)) {
34
+ return CacheAlways(event)
35
+ } else if (/.*\.(css|js)$/.test(url)) {
36
+ return CacheAlways(event)
37
+ } else {
38
+ return CacheFirst(event)
39
+ }
40
+ }
41
+ const cdn = {
42
+ gh: {
43
+ jsdelivr: 'https://cdn.jsdelivr.net/gh',
44
+ fastly: 'https://fastly.jsdelivr.net/gh',
45
+ gcore: 'https://gcore.jsdelivr.net/gh',
46
+ testingcf: 'https://testingcf.jsdelivr.net/gh',
47
+ test1: 'https://test1.jsdelivr.net/gh',
48
+ },
49
+ combine: {
50
+ jsdelivr: 'https://cdn.jsdelivr.net/combine',
51
+ fastly: 'https://fastly.jsdelivr.net/combine',
52
+ gcore: 'https://gcore.jsdelivr.net/combine',
53
+ testingcf: 'https://testingcf.jsdelivr.net/combine',
54
+ test1: 'https://test1.jsdelivr.net/combine',
55
+ },
56
+ npm: {
57
+ jsdelivr: 'https://cdn.jsdelivr.net/npm',
58
+ fastly: 'https://fastly.jsdelivr.net/npm',
59
+ gcore: 'https://gcore.jsdelivr.net/npm',
60
+ testingcf: 'https://testingcf.jsdelivr.net/npm',
61
+ test1: 'https://test1.jsdelivr.net/npm',
62
+ unpkg: 'https://unpkg.com',
63
+ eleme: 'https://npm.elemecdn.com',
64
+ },
65
+ cdnjs: {
66
+ cdnjs: 'https://cdnjs.cloudflare.com/ajax/libs',
67
+ baomitu: 'https://lib.baomitu.com',
68
+ bootcdn: 'https://cdn.bootcdn.net/ajax/libs',
69
+ bytedance: 'https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M',
70
+ sustech: 'https://mirrors.sustech.edu.cn/cdnjs/ajax/libs',
71
+ }
72
+ }
73
+ const cdn_match_list = []
74
+ for (const type in cdn) {
75
+ for (const key in cdn[type]) {
76
+ cdn_match_list.push({ type: type, key: cdn[type][key] })
77
+ }
78
+ }
79
+ const _console = console;
80
+ const color = {
81
+ black: '#000000',
82
+ red: '#FF0000',
83
+ green: '#008000',
84
+ yellow: '#FFFF00',
85
+ blue: '#0000FF',
86
+ magenta: '#FF00FF',
87
+ cyan: '#00FFFF',
88
+ white: '#FFFFFF',
89
+ };
90
+ const add = (...arr) => {
91
+ let fi = [
92
+ []
93
+ ];
94
+ for (let key = 0; key < arr.length; key++) {
95
+ const [first, ...other] = arr[key];
96
+ fi[0] += first;
97
+ fi = fi.concat(other);
98
+ }
99
+ return fi;
100
+ };
101
+ const createlog = (util) => (...args) => {
102
+ // const fun = _console[util] ? _console[util] : _console.log;
103
+ const fun = util == "error" ? _console[util] : _console.log;
104
+ fun.apply(void 0, args);
105
+ };
106
+ const creategroup = (util) => (...args) => {
107
+ const fun = _console.groupCollapsed;
108
+ fun.apply(void 0, args);
109
+ };
110
+ const colorUtils = {
111
+ bold: (str) => {
112
+ if (typeof str === 'string' || typeof str === 'number') {
113
+ return `${str};font-weight: bold;`;
114
+ }
115
+ for (let key = 1; key < str.length; key++) {
116
+ str[key] += `;font-weight: bold;`;
117
+ }
118
+ return str;
119
+ }
120
+ };
121
+ const colorHash = {
122
+ log: 'black',
123
+ wait: 'cyan',
124
+ error: 'red',
125
+ warn: 'yellow',
126
+ ready: 'green',
127
+ info: 'blue',
128
+ event: 'magenta',
129
+ };
130
+ const createChalk = (name) => (...str) => {
131
+ if (typeof str[0] === 'object') {
132
+ createlog(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), ...str));
133
+ return;
134
+ }
135
+ let strArr = str;
136
+ if (typeof str === 'string' || typeof str === 'number') {
137
+ strArr = colorUtils[colorHash[name]](str);
138
+ }
139
+ createlog(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), strArr));
140
+ };
141
+ const createChalkBg = (name) => (...str) => {
142
+ if (typeof str[0] === 'object') {
143
+ createlog(name)(...add(colorUtils.bold(colorUtils[`bg${firstToUpperCase(colorHash[name])}`](`[${firstToUpperCase(name)}] `)), ...str));
144
+ return;
145
+ }
146
+ let strArr = str;
147
+ if (typeof str === 'string' || typeof str === 'number') {
148
+ strArr = colorUtils[colorHash[name]](str);
149
+ }
150
+ createlog(name)(...add(colorUtils.bold(colorUtils[`bg${firstToUpperCase(colorHash[name])}`](`[${firstToUpperCase(name)}] `)), strArr));
151
+ };
152
+ const createChalkGroup = (name) => (...str) => {
153
+ if (typeof str[0] === 'object') {
154
+ creategroup(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), ...str));
155
+ return;
156
+ }
157
+ let strArr = str;
158
+ if (typeof str === 'string' || typeof str === 'number') {
159
+ strArr = colorUtils[colorHash[name]](str);
160
+ }
161
+ creategroup(name)(...add(colorUtils.bold(colorUtils[colorHash[name]](`[${firstToUpperCase(name)}] `)), strArr));
162
+ };
163
+ const chalk = {
164
+ group: {
165
+ end: _console.groupEnd
166
+ },
167
+ bg: {}
168
+ };
169
+ Object.keys(colorHash).forEach(key => {
170
+ chalk[key] = createChalk(key);
171
+ chalk.group[key] = createChalkGroup(key);
172
+ chalk.bg[key] = createChalkBg(key);
173
+ });
174
+ const firstToUpperCase = (str) => str.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
175
+ Object.keys(color).forEach(key => {
176
+ colorUtils[key] = (str) => {
177
+ if (typeof str === 'string' || typeof str === 'number') {
178
+ return [`%c${str}`, `color:${color[key]}`];
179
+ }
180
+ for (let i = 1; i < str.length; i++) {
181
+ str[i] += `;color:${color[key]}`;
182
+ }
183
+ return str;
184
+ };
185
+ colorUtils[`bg${firstToUpperCase(key)}`] = (str) => {
186
+ if (typeof str === 'string' || typeof str === 'number') {
187
+ return [`%c${str}`, `padding: 2px 4px; border-radius: 3px; color: ${key === 'white' ? '#000' : '#fff'}; font-weight: bold; background:${color[key]};`];
188
+ }
189
+ for (let i = 1; i < str.length; i++) {
190
+ str[i] += `;padding: 2px 4px; border-radius: 3px; font-weight: bold; background:${color[key]};`;
191
+ }
192
+ return str;
193
+ };
194
+ });
195
+ self.logger = {
196
+ add,
197
+ ...chalk,
198
+ ...colorUtils,
199
+ };
200
+
201
+ if (!debug) {
202
+ logger = {
203
+ log: () => { },
204
+ wait: () => { },
205
+ error: () => { },
206
+ warn: () => { },
207
+ ready: () => { },
208
+ info: () => { },
209
+ event: () => { },
210
+ group: {
211
+ log: () => { },
212
+ wait: () => { },
213
+ error: () => { },
214
+ warn: () => { },
215
+ ready: () => { },
216
+ info: () => { },
217
+ event: () => { },
218
+ end: () => { },
219
+ },
220
+ bg: {
221
+ log: () => { },
222
+ wait: () => { },
223
+ error: () => { },
224
+ warn: () => { },
225
+ ready: () => { },
226
+ info: () => { },
227
+ event: () => { },
228
+ }
229
+ };
230
+ console.log = () => { };
231
+ }
232
+
233
+ const generate_uuid = () => {
234
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
235
+ var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
236
+ return v.toString(16);
237
+ });
238
+ }
239
+ self.db = {
240
+ read: (key, config) => {
241
+ if (!config) { config = { type: "text" } }
242
+ return new Promise((resolve, reject) => {
243
+ caches.open(CACHE_NAME).then(cache => {
244
+ cache.match(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`)).then(function (res) {
245
+ if (!res) resolve(null)
246
+ res.text().then(text => resolve(text))
247
+ }).catch(() => {
248
+ resolve(null)
249
+ })
250
+ })
251
+ })
252
+ },
253
+ write: (key, value) => {
254
+ return new Promise((resolve, reject) => {
255
+ caches.open(CACHE_NAME).then(function (cache) {
256
+ cache.put(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`), new Response(value));
257
+ resolve()
258
+ }).catch(() => {
259
+ reject()
260
+ })
261
+ })
262
+ }
263
+ }
264
+ const compareVersion = (a, b) => {
265
+ let v1 = a.split('.');
266
+ let v2 = b.split('.');
267
+ const len = Math.max(v1.length, v2.length);
268
+ while (v1.length < len) {
269
+ v1.push('0');
270
+ }
271
+ while (v2.length < len) {
272
+ v2.push('0');
273
+ }
274
+ for (let i = 0; i < len; i++) {
275
+ const num1 = parseInt(v1[i]);
276
+ const num2 = parseInt(v2[i]);
277
+ if (num1 > num2) {
278
+ return a;
279
+ } else if (num1 < num2) {
280
+ return b;
281
+ }
282
+ }
283
+ return a;
284
+ }
285
+
286
+ const mirrors = [
287
+ `https://registry.npmjs.org/${NPMPackage}/latest`,
288
+ `https://registry.npmmirror.com/${NPMPackage}/latest`,
289
+ `https://mirrors.cloud.tencent.com/npm/${NPMPackage}/latest`
290
+ ]
291
+ const getLocalVersion = async () => {
292
+ NPMPackageVersion = await db.read('blog_version') || NPMPackageVersion
293
+ logger.bg.info(`Local Version: ${NPMPackage}@${NPMPackageVersion}`)
294
+ }
295
+ let mirror_time = 0;
296
+ const setNewestVersion = async () => {
297
+ if (!NPMMirror) {
298
+ return
299
+ }
300
+ let f = null;
301
+ if (!(mirror_time % (mirrors.length + 1))) {
302
+ f = FetchEngine(mirrors);
303
+ } else {
304
+ f = fetch(mirrors[(mirror_time % (mirrors.length + 1)) - 1]);
305
+ }
306
+ mirror_time++;
307
+ return f
308
+ .then(res => res.json())
309
+ .then(async res => {
310
+ if (!res.version) throw ('No Version Found!')
311
+ NPMPackageVersion = compareVersion(res.version, await db.read('blog_version') || NPMPackageVersion)
312
+ logger.bg.ready(`${NPMPackage}@${NPMPackageVersion}`)
313
+ await db.write('blog_version', NPMPackageVersion)
314
+ })
315
+ .catch(error => {
316
+ logger.error('[Set Newest Version] ' + (error.stack || error))
317
+ })
318
+ }
319
+ setInterval(async () => {
320
+ await setNewestVersion()
321
+ }, 60 * 1000);
322
+ setTimeout(async () => {
323
+ await setNewestVersion()
324
+ }, 5000)
325
+ const installFunction = async () => {
326
+ await getLocalVersion();
327
+ return caches.open(CACHE_NAME + "-precache")
328
+ .then(async function (cache) {
329
+ if (!await db.read('uuid')) {
330
+ await db.write('uuid', generate_uuid())
331
+ }
332
+ if (PreCachlist.length) {
333
+ logger.group.event(`Precaching ${PreCachlist.length} files.`);
334
+ let index = 0;
335
+ PreCachlist.forEach(function (url) {
336
+ cache.match(new Request(url)).then(function (response) {
337
+ if (response) {
338
+ logger.ready(`Precaching ${url}`);
339
+ } else {
340
+ logger.wait(`Precaching ${url}`);
341
+ cache.add(new Request(url));
342
+ }
343
+ index++;
344
+ if (index === PreCachlist.length) {
345
+ logger.ready(`Precached ${PreCachlist.length} files.`);
346
+ logger.group.end();
347
+ }
348
+ })
349
+ })
350
+ }
351
+ }).catch((error) => {
352
+ logger.error('[install] ' + (error.stack || error));
353
+ })
354
+ }
355
+ self.addEventListener('install', async function (event) {
356
+ logger.bg.event("service worker install event listening");
357
+ try {
358
+ self.skipWaiting();
359
+ event.waitUntil(installFunction());
360
+ logger.bg.ready('service worker install sucess!');
361
+ } catch (error) {
362
+ logger.error('[install] ' + (error.stack || error));
363
+ }
364
+ });
365
+ self.addEventListener('activate', async event => {
366
+ logger.bg.event("service worker activate event listening");
367
+ try {
368
+ event.waitUntil(
369
+ caches.keys().then((keys) => {
370
+ return Promise.all(keys.map((key) => {
371
+ if (!key.includes(cacheSuffixVersion)) {
372
+ caches.delete(key);
373
+ logger.bg.ready('Deleted Outdated Cache: ' + key);
374
+ }
375
+ }));
376
+ }).catch((error) => {
377
+ logger.error('[activate] ' + (error.stack || error));
378
+ })
379
+ );
380
+ await self.clients.claim()
381
+ logger.bg.ready('service worker activate sucess!');
382
+ } catch (error) {
383
+ logger.error('[activate] ' + (error.stack || error));
384
+ }
385
+ })
386
+ self.addEventListener('fetch', async event => {
387
+ event.respondWith(
388
+ handleFetch(event).catch((error) => {
389
+ logger.error('[fetch] ' + event.request.url + '\n[error] ' + (error.stack || error));
390
+ })
391
+ )
392
+ });
393
+
394
+
395
+ const NetworkOnly = async (event) => {
396
+ logger.group.info('NetworkOnly: ' + new URL(event.request.url).pathname);
397
+ logger.wait('service worker fetch: ' + event.request.url)
398
+ logger.group.end();
399
+ return fetch(event.request)
400
+ }
401
+ const CacheFirst = async (event) => {
402
+ return caches.match(event.request).then(function (resp) {
403
+ logger.group.info('CacheFirst: ' + new URL(event.request.url).pathname);
404
+ logger.wait('service worker fetch: ' + event.request.url)
405
+ if (resp) {
406
+ logger.group.ready(`Cache Hit`);
407
+ console.log(resp)
408
+ logger.group.end();
409
+ logger.group.end();
410
+ event.waitUntil(CacheRuntime(event.request))
411
+ return resp;
412
+ } else {
413
+ logger.warn(`Cache Miss`);
414
+ logger.group.end();
415
+ return CacheRuntime(event.request)
416
+ }
417
+ })
418
+ }
419
+ const CacheAlways = async (event) => {
420
+ return caches.match(event.request).then(function (resp) {
421
+ logger.group.info('CacheAlways: ' + new URL(event.request.url).pathname);
422
+ logger.wait('service worker fetch: ' + event.request.url)
423
+ if (resp) {
424
+ logger.group.ready(`Cache Hit`);
425
+ console.log(resp)
426
+ logger.group.end();
427
+ logger.group.end();
428
+ return resp;
429
+ } else {
430
+ logger.warn(`Cache Miss`);
431
+ logger.group.end();
432
+ return CacheRuntime(event.request)
433
+ }
434
+ })
435
+ }
436
+
437
+ const matchCache = async (event) => {
438
+ return caches.match(event.request).then(function (resp) {
439
+ logger.group.info('service worker fetch: ' + event.request.url)
440
+ if (resp) {
441
+ logger.group.ready(`Cache Hit`);
442
+ console.log(resp)
443
+ logger.group.end();
444
+ logger.group.end();
445
+ return resp;
446
+ } else {
447
+ logger.warn(`Cache Miss`);
448
+ logger.group.end();
449
+ return CacheRuntime(event.request)
450
+ }
451
+ })
452
+ }
453
+ async function CacheRuntime(request) {
454
+ const url = new URL(request.url);
455
+ let response = await matchCDN(request);
456
+ if (!response) {
457
+ response = await fetch(request).catch(() => null)
458
+ }
459
+ logger.group.event(`Cache Runtime ${url.pathname}`);
460
+ logger.wait(`Caching url: ${request.url}`);
461
+ console.log(response);
462
+
463
+ if (request.method === "GET" && (url.protocol == "https:")) {
464
+ const cache = await caches.open(CACHE_NAME + "-runtime");
465
+ cache.put(request, response.clone()).catch(error => {
466
+ logger.error('[Cache Runtime] ' + (error.stack || error));
467
+ if (error.name === 'QuotaExceededError') {
468
+ caches.delete(CACHE_NAME + "-runtime");
469
+ logger.ready("deleted cache")
470
+ }
471
+ })
472
+ logger.ready(`Cached url: ${request.url}`);
473
+ } else {
474
+ logger.warn(`Not Cached url: ${request.url}`);
475
+ }
476
+ logger.group.end();
477
+ return response;
478
+ }
479
+
480
+ const matchCDN = async (req) => {
481
+ const nav = navigator
482
+ const { saveData, effectiveType } = nav.connection || nav.mozConnection || nav.webkitConnection || {}
483
+ if (saveData || /2g/.test(effectiveType)) {
484
+ logger.warn("Slow Network: Transparent Proxy");
485
+ return fetch(req);
486
+ }
487
+ const urls = []
488
+ let urlObj = new URL(req.url)
489
+ let pathType = urlObj.pathname.split('/')[1]
490
+ let pathTestRes = "";
491
+
492
+ if (NPMMirror && new RegExp(location.origin).test(req.url)) {
493
+ logger.group.ready(`Match NPM Mirror: ` + req.url);
494
+ for (const key in cdn.npm) {
495
+ let url = cdn.npm[key] + "/" + NPMPackage + "@" + NPMPackageVersion + req.url.replace(location.origin, '')
496
+ url = fullPath(fullPath(url))
497
+ console.log(url);
498
+ urls.push(url)
499
+ }
500
+ logger.group.end()
501
+ }
502
+ if (!urls.length) {
503
+ for (const item of cdn_match_list) {
504
+ if (new RegExp(item.key).test(req.url)) {
505
+ pathType = item.type
506
+ pathTestRes = new RegExp(item.key).exec(req.url)[0]
507
+ break;
508
+ }
509
+ }
510
+ for (const type in cdn) {
511
+ if (type === pathType) {
512
+ logger.group.ready(`Match CDN ${pathType}: ` + req.url);
513
+ for (const key in cdn[type]) {
514
+ const url = cdn[type][key] + req.url.replace(pathTestRes, '')
515
+ console.log(url);
516
+ urls.push(url)
517
+ }
518
+ logger.group.end()
519
+ }
520
+ }
521
+ }
522
+
523
+ let res;
524
+ if (urls.length)
525
+ res = FetchEngine(urls)
526
+ else
527
+ res = fetch(req)
528
+ if (res && NPMMirror && new RegExp(location.origin).test(req.url)) {
529
+ const ext = fullPath(fullPath(req.url)).split('.').pop()
530
+ const contentType = getContentType(ext)
531
+ res = res
532
+ .then(res => res.arrayBuffer())
533
+ .then(buffer => new Response(buffer, {
534
+ headers: {
535
+ "Content-Type": contentType
536
+ }
537
+ }))
538
+ .catch(() => null)
539
+ }
540
+ return res
541
+ }
542
+
543
+ const fullPath = (url) => {
544
+ url = url.split('?')[0].split('#')[0]
545
+ if (url.endsWith('/')) {
546
+ url += 'index.html'
547
+ } else {
548
+ const list = url.split('/')
549
+ const last = list[list.length - 1]
550
+ if (last.indexOf('.') === -1) {
551
+ url += '.html'
552
+ }
553
+ }
554
+ return url
555
+ }
556
+ async function progress(res) {
557
+ return new Response(await res.arrayBuffer(), {
558
+ status: res.status,
559
+ headers: res.headers
560
+ })
561
+ }
562
+
563
+ function createPromiseAny() {
564
+ Promise.any = function (promises) {
565
+ return new Promise((resolve, reject) => {
566
+ promises = Array.isArray(promises) ? promises : []
567
+ let len = promises.length
568
+ let errs = []
569
+ if (len === 0) return reject(new AggregateError('All promises were rejected'))
570
+ promises.forEach((p) => {
571
+ if (p instanceof Promise) {
572
+ p.then(
573
+ (res) => resolve(res),
574
+ (err) => {
575
+ len--
576
+ errs.push(err)
577
+ if (len === 0) reject(new AggregateError(errs))
578
+ }
579
+ )
580
+ } else {
581
+ reject(p)
582
+ }
583
+ })
584
+ })
585
+ }
586
+ }
587
+
588
+ function fetchAny(reqs) {
589
+ const controller = new AbortController()
590
+
591
+ return reqs.map(req => {
592
+ return new Promise((resolve, reject) => {
593
+ fetch(req, {
594
+ signal: controller.signal
595
+ })
596
+ .then(progress)
597
+ .then(res => {
598
+ controller.abort()
599
+ if (res.status !== 200)
600
+ reject(null)
601
+ else
602
+ resolve(res)
603
+ })
604
+ .catch(() => reject(null))
605
+ })
606
+ })
607
+ }
608
+
609
+ function fetchParallel(reqs) {
610
+ const abortEvent = new Event("abortOtherInstance")
611
+ const eventTarget = new EventTarget();
612
+
613
+ return reqs.map(async req => {
614
+ const controller = new AbortController();
615
+ let tagged = false;
616
+ eventTarget.addEventListener(abortEvent.type, () => {
617
+ if (!tagged) controller.abort();
618
+ })
619
+ return new Promise((resolve, reject) => {
620
+ fetch(req, {
621
+ signal: controller.signal,
622
+ }).then(res => {
623
+ tagged = true;
624
+ eventTarget.dispatchEvent(abortEvent)
625
+ if (res.status !== 200)
626
+ reject(null)
627
+ else
628
+ resolve(res)
629
+ }).catch(() => reject(null))
630
+ })
631
+ });
632
+ }
633
+
634
+ const FetchEngine = (reqs) => {
635
+ if (!Promise.any) createPromiseAny();
636
+ return Promise.any(fetchParallel(reqs)).then(res => res)
637
+ .catch((e) => {
638
+ if (e == "AggregateError: All promises were rejected") {
639
+ return Promise.any(fetchAny(reqs))
640
+ .then((res) => res)
641
+ .catch(() => null);
642
+ }
643
+ return null;
644
+ });
645
+ };
646
+
647
+ const getContentType = (ext) => {
648
+ switch (ext) {
649
+ case 'js':
650
+ return 'text/javascript'
651
+ case 'html':
652
+ return 'text/html'
653
+ case 'css':
654
+ return 'text/css'
655
+ case 'json':
656
+ return 'application/json'
657
+ case 'webp':
658
+ return 'image/webp'
659
+ case 'jpg':
660
+ return 'image/jpg'
661
+ case 'jpeg':
662
+ return 'image/jpeg'
663
+ case 'png':
664
+ return 'image/png'
665
+ case 'gif':
666
+ return 'image/gif'
667
+ case 'xml':
668
+ return 'text/xml'
669
+ case 'xsl':
670
+ return 'text/xml'
671
+ case 'webmanifest':
672
+ return 'text/webmanifest'
673
+ case 'map':
674
+ return 'application/json'
675
+ case 'bcmap':
676
+ return 'image/vnd.wap.wbmp'
677
+ case 'wbmp':
678
+ return 'image/vnd.wap.wbmp'
679
+ case 'bmp':
680
+ return 'image/bmp'
681
+ case 'ico':
682
+ return 'image/vnd.microsoft.icon'
683
+ case 'tiff':
684
+ return 'image/tiff'
685
+ case 'tif':
686
+ return 'image/tiff'
687
+ case 'svg':
688
+ return 'image/svg+xml'
689
+ case 'svgz':
690
+ return 'image/svg+xml'
691
+ case 'woff':
692
+ return 'application/font-woff'
693
+ case 'woff2':
694
+ return 'application/font-woff2'
695
+ case 'ttf':
696
+ return 'application/font-ttf'
697
+ case 'otf':
698
+ return 'application/font-otf'
699
+ case 'eot':
700
+ return 'application/vnd.ms-fontobject'
701
+ case 'zip':
702
+ return 'application/zip'
703
+ case 'tar':
704
+ return 'application/x-tar'
705
+ case 'gz':
706
+ return 'application/gzip'
707
+ case 'bz2':
708
+ return 'application/x-bzip2'
709
+ case 'rar':
710
+ return 'application/x-rar-compressed'
711
+ case '7z':
712
+ return 'application/x-7z-compressed'
713
+ case 'doc':
714
+ return 'application/msword'
715
+ case 'docx':
716
+ return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
717
+ case 'xls':
718
+ return 'application/vnd.ms-excel'
719
+ case 'xlsx':
720
+ return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
721
+ case 'ppt':
722
+ return 'application/vnd.ms-powerpoint'
723
+ case 'pptx':
724
+ return 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
725
+ case 'pdf':
726
+ return 'application/pdf'
727
+ case 'txt':
728
+ return 'text/plain'
729
+ case 'rtf':
730
+ return 'application/rtf'
731
+ case 'mp3':
732
+ return 'audio/mpeg'
733
+ case 'wav':
734
+ return 'audio/x-wav'
735
+ case 'ogg':
736
+ return 'audio/ogg'
737
+ case 'mp4':
738
+ return 'video/mp4'
739
+ case 'm4v':
740
+ return 'video/x-m4v'
741
+ case 'mov':
742
+ return 'video/quicktime'
743
+ case 'avi':
744
+ return 'video/x-msvideo'
745
+ case 'wmv':
746
+ return 'video/x-ms-wmv'
747
+ case 'flv':
748
+ return 'video/x-flv'
749
+ case 'swf':
750
+ return 'application/x-shockwave-flash'
751
+ case 'mpg':
752
+ return 'video/mpeg'
753
+ case 'mpeg':
754
+ return 'video/mpeg'
755
+ case 'mpe':
756
+ return 'video/mpeg'
757
+ case 'mpv':
758
+ return 'video/mpeg'
759
+ case 'm2v':
760
+ return 'video/mpeg'
761
+ case 'm4a':
762
+ return 'audio/mp4'
763
+ case 'aac':
764
+ return 'audio/aac'
765
+ case 'm3u':
766
+ return 'audio/x-mpegurl'
767
+ case 'm3u8':
768
+ return 'application/vnd.apple.mpegurl'
769
+ case 'pls':
770
+ return 'audio/x-scpls'
771
+ case 'cue':
772
+ return 'application/x-cue'
773
+ case 'wma':
774
+ return 'audio/x-ms-wma'
775
+ case 'flac':
776
+ return 'audio/flac'
777
+ case 'aif':
778
+ return 'audio/x-aiff'
779
+ case 'aiff':
780
+ return 'audio/x-aiff'
781
+ case 'aifc':
782
+ return 'audio/x-aiff'
783
+ case 'au':
784
+ return 'audio/basic'
785
+ case 'snd':
786
+ return 'audio/basic'
787
+ case 'mid':
788
+ return 'audio/midi'
789
+ case 'midi':
790
+ return 'audio/midi'
791
+ case 'kar':
792
+ return 'audio/midi'
793
+ default:
794
+ return 'text/plain'
795
+ }
796
+ }
797
+