@monetize.software/sdk 3.0.0-alpha.20 → 3.0.0-alpha.21
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/chunks/{PaywallUI-BXEOgPTK.js → PaywallUI-BJKIG_oT.js} +315 -315
- package/dist/chunks/PaywallUI-BJKIG_oT.js.map +1 -0
- package/dist/chunks/PaywallUI-C2aGYQ7I.js +26 -0
- package/dist/chunks/PaywallUI-C2aGYQ7I.js.map +1 -0
- package/dist/chunks/index-CLB1AgLg.js +2074 -0
- package/dist/chunks/index-CLB1AgLg.js.map +1 -0
- package/dist/chunks/index-CzDSBl4d.js +2 -0
- package/dist/chunks/index-CzDSBl4d.js.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +17 -2066
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +17 -17
- package/dist/ui.cjs +1 -1
- package/dist/ui.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/PaywallUI-BXEOgPTK.js.map +0 -1
- package/dist/chunks/PaywallUI-Cybo6wdO.js +0 -26
- package/dist/chunks/PaywallUI-Cybo6wdO.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";class r extends Error{constructor(t,e,s={}){super(e),this.name="PaywallError",this.code=t,this.status=s.status,this.cause=s.cause}}class K extends r{constructor(t){super("not_enough_queries",t.message??"Not enough queries",{status:402}),this.name="QuotaExceededError",this.balances=t.balances,this.queryType=t.queryType,this.currentBalance=t.currentBalance}}const g="3.0.0-alpha.0";class b{constructor(t){this.opts=t}async request(t,e={}){const s=new URL(t,this.opts.apiOrigin).toString(),a=this.opts.fetch??fetch,n=new Headers(e.headers);n.set("Accept","application/json"),n.set("X-SDK-Version",g),n.set("X-Paywall-Id",this.opts.paywallId),this.opts.capabilities?.length&&n.set("X-SDK-Capabilities",this.opts.capabilities.join(","));const o=await this.opts.getAuthToken?.();o&&n.set("Authorization",`Bearer ${o}`);const d=typeof FormData<"u"&&e.body instanceof FormData;e.body&&!n.has("Content-Type")&&!d&&n.set("Content-Type","application/json");let f;try{f=await a(s,{...e,headers:n,credentials:"omit"})}catch(h){throw(h&&typeof h=="object"&&"name"in h?h.name:void 0)==="AbortError"?new r("aborted","Request aborted",{cause:h}):new r("network_error","Network request failed",{cause:h})}const l=(f.headers.get("content-type")??"").includes("application/json")?await f.json().catch(()=>null):null;if(!f.ok){const h=l&&typeof l=="object"&&"code"in l&&String(l.code)||`http_${f.status}`,w=l&&typeof l=="object"&&"message"in l&&String(l.message)||f.statusText||"Request failed";throw new r(h,w,{status:f.status,cause:l})}return l}}class N{constructor(t){if(!t.paywallId)throw new r("invalid_config","paywallId is required");if(!t.apiOrigin)throw new r("invalid_config","apiOrigin is required. Pass the paywall custom_domain configured in the platform.");this.paywallId=t.paywallId,this.apiOrigin=t.apiOrigin,this.auth=t.auth,this.userId=t.userId,this.capabilities=t.capabilities,this.customFetch=t.fetch,this.onChargeSuccess=t.onChargeSuccess,this.onQuotaExceeded=t.onQuotaExceeded,t.userId&&!t.auth&&typeof window<"u"&&typeof window.document<"u"&&console.warn("[paywall] WARNING: ApiGatewayClient.userId set without auth in browser. Client can spoof userId. Use AuthClient + Bearer for trusted user.id.")}async call(t){const e=t.path?t.path.replace(/^\/+/,""):"",s=new URL(`/api/v1/api-gateway/${encodeURIComponent(t.providerId)}${e?`/${e}`:""}`,this.apiOrigin);s.searchParams.set("paywall_id",this.paywallId);const a=new Headers(t.headers);a.set("X-SDK-Version",g),a.set("X-Paywall-Id",this.paywallId),this.capabilities?.length&&a.set("X-SDK-Capabilities",this.capabilities.join(","));const n=await this.auth?.getAccessToken();n?a.set("Authorization",`Bearer ${n}`):this.userId&&a.set("X-User-ID",this.userId);const o=typeof FormData<"u"&&t.body instanceof FormData,d=typeof Blob<"u"&&t.body instanceof Blob,f=typeof ReadableStream<"u"&&t.body instanceof ReadableStream,p=typeof t.body=="string";let c;t.body===void 0||t.body===null?c=void 0:o||d||f||p?c=t.body:(c=JSON.stringify(t.body),a.has("Content-Type")||a.set("Content-Type","application/json"));const l=this.customFetch??fetch;let h;try{h=await l(s.toString(),{method:t.method??"POST",headers:a,body:c,signal:t.signal,credentials:"omit"})}catch(y){const F=y instanceof Error?y.message:String(y);throw new r("network_error",`Network request failed: ${F}`,{cause:y})}if(h.status===402){const y=await M(h);throw this.onQuotaExceeded?.(y),y}if(!h.ok){const y=await x(h.clone());throw new r(y??`http_${h.status}`,h.statusText||"Gateway request failed",{status:h.status})}const w=h.headers.get("X-Query-Type")??void 0;return this.onChargeSuccess?.(w),h}}async function M(i){let t={};try{t=await i.json()}catch{}const e=t.details?.balances;let s=[];if(Array.isArray(e)){const a=e[0];Array.isArray(a)?s=a:a&&Array.isArray(a.balances)&&(s=a.balances)}return new K({balances:s,queryType:t.details?.queryType??"",currentBalance:t.details?.currentBalance??null})}async function x(i){if(!(i.headers.get("content-type")??"").includes("application/json"))return null;try{const e=await i.json();return e.code||e.error||null}catch{return null}}function J(){return typeof chrome<"u"&&!!chrome?.storage?.local&&!!chrome?.runtime?.id}const V={getItem(i){return new Promise(t=>{chrome.storage.local.get([i],e=>{const s=e[i];t(typeof s=="string"?s:null)})})},setItem(i,t){return new Promise(e=>{chrome.storage.local.set({[i]:t},()=>e())})},removeItem(i){return new Promise(t=>{chrome.storage.local.remove([i],()=>t())})},watch(i,t){const e=chrome?.storage?.onChanged;if(!e)return()=>{};const s=(a,n)=>{if(n!=="local")return;const o=a[i];o&&t(typeof o.newValue=="string"?o.newValue:null)};return e.addListener(s),()=>e.removeListener(s)}},H={async getItem(i){try{return window.localStorage.getItem(i)}catch{return null}},async setItem(i,t){try{window.localStorage.setItem(i,t)}catch{}},async removeItem(i){try{window.localStorage.removeItem(i)}catch{}},watch(i,t){if(typeof window>"u")return()=>{};const e=s=>{s.storageArea===window.localStorage&&s.key===i&&t(s.newValue)};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}},I=new Map,j={async getItem(i){return I.get(i)??null},async setItem(i,t){I.set(i,t)},async removeItem(i){I.delete(i)}};function _(i){return i||(J()?V:typeof window<"u"&&"localStorage"in window?H:j)}const u={visitorId:"pw-visitor-id",lastLoginMethod:i=>`pw-${i}-last-login-method`,lastLoginEmail:i=>`pw-${i}-last-login-email`,userState:(i,t)=>`pw-${i}-${t}-user-v1`,authSession:i=>`pw-${i}-auth-v1`,anonRefreshToken:i=>`pw-${i}-anon-rt-v1`,bootstrap:i=>`pw-${i}-bootstrap-v1`,balances:(i,t)=>`pw-${i}-${t}-balances-v1`};function B(){const i=typeof globalThis<"u"?globalThis.crypto:void 0;if(i&&typeof i.randomUUID=="function")return i.randomUUID();const t=new Uint8Array(16);if(i&&typeof i.getRandomValues=="function")i.getRandomValues(t);else for(let s=0;s<16;s++)t[s]=Math.floor(Math.random()*256);t[6]=t[6]&15|64,t[8]=t[8]&63|128;const e=Array.from(t,s=>s.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}async function v(i){try{const e=await i.getItem(u.visitorId);if(e&&typeof e=="string"&&e.length>=16)return e}catch{}const t=B();try{await i.setItem(u.visitorId,t)}catch{}return t}const G=5e3,X=30*6e4,T=60*6e4,z=5*6e4,S={has_active_subscription:!1,purchases:[],trial:null,had_previous_trial:!1};function O(i){return i&&(i.email||i.userId||i.anonymousId)||"guest"}function Q(i,t){return i===t?!0:!i||!t?!1:JSON.stringify(i)===JSON.stringify(t)}const W=5e3,U=5*6e4,Y=3e4;function Z(i,t){if(i===t)return!0;if(!i||!t||i.length!==t.length)return!1;for(let e=0;e<i.length;e++)if(i[e].type!==t[e].type||i[e].count!==t[e].count)return!1;return!0}class tt{constructor(t){if(this.cachedBootstrap=null,this.cachedBootstrapAt=0,this.inflightBootstrap=null,this.bootstrapListeners=new Set,this.bootstrapStorageUnwatch=null,this.authUnsubscribe=null,this.cachedUser=null,this.cachedUserAt=0,this.inflightUser=null,this.userListeners=new Set,this.visitorIdPromise=null,this.visitorId=null,this.inflightCheckouts=new Map,this.cachedBalances=null,this.cachedBalancesAt=0,this.balancesStorageUnwatch=null,this.inflightBalances=null,this.balanceListeners=new Set,this.previewVersionCounter=0,!t.paywallId)throw new r("invalid_config","paywallId is required");if(!t.apiOrigin)throw new r("invalid_config",'apiOrigin is required. Pass the paywall custom_domain configured in the platform (e.g. "https://pay.your-domain.com"). The legacy "appbox.space" fallback is not used in SDK 3.0.');this.paywallId=t.paywallId,this.apiOrigin=t.apiOrigin,this.capabilities=t.capabilities,this.auth=t.auth,this.previewMode=t.preview===!0;const e=t.auth?.getCachedUser();this.identity=t.identity??(e?k(e):void 0),this.apiKey=t.apiKey,this.fetchImpl=t.fetch,t.apiKey&&typeof window<"u"&&typeof window.document<"u"&&console.error("[paywall] SECURITY: BillingClient.apiKey detected in browser context. This is a server-SDK key and exposes your account. Remove apiKey or move BillingClient to a trusted backend."),this.storage=_(t.storage),this.api=new b({apiOrigin:this.apiOrigin,paywallId:t.paywallId,capabilities:t.capabilities,fetch:t.fetch,getAuthToken:t.auth?()=>t.auth.getAccessToken():void 0}),t.auth&&(this.authUnsubscribe=t.auth.onAuthChange((s,a)=>{const n=a?k(a.user):void 0;et(this.identity,n)||this.setIdentity(n)})),this.hydrateUserFromStorage(),this.hydrateBootstrapFromStorage(),this.subscribeBootstrapStorage(),this.hydrateBalancesFromStorage(),this.subscribeBalancesStorage(),this.visitorIdPromise=v(this.storage).then(s=>(this.visitorId=s,s))}async getVisitorId(){return this.visitorId?this.visitorId:(this.visitorIdPromise||(this.visitorIdPromise=v(this.storage).then(t=>(this.visitorId=t,t))),this.visitorIdPromise)}getCachedVisitorId(){return this.visitorId}setIdentity(t){this.identity=t,this.cachedUser=null,this.cachedUserAt=0,this.inflightUser=null,this.cachedBalances=null,this.cachedBalancesAt=0,this.inflightBalances=null,this.balancesStorageUnwatch&&(this.balancesStorageUnwatch(),this.balancesStorageUnwatch=null),this.hydrateBalancesFromStorage(),this.subscribeBalancesStorage(),this.hydrateUserFromStorage(),t?this.getUser({force:!0}).catch(()=>{}):(this.applyUser(S),this.applyBalances([]))}destroy(){this.authUnsubscribe&&(this.authUnsubscribe(),this.authUnsubscribe=null),this.bootstrapStorageUnwatch&&(this.bootstrapStorageUnwatch(),this.bootstrapStorageUnwatch=null),this.balancesStorageUnwatch&&(this.balancesStorageUnwatch(),this.balancesStorageUnwatch=null),this.userListeners.clear(),this.balanceListeners.clear(),this.bootstrapListeners.clear()}getIdentity(){return this.identity}getStorage(){return this.storage}async bootstrap(t=!1){const e=typeof t=="boolean"?{force:t}:t;if(this.previewMode){if(this.cachedBootstrap)return this.cachedBootstrap;throw new r("invalid_config","BillingClient in preview mode but cachedBootstrap is not seeded. Call setBootstrap(bootstrap) before open().")}const s=Date.now(),a=this.cachedBootstrap&&this.cachedBootstrapAt>0&&s-this.cachedBootstrapAt<T;return!e.force&&a?(s-this.cachedBootstrapAt>z&&this.revalidateBootstrap(e.signal).catch(()=>{}),{...this.cachedBootstrap,user:this.cachedUser??void 0}):this.inflightBootstrap?this.inflightBootstrap:(this.inflightBootstrap=this.fetchBootstrap({ifVersion:e.force?void 0:this.cachedBootstrap?.version,signal:e.signal}).finally(()=>{this.inflightBootstrap=null}),this.inflightBootstrap)}onBootstrapChange(t){return this.bootstrapListeners.add(t),()=>{this.bootstrapListeners.delete(t)}}setBootstrap(t){const e=this.cachedBootstrap??{settings:{id:this.paywallId,name:""},prices:[],offers:[]},s={...e,...t,settings:t.settings!==void 0?{...e.settings,...t.settings}:e.settings,prices:t.prices!==void 0?t.prices:e.prices,offers:t.offers!==void 0?t.offers:e.offers,version:`preview:${++this.previewVersionCounter}`};s.layout||(s.layout=L(s.settings,s.prices)),m(s),this.cachedBootstrap=s,this.cachedBootstrapAt=Date.now();for(const a of this.bootstrapListeners)try{a(s)}catch(n){console.warn("[paywall] onBootstrapChange listener threw",n)}}async fetchBootstrap(t){const e={};this.identity?.email&&(e["X-User-Email"]=this.identity.email);const s=t.ifVersion?`/api/v1/paywall/${this.paywallId}/bootstrap?if_version=${encodeURIComponent(t.ifVersion)}`:`/api/v1/paywall/${this.paywallId}/bootstrap`,a=await this.api.request(s,{...Object.keys(e).length?{headers:e}:{},signal:t.signal});if("unchanged"in a&&a.unchanged)return this.cachedBootstrap?(this.cachedBootstrapAt=Date.now(),a.user&&this.applyUser(a.user),this.cachedBootstrap):this.fetchBootstrap({signal:t.signal});const n=a;return st(n.settings.custom_domain,this.apiOrigin),n.layout||(n.layout=L(n.settings,n.prices)),m(n),this.applyBootstrap(n,{persist:!0}),n.user&&this.applyUser(n.user),n}revalidateBootstrap(t){return this.inflightBootstrap?this.inflightBootstrap:(this.inflightBootstrap=this.fetchBootstrap({ifVersion:this.cachedBootstrap?.version,signal:t}).finally(()=>{this.inflightBootstrap=null}),this.inflightBootstrap)}applyBootstrap(t,{persist:e}){const s=!this.cachedBootstrap||this.cachedBootstrap.version!==t.version;if(this.cachedBootstrap=t,this.cachedBootstrapAt=Date.now(),e&&this.persistBootstrap(t),s)for(const a of this.bootstrapListeners)try{a(t)}catch(n){console.warn("[paywall] onBootstrapChange listener threw",n)}}async hydrateBootstrapFromStorage(){if(!this.cachedBootstrap)try{const t=await this.storage.getItem(u.bootstrap(this.paywallId));if(!t)return;const e=JSON.parse(t);if(!e?.bootstrap||Date.now()-e.at>T||this.cachedBootstrap)return;m(e.bootstrap),this.cachedBootstrap=e.bootstrap,this.cachedBootstrapAt=e.at;for(const s of this.bootstrapListeners)try{s(e.bootstrap)}catch(a){console.warn("[paywall] onBootstrapChange listener threw",a)}}catch{}}async persistBootstrap(t){if(t.version)try{const{user:e,...s}=t;await this.storage.setItem(u.bootstrap(this.paywallId),JSON.stringify({at:Date.now(),bootstrap:s}))}catch{}}subscribeBootstrapStorage(){typeof this.storage.watch=="function"&&(this.bootstrapStorageUnwatch=this.storage.watch(u.bootstrap(this.paywallId),t=>{if(t)try{const e=JSON.parse(t);if(!e?.bootstrap)return;if(this.cachedBootstrap?.version&&this.cachedBootstrap.version===e.bootstrap.version){this.cachedBootstrapAt=e.at;return}m(e.bootstrap),this.applyBootstrap(e.bootstrap,{persist:!1})}catch{}}))}getCachedBootstrap(){return this.cachedBootstrap}async getPrices(t={}){return(await this.bootstrap(t)).prices}getCachedPrices(){return this.cachedBootstrap?.prices??null}getCachedOffers(){return this.cachedBootstrap?.offers??null}getUserLanguage(){const t=typeof navigator<"u"&&navigator.language?navigator.language:null,e=this.cachedBootstrap?.settings.locale_default??null,s=this.cachedBootstrap?P(this.cachedBootstrap):null;return{tag:s??t??e,applied:s,browserLanguage:t,countryLanguage:e}}async getUser({force:t=!1,signal:e}={}){return!t&&this.cachedUser&&Date.now()-this.cachedUserAt<G?this.cachedUser:this.inflightUser?this.inflightUser:(this.inflightUser=(async()=>{try{if(!this.identity?.email)return this.applyUser(S),S;const s=await this.api.request(`/api/v1/paywall/${this.paywallId}/user-state`,{headers:{"X-User-Email":this.identity.email},signal:e});return this.applyUser(s),s}finally{this.inflightUser=null}})(),this.inflightUser)}onUserChange(t,e={}){this.userListeners.add(t);const s=e.immediate??"microtask";if(this.cachedUser&&s!=="none"){const a=this.cachedUser;if(s==="sync")try{t(a)}catch(n){console.warn("[paywall] onUserChange initial sync threw",n)}else queueMicrotask(()=>{this.userListeners.has(t)&&t(a)})}return()=>{this.userListeners.delete(t)}}getCachedUser(){return this.cachedUser}applyUser(t){const e=!Q(this.cachedUser,t);if(this.cachedUser=t,this.cachedUserAt=Date.now(),e){this.persistUser(t);for(const s of this.userListeners)try{s(t)}catch(a){console.warn("[paywall] onUserChange listener threw",a)}}}storageKey(){return u.userState(this.paywallId,O(this.identity))}async hydrateUserFromStorage(){if(!this.cachedUser)try{const t=await this.storage.getItem(this.storageKey());if(!t)return;const e=JSON.parse(t);if(!e?.user||Date.now()-e.at>X||this.cachedUser)return;this.applyUser(e.user)}catch{}}async persistUser(t){try{await this.storage.setItem(this.storageKey(),JSON.stringify({at:Date.now(),user:t}))}catch{}}async getBalances({force:t=!1,signal:e}={}){const s=Date.now(),a=this.cachedBalances?s-this.cachedBalancesAt:1/0;return!t&&this.cachedBalances&&(a<W||a<Y)?this.cachedBalances:!t&&this.cachedBalances&&a<U?(this.fetchBalances({signal:e}).catch(()=>{}),this.cachedBalances):this.inflightBalances?this.inflightBalances:this.fetchBalances({signal:e})}fetchBalances({signal:t}={}){return this.inflightBalances?this.inflightBalances:(this.inflightBalances=(async()=>{try{if(!this.auth)return this.applyBalances([]),[];const e=await this.api.request(`/api/v1/paywall/${this.paywallId}/balances`,{signal:t}),s=Array.isArray(e.balances)?e.balances:[];return this.applyBalances(s),s}finally{this.inflightBalances=null}})(),this.inflightBalances)}getCachedBalances(){return this.cachedBalances}onBalanceChange(t,e={}){this.balanceListeners.add(t);const s=e.immediate??"microtask";if(this.cachedBalances&&s!=="none"){const a=this.cachedBalances;if(s==="sync")try{t(a)}catch(n){console.warn("[paywall] onBalanceChange initial sync threw",n)}else queueMicrotask(()=>{this.balanceListeners.has(t)&&t(a)})}return()=>{this.balanceListeners.delete(t)}}decrementBalanceLocal(t){if(!t){this.getBalances({force:!0});return}if(!this.cachedBalances)return;const e=this.cachedBalances.findIndex(n=>n.type===t);if(e<0||this.cachedBalances[e].count<=0)return;const a=this.cachedBalances.map((n,o)=>o===e?{...n,count:n.count-1}:n);this.applyBalances(a)}refreshBalances(){return this.getBalances({force:!0})}createApiGatewayClient(t={}){const e=t.onChargeSuccess,s=t.onQuotaExceeded;return new N({paywallId:this.paywallId,apiOrigin:this.apiOrigin,auth:this.auth,userId:this.auth?void 0:this.identity?.userId,capabilities:this.capabilities,fetch:this.fetchImpl,...t,onChargeSuccess:a=>{this.decrementBalanceLocal(a),e?.(a)},onQuotaExceeded:a=>{this.refreshBalances(),s?.(a)}})}applyBalances(t,{persist:e=!0}={}){const s=!Z(this.cachedBalances,t);if(this.cachedBalances=t,this.cachedBalancesAt=Date.now(),e&&this.persistBalances(t),s)for(const a of this.balanceListeners)try{a(t)}catch(n){console.warn("[paywall] onBalanceChange listener threw",n)}}balancesStorageKey(){return u.balances(this.paywallId,O(this.identity))}async hydrateBalancesFromStorage(){if(!this.cachedBalances)try{const t=await this.storage.getItem(this.balancesStorageKey());if(!t)return;const e=JSON.parse(t);if(!e?.balances||!Array.isArray(e.balances)||Date.now()-e.at>U||this.cachedBalances)return;this.cachedBalances=e.balances,this.cachedBalancesAt=e.at;for(const s of this.balanceListeners)try{s(e.balances)}catch(a){console.warn("[paywall] onBalanceChange listener threw",a)}}catch{}}async persistBalances(t){try{await this.storage.setItem(this.balancesStorageKey(),JSON.stringify({at:Date.now(),balances:t}))}catch{}}subscribeBalancesStorage(){typeof this.storage.watch=="function"&&(this.balancesStorageUnwatch=this.storage.watch(this.balancesStorageKey(),t=>{if(t)try{const e=JSON.parse(t);if(!e?.balances||!Array.isArray(e.balances)||e.at<=this.cachedBalancesAt)return;this.applyBalances(e.balances,{persist:!1})}catch{}}))}async createCheckout(t){if(!this.identity?.email)throw new r("identity_required","createCheckout requires identity with email");const e=t.idempotencyKey??`auto:${t.priceId}`,s=this.inflightCheckouts.get(e);if(s)return s;const n={"Idempotency-Key":t.idempotencyKey??B()};this.apiKey&&(n["X-Api-Key"]=this.apiKey);const o=this.cachedBootstrap?.settings,d=t.successUrl??o?.success_redirect_url??void 0,f=t.shopUrl??o?.checkout_shop_url??void 0,c=this.cachedBootstrap?.prices.find(h=>h.id===t.priceId)?.local?.currency??void 0,l=this.api.request(`/api/v1/paywall/${this.paywallId}/start-checkout`,{method:"POST",headers:n,signal:t.signal,body:JSON.stringify({email:this.identity.email,priceId:Number(t.priceId),offerId:t.offerId,successUrl:d,errorUrl:t.errorUrl,shopUrl:f,productName:o?.checkout_product_name??void 0,trial_days:t.trialDays,ignoreActivePurchase:t.ignoreActivePurchase?!0:void 0,userMeta:this.identity.userId?{userId:this.identity.userId}:void 0,localCurrency:c})}).then(h=>({url:h.checkoutUrl,acquiring:h.acquiring})).catch(h=>{throw h instanceof r&&h.status===409&&h.cause&&typeof h.cause=="object"&&h.cause.hasActivePurchase===!0?new r("already_purchased","You already have an active subscription",{status:409,cause:h.cause}):h});return this.inflightCheckouts.set(e,l),l.finally(()=>{this.inflightCheckouts.get(e)===l&&this.inflightCheckouts.delete(e)}).catch(()=>{}),l}async getCustomerPortalUrl(t={}){if(!this.auth&&!this.apiKey&&!this.identity?.email)throw new r("identity_required","getCustomerPortalUrl requires auth, apiKey, or identity.email");const e={};this.apiKey&&(e["X-Api-Key"]=this.apiKey);const s=this.auth&&this.auth.getCachedSession()?{returnUrl:t.returnUrl}:{email:this.identity?.email,userMeta:this.identity?.userId?{userId:this.identity.userId}:void 0,returnUrl:t.returnUrl};return{url:(await this.api.request(`/api/v1/paywall/${this.paywallId}/get-customer-portal`,{method:"POST",headers:Object.keys(e).length?e:void 0,body:JSON.stringify(s),signal:t.signal})).url}}async listPurchases(t={}){const e=!!(this.identity?.email||this.identity?.userId);if(!this.auth&&!(this.apiKey&&e))throw new r("identity_required","listPurchases requires AuthClient (Bearer) or apiKey + identity.email/userId");const s={};this.apiKey&&(s["X-Api-Key"]=this.apiKey);const a=new URLSearchParams;this.apiKey&&this.identity?.email&&a.set("email",this.identity.email),this.apiKey&&this.identity?.userId&&a.set("user_id",this.identity.userId);const n=a.toString(),o=n?`/api/v1/paywall/${this.paywallId}/user?${n}`:`/api/v1/paywall/${this.paywallId}/user`;return(await this.api.request(o,{method:"GET",headers:s,signal:t.signal})).purchases??[]}async cancelSubscription(t){const e=!!(this.identity?.email||this.identity?.userId);if(!this.auth&&!(this.apiKey&&e))throw new r("identity_required","cancelSubscription requires AuthClient (Bearer) or apiKey + identity.email/userId");const s={};this.apiKey&&(s["X-Api-Key"]=this.apiKey);const a={subscriptionId:t.subscriptionId,paywallId:this.paywallId,cancellationReason:t.reason};return this.apiKey&&this.identity?.email&&(a.email=this.identity.email),this.apiKey&&this.identity?.userId&&(a.userId=this.identity.userId),this.api.request("/api/paywall/cancel-subscription",{method:"POST",headers:s,body:JSON.stringify(a),signal:t.signal})}async createSupportTicket(t){const e=t.email??this.identity?.email??null,s=`/api/v1/paywall/${this.paywallId}/support/ticket`;if(!!t.files&&t.files.length>0){const n=new FormData;n.set("subject",t.subject),n.set("content",t.content),e&&n.set("customer_email",e);for(const o of t.files)n.append("files",o);return this.api.request(s,{method:"POST",body:n})}return this.api.request(s,{method:"POST",body:JSON.stringify({subject:t.subject,content:t.content,customer_email:e})})}}function k(i){return{email:i.email,userId:i.id}}function et(i,t){return i===t?!0:!i||!t?!1:i.email===t.email&&i.userId===t.userId&&i.anonymousId===t.anonymousId}function E(i){if(!i)return null;const t=i.trim();if(!t)return null;try{return new URL(t.includes("://")?t:`https://${t}`).origin}catch{return null}}function st(i,t){const e=E(i);if(!(!e||E(t)===e))throw new r("invalid_config",`apiOrigin mismatch: SDK initialized with "${t}" but paywall is configured with custom_domain "${i}". Use the custom_domain from the platform paywall settings.`)}function L(i,t){return{type:"modal",blocks:[{type:"heading",text:i.name||"Upgrade",level:1},{type:"price_grid",priceIds:t.map(e=>e.id)},{type:"cta_button",action:"checkout"},{type:"guarantee_badge"},{type:"current_session"}]}}function P(i){const t=i.locales;if(!t)return null;const e=[];if(typeof navigator<"u"){navigator.language&&e.push(navigator.language);const a=navigator.language?.split("-")[0];a&&a!==navigator.language&&e.push(a)}const s=i.settings.locale_default;s&&e.push(s);for(const a of e)if(a&&Object.prototype.hasOwnProperty.call(t,a))return a;return null}function m(i){const t=P(i);if(!t)return;const e=i.locales?.[t];e&&(e.layout&&(i.layout=e.layout),e.prices&&(i.prices=i.prices.map(s=>{const a=e.prices?.[s.id];if(!a)return s;const n={...s};return"label"in a&&(n.label=a.label??null),"description"in a&&(n.description=a.description??null),n})))}function R(i){const t=new Uint8Array(i),e=typeof globalThis<"u"?globalThis.crypto:void 0;if(e&&typeof e.getRandomValues=="function")e.getRandomValues(t);else for(let s=0;s<i;s++)t[s]=Math.floor(Math.random()*256);return t}function A(i){let t="";for(let e=0;e<i.length;e++)t+=String.fromCharCode(i[e]);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function it(){return A(R(64))}async function at(i){const t=new TextEncoder().encode(i),e=globalThis.crypto;if(!e?.subtle?.digest)throw new Error("crypto.subtle is required for PKCE");const s=await e.subtle.digest("SHA-256",t);return A(new Uint8Array(s))}function nt(){return A(R(16))}const rt=6e4,ot=600*1e3;class ht{constructor(t){if(this.session=null,this.inflightRefresh=null,this.inflightAnonSignin=null,this.listeners=new Set,this.storageUnwatch=null,this.destroyed=!1,this.oauthFlows=new Map,!t.paywallId)throw new r("invalid_config","paywallId is required");if(!t.apiOrigin)throw new r("invalid_config","apiOrigin is required. Pass the paywall custom_domain configured in the platform.");this.paywallId=t.paywallId,this.apiOrigin=t.apiOrigin,this.storage=_(t.storage),this.api=new b({apiOrigin:this.apiOrigin,paywallId:t.paywallId,fetch:t.fetch}),this.openPopup=t.openPopup??((e,s)=>typeof window>"u"?null:window.open(e,s,"width=480,height=640,popup=yes")),this.hydrated=this.hydrate(),this.startStorageWatch()}startStorageWatch(){typeof this.storage.watch=="function"&&(this.storageUnwatch=this.storage.watch(this.storageKey(),t=>{this.applyExternalSession(t)}))}async applyExternalSession(t){if(!this.destroyed&&(await this.hydrated,!this.destroyed)){if(t==null){this.session&&this.setSession(null,{skipPersist:!0,event:"SIGNED_OUT"});return}try{const e=JSON.parse(t);if(!e||typeof e.access_token!="string"||typeof e.refresh_token!="string"||typeof e.expires_at!="number"||!e.user)return;const s=!this.session||this.session.user.id!==e.user.id?"SIGNED_IN":"TOKEN_REFRESHED";this.setSession(e,{skipPersist:!0,event:s})}catch{}}}ready(){return this.hydrated}getCachedSession(){return this.session}getCachedUser(){return this.session?.user??null}async getAccessToken(){if(await this.hydrated,!this.session&&(await this.rehydrateFromStorage(),!this.session))return null;if(this.isFresh(this.session))return this.session.access_token;try{return(await this.refresh())?.access_token??null}catch{return this.session?.access_token??null}}async signInWithEmail(t){await this.hydrated;const e=await this.readVisitorId(),s={};t.idempotencyKey&&(s["Idempotency-Key"]=t.idempotencyKey);const a=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/email/signin`,{method:"POST",headers:Object.keys(s).length?s:void 0,body:JSON.stringify({email:t.email,password:t.password,visitor_id:e,user_meta:t.userMeta})}),n=this.toSession(a,a.user);return this.setSession(n,{event:"SIGNED_IN"}),this.recordLastLogin("email",t.email),n}async signUp(t){await this.hydrated;const e=await this.readVisitorId(),s={};t.idempotencyKey&&(s["Idempotency-Key"]=t.idempotencyKey);const a=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/email/signup`,{method:"POST",headers:Object.keys(s).length?s:void 0,body:JSON.stringify({email:t.email,password:t.password,visitor_id:e,user_meta:t.userMeta})});if(a.status==="confirmation_required")return this.recordLastLogin("email",t.email),{kind:"confirmation_required",user:a.user};const n=this.toSession(a,a.user);return this.setSession(n,{event:"SIGNED_IN"}),this.recordLastLogin("email",t.email),{kind:"signed_in",session:n}}async resendConfirmation(t){await this.hydrated;const e={};t.idempotencyKey&&(e["Idempotency-Key"]=t.idempotencyKey),await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/email/resend`,{method:"POST",headers:Object.keys(e).length?e:void 0,body:JSON.stringify({email:t.email})})}async sendOtp(t){await this.hydrated,await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/otp/send`,{method:"POST",body:JSON.stringify({email:t.email,create_user:t.createUser??!0,user_meta:t.userMeta})})}async verifyOtp(t){await this.hydrated;const e=await this.readVisitorId(),s=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/otp/verify`,{method:"POST",body:JSON.stringify({email:t.email,token:t.token,type:t.type??"email",visitor_id:e,user_meta:t.userMeta})}),a=this.toSession(s,s.user),n=t.type==="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN";return this.setSession(a,{event:n}),a}async requestPasswordReset(t){await this.hydrated,await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/password/request-reset`,{method:"POST",body:JSON.stringify({email:t.email})})}async updatePassword(t){await this.hydrated;const e=await this.getAccessToken();if(!e)throw new r("not_authenticated","no active session");await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/password/update`,{method:"POST",headers:{Authorization:`Bearer ${e}`},body:JSON.stringify({password:t.password})})}async signInAnonymously(t={}){if(this.inflightAnonSignin)return this.inflightAnonSignin;this.inflightAnonSignin=(async()=>{if(await this.hydrated,!t.forceNewAnon&&this.session?.user.is_anonymous===!0)return this.session;if(!t.forceNewAnon){const o=await this.resumeAnonymous();if(o)return o}const e=await this.readVisitorId(),s=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/anonymous/signin`,{method:"POST",body:JSON.stringify({...t.captchaToken?{captcha_token:t.captchaToken}:{},visitor_id:e,user_meta:t.userMeta})}),a={...s.user,email:s.user.email??null,is_anonymous:!0},n=this.toSession(s,a);return this.setSession(n,{event:"SIGNED_IN"}),await this.writeAnonRefreshToken(n.refresh_token),n})();try{return await this.inflightAnonSignin}finally{this.inflightAnonSignin=null}}async resumeAnonymous(){const t=await this.readAnonRefreshToken();if(!t)return null;try{const e=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/refresh`,{method:"POST",body:JSON.stringify({refresh_token:t})}),s=this.session?.user.is_anonymous===!0?this.session.user:{id:"",email:null,is_anonymous:!0},a=this.toSession(e,s);return this.setSession(a,{event:"SIGNED_IN"}),await this.writeAnonRefreshToken(a.refresh_token),a}catch(e){if(e instanceof r&&e.status===401)return await this.clearAnonRefreshToken(),null;throw e}}async upgradeAnonymousToEmail(t){await this.hydrated;const e=await this.getAccessToken();if(!e)throw new r("not_authenticated","no active session");const s={Authorization:`Bearer ${e}`};t.idempotencyKey&&(s["Idempotency-Key"]=t.idempotencyKey);const a=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/anonymous/upgrade`,{method:"POST",headers:s,body:JSON.stringify({email:t.email,password:t.password,user_meta:t.userMeta})});if(a.status==="confirmation_required")return{kind:"confirmation_required",email:a.email};const n=this.session;if(!n)throw new r("not_authenticated","session disappeared during upgrade");const o={...n.user,id:a.user.id,email:a.user.email,is_anonymous:a.user.is_anonymous??!1},d={...n,user:o};return this.setSession(d,{event:"USER_UPDATED"}),await this.clearAnonRefreshToken(),{kind:"updated",session:d}}async signInWithOAuth(t){if(typeof window>"u")throw new r("oauth_unavailable","window is required for OAuth");const{authorize_url:e,state:s}=await this.startOAuthFlow({provider:t.provider,scopes:t.scopes,userMeta:t.userMeta}),a=this.openPopup(e,`pw-oauth-${s}`);if(!a)throw this.oauthFlows.delete(s),new r("popup_blocked","browser blocked auth popup — call from a user gesture");t.onPopupOpened?.();const n=await ut(a,s);if(this.destroyed)throw this.oauthFlows.delete(s),new r("aborted","AuthClient destroyed mid-flow");return this.completeOAuthFlow({state:s,code:n})}async startOAuthFlow(t){await this.hydrated,this.gcOAuthFlows();const e=it(),s=await at(e),a=nt(),n={},o=await this.getAccessToken().catch(()=>null);o&&(n.Authorization=`Bearer ${o}`);const{authorize_url:d}=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/oauth/init`,{method:"POST",headers:Object.keys(n).length?n:void 0,body:JSON.stringify({provider:t.provider,code_challenge:s,code_challenge_method:"s256",scopes:t.scopes})});return this.oauthFlows.set(a,{verifier:e,userMeta:t.userMeta,provider:t.provider,startedAt:Date.now()}),this.recordLastLoginMethod(t.provider),{authorize_url:d,state:a}}async completeOAuthFlow(t){await this.hydrated;const e=this.oauthFlows.get(t.state);if(!e)throw new r("oauth_invalid_state","OAuth flow not found — start with startOAuthFlow first or check TTL");this.oauthFlows.delete(t.state);const s=await this.readVisitorId(),a=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/oauth/exchange`,{method:"POST",body:JSON.stringify({auth_code:t.code,code_verifier:e.verifier,visitor_id:s,user_meta:e.userMeta})});if(this.destroyed)throw new r("aborted","AuthClient destroyed mid-flow");const n=this.toSession(a,a.user);return this.setSession(n,{event:"SIGNED_IN"}),n.user.email&&this.recordLastLoginEmail(n.user.email),n}gcOAuthFlows(){const t=Date.now()-ot;for(const[e,s]of this.oauthFlows)s.startedAt<t&&this.oauthFlows.delete(e)}async refresh(){if(await this.hydrated,!this.session)return null;if(this.inflightRefresh)return this.inflightRefresh;const t=this.session.refresh_token,e=this.session.user;return this.inflightRefresh=(async()=>{try{const s=await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/refresh`,{method:"POST",body:JSON.stringify({refresh_token:t})}),a=this.toSession(s,e);return this.setSession(a,{event:"TOKEN_REFRESHED"}),e.is_anonymous===!0&&await this.writeAnonRefreshToken(a.refresh_token),a}catch(s){if(s instanceof r&&s.status===401)return e.is_anonymous===!0&&await this.clearAnonRefreshToken(),this.setSession(null,{event:"SIGNED_OUT"}),null;throw s}finally{this.inflightRefresh=null}})(),this.inflightRefresh}async revokeAllSessions(){await this.hydrated;const t=this.session?.access_token;if(!t)throw new r("not_authenticated","no active session");await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/revoke-all`,{method:"POST",headers:{Authorization:`Bearer ${t}`}}),this.setSession(null,{event:"SIGNED_OUT"})}async signOut(t={}){await this.hydrated;const e=this.session?.access_token,s=this.session?.user.is_anonymous===!0;if(this.setSession(null,{event:"SIGNED_OUT"}),t.forgetAnonymous&&await this.clearAnonRefreshToken(),!!e&&!(s&&!t.forgetAnonymous))try{await this.api.request(`/api/v1/paywall/${this.paywallId}/auth/signout`,{method:"POST",headers:{Authorization:`Bearer ${e}`}})}catch{}}onAuthChange(t){return this.listeners.add(t),this.hydrated.then(()=>{if(this.destroyed||!this.listeners.has(t))return;const e=this.session;try{t("INITIAL_SESSION",e)}catch(s){console.warn("[paywall] onAuthChange INITIAL_SESSION threw",s)}}),()=>{this.listeners.delete(t)}}isFresh(t){return t.expires_at-Date.now()>rt}toSession(t,e){const s=t.expires_at!=null?t.expires_at*1e3:Date.now()+t.expires_in*1e3;return{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:s,user:e}}setSession(t,e){if(this.destroyed)return;const s=this.session;this.session=t,e.skipPersist||this.persist(),ft(s,t)||this.emit(e.event)}emit(t){for(const e of this.listeners)try{e(t,this.session)}catch(s){console.warn("[paywall] onAuthChange listener threw",s)}}storageKey(){return u.authSession(this.paywallId)}async hydrate(){try{const t=await this.storage.getItem(this.storageKey());if(!t)return;const e=JSON.parse(t);if(!e||typeof e.access_token!="string"||typeof e.refresh_token!="string"||typeof e.expires_at!="number"||!e.user)return;this.session=e}catch{}}async rehydrateFromStorage(){try{const t=await this.storage.getItem(this.storageKey());if(!t)return;const e=JSON.parse(t);if(!e||typeof e.access_token!="string"||typeof e.refresh_token!="string"||typeof e.expires_at!="number"||!e.user)return;this.setSession(e,{skipPersist:!0,event:"SIGNED_IN"})}catch{}}destroy(){this.destroyed=!0,this.storageUnwatch&&(this.storageUnwatch(),this.storageUnwatch=null),this.listeners.clear(),this.inflightRefresh=null}isDestroyed(){return this.destroyed}async persist(){try{this.session?await this.storage.setItem(this.storageKey(),JSON.stringify(this.session)):await this.storage.removeItem(this.storageKey())}catch{}}async readAnonRefreshToken(){try{const t=await this.storage.getItem(u.anonRefreshToken(this.paywallId));return typeof t=="string"&&t.length>0?t:null}catch{return null}}async writeAnonRefreshToken(t){try{await this.storage.setItem(u.anonRefreshToken(this.paywallId),t)}catch{}}async clearAnonRefreshToken(){try{await this.storage.removeItem(u.anonRefreshToken(this.paywallId))}catch{}}async getLastLogin(){try{const[t,e]=await Promise.all([this.storage.getItem(u.lastLoginMethod(this.paywallId)),this.storage.getItem(u.lastLoginEmail(this.paywallId))]);return!t||!dt(t)?null:{method:t,email:typeof e=="string"&&e?e:null}}catch{return null}}recordLastLogin(t,e){this.recordLastLoginMethod(t),e&&this.recordLastLoginEmail(e)}recordLastLoginMethod(t){this.storage.setItem(u.lastLoginMethod(this.paywallId),t).catch(()=>{})}recordLastLoginEmail(t){this.storage.setItem(u.lastLoginEmail(this.paywallId),t).catch(()=>{})}async readVisitorId(){try{const t=await this.storage.getItem(u.visitorId);return typeof t=="string"&&t.length>=16?t:void 0}catch{return}}}const ct=5*6e4,lt=500;function ut(i,t){return new Promise((e,s)=>{let a=!1;const n=()=>{a=!0,window.removeEventListener("message",o),clearInterval(d),clearTimeout(f)},o=p=>{if(a)return;const c=p.data;if(!(!c||c.type!=="pw-oauth")&&c.messageId===t){if(c.status==="success"&&c.code){n();try{i.close()}catch{}e(c.code)}else if(c.status==="error"){n();try{i.close()}catch{}s(new r("oauth_failed",c.description||c.error||"OAuth provider returned error"))}}},d=setInterval(()=>{if(a)return;let p;try{p=i.closed}catch{return}p&&(n(),s(new r("oauth_cancelled","auth popup was closed")))},lt),f=setTimeout(()=>{if(!a){n();try{i.close()}catch{}s(new r("oauth_timeout","OAuth flow timed out"))}},ct);window.addEventListener("message",o)})}function dt(i){return i==="google"||i==="apple"||i==="github"||i==="facebook"||i==="email"}function ft(i,t){return i===t?!0:!i||!t?!1:i.access_token===t.access_token&&i.refresh_token===t.refresh_token&&i.expires_at===t.expires_at&&i.user.id===t.user.id&&i.user.email===t.user.email}const yt=1500,pt=20,C=200;class gt{constructor(t){this.buffer=[],this.flushTimer=null,this.destroyed=!1,this.unloadHandler=null,this.visibilityHandler=null,this.opts=t,this.isEnabled()&&this.attachUnloadHandlers()}isEnabled(){return this.opts.enabled!==!1}track(t,e){if(this.destroyed||!this.isEnabled()||typeof t!="string"||t.length===0)return;this.buffer.push({type:t,ts:Date.now(),props:e});const s=this.opts.maxBufferSize??pt;if(this.buffer.length>=s){this.flush();return}this.buffer.length>C&&(this.buffer=this.buffer.slice(-C)),this.scheduleFlush()}scheduleFlush(){if(this.flushTimer||this.destroyed)return;const t=this.opts.flushIntervalMs??yt;this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush()},t)}async flush(){if(this.buffer.length===0)return;this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null);const t=this.buffer;this.buffer=[];try{const e=await this.opts.getVisitorId(),s=this.opts.getUserId?.()??null,a=JSON.stringify({events:t}),n=this.opts.fetch??(typeof fetch<"u"?fetch:void 0);if(!n)return;await n(this.opts.endpoint,{method:"POST",credentials:"omit",keepalive:!0,headers:this.buildHeaders(e,s),body:a})}catch{}}flushBeacon(){if(this.buffer.length===0)return;const t=this.buffer;this.buffer=[];const e=this.opts.getCachedVisitorId?.()??null,s=this.opts.getUserId?.()??null;if(!e){this.buffer.unshift(...t),this.flush();return}const a=JSON.stringify({events:t,visitor_id:e,user_id:s,sdk_version:g,paywall_id:this.opts.paywallId,capabilities:this.opts.capabilities?.join(",")??""}),n=this.opts.sendBeacon??(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"?navigator.sendBeacon.bind(navigator):null);if(!n){this.buffer.unshift(...t),this.flush();return}try{n(this.opts.endpoint,a)||(this.buffer.unshift(...t),this.flush())}catch{this.buffer.unshift(...t),this.flush()}}buildHeaders(t,e){const s={"Content-Type":"application/json","X-SDK-Version":g,"X-Paywall-Id":this.opts.paywallId,"X-Visitor-Id":t};return this.opts.capabilities?.length&&(s["X-SDK-Capabilities"]=this.opts.capabilities.join(",")),e&&(s["X-User-Id"]=e),s}attachUnloadHandlers(){typeof window>"u"||(this.unloadHandler=()=>this.flushBeacon(),this.visibilityHandler=()=>{typeof document<"u"&&document.visibilityState==="hidden"&&this.flushBeacon()},window.addEventListener("pagehide",this.unloadHandler),typeof document<"u"&&document.addEventListener("visibilitychange",this.visibilityHandler))}detachUnloadHandlers(){typeof window>"u"||(this.unloadHandler&&window.removeEventListener("pagehide",this.unloadHandler),this.visibilityHandler&&typeof document<"u"&&document.removeEventListener("visibilitychange",this.visibilityHandler),this.unloadHandler=null,this.visibilityHandler=null)}destroy(){this.destroyed||(this.destroyed=!0,this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.flush(),this.detachUnloadHandlers())}}function D(i){return`pw-offer-${i}-start`}function q(i,t){if(!i||i.length===0)return null;const e=i.find(a=>a.price_id===t&&(a.discount_percent??0)>0);return e||(i.find(a=>a.price_id==null&&(a.discount_percent??0)>0)??null)}function wt(i,t,e={}){const s=q(i,t);return s&&$(s,e)?s:null}function $(i,t={}){const e=i.discount_percent??0;if(e<=0)return null;const s=t.now??Date.now(),a=mt(i,t.readStart),n=It(i,a),o=a!==null?Math.max(0,a-s):null;return a!==null&&a<=s?null:{offer:i,discountPercent:e,remainingMs:o,totalMs:n,expiresAt:a}}function mt(i,t){if(i.expires_at){const e=Date.parse(i.expires_at);return Number.isFinite(e)?e:null}if(i.duration_minutes&&i.duration_minutes>0&&t){const e=t(i.id);if(!e)return null;const s=Date.parse(e);return Number.isFinite(s)?s+i.duration_minutes*6e4:null}return null}function It(i,t){return i.duration_minutes&&i.duration_minutes>0?i.duration_minutes*6e4:t!==null?t-Date.now():null}function St(i){if(typeof window>"u")return null;try{return window.localStorage.getItem(D(i))}catch{return null}}exports.ApiClient=b;exports.ApiGatewayClient=N;exports.AuthClient=ht;exports.BillingClient=tt;exports.EventTracker=gt;exports.PaywallError=r;exports.QuotaExceededError=K;exports.SDK_VERSION=g;exports.STORAGE_KEYS=u;exports.createStorage=_;exports.ensureVisitorId=v;exports.findApplicableOffer=q;exports.findLiveOffer=wt;exports.generateVisitorId=B;exports.offerStartStorageKey=D;exports.readBrowserOfferStart=St;exports.resolveOffer=$;
|
|
2
|
+
//# sourceMappingURL=index-CzDSBl4d.js.map
|