'use strict'; const OFFLINE_DATA_FILE = 'offline.json', CACHE_NAME_PREFIX = 'c3offline', BROADCASTCHANNEL_NAME = 'offline', CONSOLE_PREFIX = '[SW] ', LAZYLOAD_KEYNAME = '', broadcastChannel = 'undefined' == typeof BroadcastChannel ? null : new BroadcastChannel('offline'); function PostBroadcastMessage(a) { broadcastChannel && setTimeout(() => broadcastChannel.postMessage(a), 3e3); } function Broadcast(a) { PostBroadcastMessage({ type: a }); } function BroadcastDownloadingUpdate(a) { PostBroadcastMessage({ type: 'downloading-update', version: a }); } function BroadcastUpdateReady(a) { PostBroadcastMessage({ type: 'update-ready', version: a }); } function IsUrlInLazyLoadList(a, b) { if (!b) return !1; try { for (const c of b) if (new RegExp(c).test(a)) return !0; } catch (a) { console.error('[SW] Error matching in lazy-load list: ', a); } return !1; } function WriteLazyLoadListToStorage(a) { return 'undefined' == typeof localforage ? Promise.resolve() : localforage.setItem(LAZYLOAD_KEYNAME, a); } function ReadLazyLoadListFromStorage() { return 'undefined' == typeof localforage ? Promise.resolve([]) : localforage.getItem(LAZYLOAD_KEYNAME); } function GetCacheBaseName() { return 'c3offline-' + self.registration.scope; } function GetCacheVersionName(a) { return GetCacheBaseName() + '-v' + a; } async function GetAvailableCacheNames() { const a = await caches.keys(), b = GetCacheBaseName(); return a.filter((a) => a.startsWith(b)); } async function IsUpdatePending() { const a = await GetAvailableCacheNames(); return 2 <= a.length; } async function GetMainPageUrl() { const a = await clients.matchAll({ includeUncontrolled: !0, type: 'window' }); for (const b of a) { let a = b.url; if ( (a.startsWith(self.registration.scope) && (a = a.substring(self.registration.scope.length)), a && '/' !== a) ) return a.startsWith('?') && (a = '/' + a), a; } return ''; } function fetchWithBypass(a, b) { return ( 'string' == typeof a && (a = new Request(a)), b ? fetch(a.url, { headers: a.headers, mode: a.mode, credentials: a.credentials, redirect: a.redirect, cache: 'no-store' }) : fetch(a) ); } async function CreateCacheFromFileList(a, b, c) { const d = await Promise.all(b.map((a) => fetchWithBypass(a, c))); let e = !0; for (const f of d) f.ok || ((e = !1), console.error("[SW] Error fetching '" + f.url + "' (" + f.status + ' ' + f.statusText + ')')); if (!e) throw new Error('not all resources were fetched successfully'); const f = await caches.open(a); try { return await Promise.all(d.map((a, c) => f.put(b[c], a))); } catch (b) { throw (console.error('[SW] Error writing cache entries: ', b), caches.delete(a), b); } } async function UpdateCheck(a) { try { const b = await fetchWithBypass(OFFLINE_DATA_FILE, !0); if (!b.ok) throw new Error('offline.json responded with ' + b.status + ' ' + b.statusText); const c = await b.json(), d = c.version, e = c.fileList, f = c.lazyLoad, g = GetCacheVersionName(d), h = await caches.has(g); if (h) { const a = await IsUpdatePending(); return void (a ? (console.log('[SW] Update pending'), Broadcast('update-pending')) : (console.log('[SW] Up to date'), Broadcast('up-to-date'))); } const i = await GetMainPageUrl(); e.unshift('./'), i && -1 === e.indexOf(i) && e.unshift(i), console.log('[SW] Caching ' + e.length + ' files for offline use'), a ? Broadcast('downloading') : BroadcastDownloadingUpdate(d), f && (await WriteLazyLoadListToStorage(f)), await CreateCacheFromFileList(g, e, !a); const j = await IsUpdatePending(); j ? (console.log('[SW] All resources saved, update ready'), BroadcastUpdateReady(d)) : (console.log('[SW] All resources saved, offline support ready'), Broadcast('offline-ready')); } catch (a) { console.warn('[SW] Update check failed: ', a); } } self.addEventListener('install', (a) => { a.waitUntil(UpdateCheck(!0).catch(() => null)); }); async function GetCacheNameToUse(a, b) { if (1 === a.length || !b) return a[0]; const c = await clients.matchAll(); if (1 < c.length) return a[0]; const d = a[a.length - 1]; return ( console.log('[SW] Updating to new version'), await Promise.all(a.slice(0, -1).map((a) => caches.delete(a))), d ); } async function HandleFetch(a, b) { const c = await GetAvailableCacheNames(); if (!c.length) return fetch(a.request); const d = await GetCacheNameToUse(c, b), e = await caches.open(d), f = await e.match(a.request); if (f) return f; const g = await Promise.all([fetch(a.request), ReadLazyLoadListFromStorage()]), h = g[0], i = g[1]; if (IsUrlInLazyLoadList(a.request.url, i)) try { await e.put(a.request, h.clone()); } catch (b) { console.warn("[SW] Error caching '" + a.request.url + "': ", b); } return h; } self.addEventListener('fetch', (a) => { if (new URL(a.request.url).origin === location.origin) { const b = 'navigate' === a.request.mode, c = HandleFetch(a, b); b && a.waitUntil(c.then(() => UpdateCheck(!1))), a.respondWith(c); } });