PageSourceSearch

https://manuals.plus/account/ezoic-link.js?v=20261001b

js manuals.plus collected 2026-10-01 10:36:01 UTC 11,164 bytes, 259 lines download raw bytes

1(function (window) {
2  'use strict';
3  if (!window.ManualsPremiumUi) {
4    (function installPremiumUi(document) {
5      var key = 'manuals-premium-ui-v1';
6      var ttl = 86400000;
7      var pagePremium = false;
8
9      function installSuppressionStyle() {
10        if (document.getElementById('manuals-premium-ad-suppression')) return;
11        var style = document.createElement('style');
12        style.id = 'manuals-premium-ad-suppression';
13        style.textContent = 'html.mp-premium header .site-description{font-size:0!important;line-height:0!important;white-space:nowrap}html.mp-premium header .site-description::after{content:"PREMIUM";display:inline-block;font-size:.78rem;line-height:1.2;font-weight:800;letter-spacing:.08em;color:#0073aa}html.mp-premium .mp-ad-slot,html.mp-premium .premium-ad-section,html.mp-premium [id^="ezoic-pub-ad-"],html.mp-premium .ezoic-ad,html.mp-premium [class^="ezoic-ad"],html.mp-premium [class*=" ezoic-ad"],html.mp-premium [data-ezoic-ad],html.mp-premium [data-ez-name],html.mp-premium [id^="div-gpt-ad-"],html.mp-premium [id^="google_ads_iframe"],html.mp-premium .ez-placeholder,html.mp-premium [class*="ez-placeholder"],html.mp-premium .ezmob-footer,html.mp-premium [id^="ezmobfooter"],html.mp-premium .ez-sticky-video,html.mp-premium [id^="ez-video"],html.mp-premium ins.adsbygoogle,html.mp-premium iframe[src*="googlesyndication.com"]{display:none!important;min-height:0!important;height:0!important;margin:0!important;padding:0!important;border:0!important;overflow:hidden!important}';
14        (document.head || document.documentElement).appendChild(style);
15      }
16
17      function suppressAdRuntime(active) {
18        if (!active || window.__manualsPremiumAdsDisabled) return;
19        window.__manualsPremiumAdsDisabled = true;
20        window.ezstandalone = window.ezstandalone || {};
21        window.ezstandalone.cmd = window.ezstandalone.cmd || [];
22        window.ezstandalone.cmd.unshift(function () {
23          try {
24            if (typeof window.ezstandalone.setEzoicAnchorAd === 'function') window.ezstandalone.setEzoicAnchorAd(false);
25            if (typeof window.ezstandalone.config === 'function') {
26              window.ezstandalone.config({disableInterstitial:true,disableVideo:true,disableLeftSideRail:true,disableRightSideRail:true,disableSidebarFloating:true});
27            }
28          } catch (ignore) {}
29        });
30        try {
31          if (window.ezsubscriptions && typeof window.ezsubscriptions.disableAds === 'function') window.ezsubscriptions.disableAds();
32        } catch (ignore) {}
33      }
34
35      function serverMembershipActive() {
36        var bodyMember = document.body && document.body.getAttribute('data-member') === '1';
37        var premium = window.MANUALS_PREMIUM || {};
38        var account = window.MANUALS_ACCOUNT_PREMIUM || {};
39        return bodyMember || premium.member === true || account.active === true || account.recordedActive === true;
40      }
41
42      function isActive() {
43        if (pagePremium) return true;
44        try {
45          var value = JSON.parse(window.localStorage.getItem(key) || 'null');
46          if (value && value.active === true && Number(value.expires) > Date.now()) return true;
47          if (value) window.localStorage.removeItem(key);
48        } catch (ignore) {}
49        return false;
50      }
51
52      function updateLabel(active) {
53        if (!document.body) return;
54        document.querySelectorAll('header *').forEach(function (node) {
55          if (active && node.textContent.trim() === 'User Manuals Simplified.') {
56            node.textContent = 'PREMIUM';
57            node.setAttribute('data-manuals-premium-label', '1');
58          } else if (!active && node.getAttribute('data-manuals-premium-label') === '1') {
59            node.textContent = 'User Manuals Simplified.';
60            node.removeAttribute('data-manuals-premium-label');
61          }
62        });
63      }
64
65      function apply(value) {
66        var active = typeof value === 'boolean' ? value : isActive();
67        if (active) pagePremium = true;
68        else if (pagePremium) active = true;
69        installSuppressionStyle();
70        document.documentElement.classList.toggle('mp-premium', active);
71        updateLabel(active);
72        suppressAdRuntime(active);
73        return active;
74      }
75
76      function set(active) {
77        try {
78          if (active) {
79            window.localStorage.setItem(key, JSON.stringify({active: true, expires: Date.now() + ttl}));
80          } else {
81            window.localStorage.removeItem(key);
82          }
83        } catch (ignore) {}
84        apply(!!active);
85        try {
86          window.dispatchEvent(new CustomEvent('manualsPremium:change', {detail: {active: !!active}}));
87        } catch (ignore) {}
88        return !!active;
89      }
90
91      window.ManualsPremiumUi = {isActive: isActive, apply: apply, set: set};
92      if (serverMembershipActive()) set(true); else apply();
93      if (document.readyState === 'loading') {
94        document.addEventListener('DOMContentLoaded', function () {
95          if (serverMembershipActive()) set(true); else apply();
96        }, {once: true});
97      }
98      window.addEventListener('storage', function (event) { if (event.key === key) apply(); });
99    }(document));
100  }
101  if (window.ManualsEzoicAccountLink) return;
102
103  var domainId = 309095;
104  var authReady = null;
105  var subscriptionReadiness = new WeakMap();
106  var authRestoration = new WeakMap();
107
108  async function ensureSubscriptionsReady(api) {
109    if (!api || typeof api.getProducts !== 'function') return;
110    var ready = subscriptionReadiness.get(api);
111    if (!ready) {
112      // The SDK command queue can flush before magic-link redemption finishes.
113      // getProducts() awaits that bootstrap; getSessionToken() does not.
114      ready = Promise.resolve().then(function () { return api.getProducts(); });
115      subscriptionReadiness.set(api, ready);
116      ready.catch(function () { subscriptionReadiness.delete(api); });
117    }
118    await ready;
119  }
120
121  function ensureEzAuth() {
122    if (authReady) return authReady;
123    authReady = new Promise(function (resolve) {
124      var configured = window.ezAuthConfig && Number(window.ezAuthConfig.domainId || 0);
125      if (configured > 0 && configured !== domainId) {
126        resolve(null);
127        return;
128      }
129      window.ezAuthConfig = Object.assign({}, window.ezAuthConfig || {}, {domainId: domainId});
130
131      function initialized() {
132        return window.ezAuth
133          && typeof window.ezAuth.isInitialized === 'function'
134          && window.ezAuth.isInitialized();
135      }
136      if (initialized()) {
137        if (typeof window.ezAuth.getDomainId === 'function'
138            && Number(window.ezAuth.getDomainId() || 0) !== domainId) {
139          resolve(null);
140          return;
141        }
142        resolve(window.ezAuth);
143        return;
144      }
145      if (window.ezAuth && typeof window.ezAuth.init === 'function') {
146        try { window.ezAuth.init({domainId: domainId}); } catch (ignore) {}
147      } else if (!document.querySelector('script[src="https://www.ezojs.com/detroitchicago/ferndale.js"]')) {
148        var script = document.createElement('script');
149        script.src = 'https://www.ezojs.com/detroitchicago/ferndale.js';
150        script.async = true;
151        document.head.appendChild(script);
152      }
153
154      var deadline = Date.now() + 10000;
155      (function poll() {
156        if (initialized()) {
157          resolve(window.ezAuth);
158        } else if (Date.now() >= deadline) {
159          authReady = null;
160          resolve(null);
161        } else {
162          window.setTimeout(poll, 50);
163        }
164      }());
165    });
166    return authReady;
167  }
168
169  async function credentials(api) {
170    await ensureSubscriptionsReady(api);
171    var accountId = 0;
172    var accessToken = '';
173    try {
174      var auth = await ensureEzAuth();
175      if (auth && typeof auth.getUser === 'function') {
176        if (typeof auth.restore === 'function' && !auth.getUser()) {
177          var restoring = authRestoration.get(auth);
178          if (!restoring) {
179            // Anonymous restore emits onChange too. Restore once rather than
180            // starting another restore for every reconciliation it triggers.
181            restoring = Promise.resolve().then(function () { return auth.restore(); });
182            authRestoration.set(auth, restoring);
183            restoring.catch(function () { authRestoration.delete(auth); });
184          }
185          await restoring;
186        }
187        var user = auth.getUser();
188        accountId = user && Number.isSafeInteger(Number(user.accountId)) ? Number(user.accountId) : 0;
189        if (accountId > 0 && typeof auth.getAccessToken === 'function') {
190          accessToken = await auth.getAccessToken() || '';
191        }
192      }
193    } catch (ignore) {
194      accountId = 0;
195      accessToken = '';
196    }
197
198    // Restoration can complete while the identity calls above are awaiting.
199    // Sample the current reader session after those awaits, for every request.
200    var readerToken = null;
201    try { readerToken = api && api.getSessionToken ? api.getSessionToken() : null; } catch (ignore) {}
202
203    if ((accountId <= 0 || !accessToken) && !readerToken) {
204      return null;
205    }
206
207    var result = {reader_token: readerToken};
208    if (accountId > 0 && accessToken) {
209      result.ezoic_account_id = accountId;
210      result.ezoic_access_token = accessToken;
211    }
212    return result;
213  }
214
215  async function sync(api, endpoint, payload) {
216    var identity = await credentials(api);
217    if (!identity) return {ok: false, anonymous: true};
218    var response = await fetch(endpoint || '/account/api/premium/', {
219      method: 'POST',
220      credentials: 'same-origin',
221      cache: 'no-store',
222      headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
223      body: JSON.stringify(Object.assign(identity, payload || {}))
224    });
225    var data = await response.json().catch(function () { return {}; });
226    if (!response.ok || !data.ok) {
227      var error = new Error(data.error || 'ezoic_link_failed');
228      error.code = data.error || 'ezoic_link_failed';
229      error.status = response.status;
230      throw error;
231    }
232    return data;
233  }
234
235  async function login(api) {
236    var identity = await credentials(api);
237    if (identity) {
238      return api.login();
239    }
240    var staleReader = null;
241    try { staleReader = api && api.getSessionToken ? api.getSessionToken() : null; } catch (ignore) {}
242    if (staleReader && api && typeof api.logout === 'function') {
243      await api.logout();
244    }
245    return api.login();
246  }
247
248  function message(error) {
249    if (error && error.code === 'account_link_conflict') {
250      return 'This Ezoic account is already linked to a different Manuals+ account. Your current Manuals+ login was not changed.';
251    }
252    if (error && error.code === 'ezoic_identity_invalid') {
253      return 'Your email-link sign-in expired. Use Login with Email Link again to reconnect it safely.';
254    }
255    return 'The Ezoic account link could not be verified. Your existing Manuals+ login was not changed.';
256  }
257
258  window.ManualsEzoicAccountLink = {ready: ensureEzAuth, credentials: credentials, sync: sync, login: login, message: message};
259}(window));

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.