1(function (window, document) { 2 'use strict'; 3 var bridge = window.ManualsEzoicAccountLink; 4 var api = null; 5 var auth = null; 6 var busy = false; 7 var pending = false; 8 var mounted = false; 9 var navigating = false; 10 var changeVersion = 0; 11 var screen = 'loading'; 12 var status = document.getElementById('manuals-ezoic-status'); 13 var retry = document.querySelector('[data-manuals-ezoic-retry]'); 14 15 function show(message, error) { 16 if (!status) return; 17 status.textContent = message || ''; 18 status.className = error ? 'notice error' : 'notice'; 19 status.style.display = message ? 'block' : 'none'; 20 } 21 22 function actionScreen() { 23 return screen === 'loading' || screen === 'reset' || screen === 'verify' 24 || screen === 'notice' || screen === 'forgot'; 25 } 26 27 async function confirmLocalSession(userId) { 28 var response = await fetch('/login/google-onetap', { 29 method: 'GET', credentials: 'same-origin', cache: 'no-store', 30 headers: {'Accept': 'application/json', 'X-Requested-With': 'manuals-account'} 31 }); 32 var result = await response.json().catch(function () { return {}; }); 33 if (!response.ok || !result.ok || !result.user || Number(result.user.id) !== userId) { 34 var error = new Error('local_session_unconfirmed'); 35 error.code = 'local_session_unconfirmed'; 36 throw error; 37 } 38 } 39 40 async function reconcile() { 41 changeVersion++; 42 pending = true; 43 if (busy || navigating || !api || !mounted || actionScreen() 44 || window.manualsLoginAlreadySignedIn) return; 45 if (!window.manualsLoginIntentReady) { 46 window.setTimeout(reconcile, 80); 47 return; 48 } 49 busy = true; 50 if (retry) retry.hidden = true; 51 try { 52 do { 53 pending = false; 54 var version = changeVersion; 55 var result = await bridge.sync(api, '/account/api/premium/', {}); 56 if (actionScreen()) break; 57 if (version !== changeVersion) continue; 58 var userId = Number(result.account_user_id); 59 if (!result.anonymous && result.ok && Number.isSafeInteger(userId) && userId > 0) { 60 await confirmLocalSession(userId); 61 if (actionScreen()) break; 62 if (version !== changeVersion) continue; 63 navigating = true; 64 window.manualsLoginAlreadySignedIn = true; 65 show('Signed in. Opening your Manuals+ accountâ¦', false); 66 window.location.replace(window.manualsContinueTo); 67 break; 68 } 69 } while (pending && !actionScreen()); 70 } catch (error) { 71 show(error.code === 'local_session_unconfirmed' 72 ? 'Your Manuals+ session could not be confirmed. Allow cookies and try again.' 73 : bridge.message(error), true); 74 if (retry) retry.hidden = false; 75 } finally { 76 busy = false; 77 if (pending && !navigating && !actionScreen()) { 78 pending = false; 79 window.setTimeout(reconcile, 0); 80 } 81 } 82 } 83 84 async function mount() { 85 if (mounted) return; 86 try { 87 auth = await bridge.ready(); 88 if (!auth || typeof auth.mount !== 'function') throw new Error('sdk_unavailable'); 89 var container = document.getElementById('manuals-ezoic-form'); 90 if (!container) return; 91 container.textContent = ''; 92 auth.mount(container, { 93 mode: 'login', showToggle: true, 94 onScreenChange: function (nextScreen) { 95 var wasAction = actionScreen(); 96 screen = nextScreen; 97 // Reset and verification links must finish their own screens before 98 // an existing Ezoic session can redirect away from the emailed action. 99 if (mounted && wasAction && !actionScreen()) reconcile(); 100 } 101 }); 102 mounted = true; 103 auth.onChange(reconcile); 104 if (retry) retry.hidden = true; 105 reconcile(); 106 } catch (error) { 107 show('Email sign-in could not load. Try again or use another sign-in option.', true); 108 if (retry) retry.hidden = false; 109 } 110 } 111 112 if (retry) retry.addEventListener('click', function () { 113 show('', false); 114 if (mounted) reconcile(); else mount(); 115 }); 116 117 window.ezsubscriptions = window.ezsubscriptions || {}; 118 window.ezsubscriptions.cmd = window.ezsubscriptions.cmd || []; 119 window.ezsubscriptions.cmd.push(function (resolved) { 120 api = resolved || window.ezsubscriptions; 121 if (typeof api.on === 'function') api.on('access:change', reconcile); 122 reconcile(); 123 }); 124 mount(); 125}(window, document));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.