@tinkerlandai/longplay-sdk 0.10.7 → 0.10.8
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/CHANGELOG.md +10 -1
- package/README.md +3 -3
- package/README.zh-CN.md +2 -2
- package/dist/{chunk-ZKSKBL4N.js → chunk-5ZS3TNC4.js} +1 -1
- package/dist/{chunk-22Z7JR4B.js → chunk-7XVAFQEE.js} +1 -1
- package/dist/{chunk-3OFRQUUI.js → chunk-CBVZUTNH.js} +1 -1
- package/dist/{chunk-O52OWKP7.js → chunk-DCV6IS2Z.js} +1 -1
- package/dist/chunk-EI2VRDYJ.js +1 -0
- package/dist/{chunk-I4BZSRT4.js → chunk-GJRXHH6G.js} +1 -1
- package/dist/chunk-R26BYN3U.js +1 -0
- package/dist/{chunk-Y3AGPHWF.js → chunk-RP2P3FU4.js} +1 -1
- package/dist/{chunk-IAOOTBJV.js → chunk-U4UEOR5W.js} +2 -2
- package/dist/{content-F7IVCK3I.js → content-XXVHMKKL.js} +1 -1
- package/dist/funnel-runtime-host-PBJ63LOE.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1 -1
- package/dist/native-shell.js +1 -1
- package/dist/openrouter.js +1 -1
- package/dist/page.js +1 -1
- package/dist/{paywall-XGDRMPLP.js → paywall-CDR4GZMX.js} +1 -1
- package/dist/react-native.js +1 -1
- package/dist/server.js +1 -1
- package/dist/visual.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-6LILLFH3.js +0 -1
- package/dist/chunk-SV6W2E2A.js +0 -1
- package/dist/funnel-runtime-host-W25OXLGE.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.8 — 2026-11-01
|
|
4
|
+
|
|
5
|
+
- Recover IAM entry background Waits and unknown starts after reload by replaying the original start request under the same Customer and build, without persisting credentials or allocating another Run.
|
|
6
|
+
|
|
7
|
+
- Start one IAM entry Run when a router renders a back/forward page before the host observes the popstate.
|
|
8
|
+
- Present automatic IAM entries at most once per visit; dismissing or completing a Run no longer starts another Funnel on the same page.
|
|
9
|
+
- Hide paused or timer/event-waiting entry Runs, report `run_background`, and let other entries take the page instead of showing bare controls.
|
|
10
|
+
- Reread an open page's visual experiment payload every 60 seconds while visible, so stopped experiments revert without a reload.
|
|
11
|
+
- Close a shown entry screen Run when the page unloads, the host is destroyed or the Customer changes, so a reload or account switch no longer suppresses that Funnel's entries until the Run expires.
|
|
12
|
+
|
|
3
13
|
## 0.10.7 — 2026-11-01
|
|
4
14
|
|
|
5
15
|
- Require the clicked node itself to remain the unique active IAM target; hidden or detached controls cannot borrow a replacement's anchor.
|
|
@@ -10,7 +20,6 @@
|
|
|
10
20
|
|
|
11
21
|
Only Longplay public factories, errors, types and browser globals are supported. Migrate old Indiana imports to their Longplay names. Internal implementations, protocol and saved identities are unchanged; previously published artifacts remain immutable.
|
|
12
22
|
|
|
13
|
-
|
|
14
23
|
## 0.10.5 — 2026-11-01
|
|
15
24
|
|
|
16
25
|
- Make IAM Funnel entries recover from configuration timeouts, delayed scene changes, hidden retained pages and earlier refused entries; recheck the selected scene before mounting a Run.
|
package/README.md
CHANGED
|
@@ -179,7 +179,7 @@ Funnel, standalone Features and page experiments evaluate independently. Matchin
|
|
|
179
179
|
|
|
180
180
|
For Customer-based evaluation, `id` means the Longplay Customer UUID (`customer.id`); `externalUserId` means the merchant account ID (`customer.externalUserId`). Choose the experiment's `hashAttribute` explicitly when creating it and preserve that meaning in every consumer. Do not put the merchant account ID into `attributes.id`. Supply local attributes from your trusted backend's Customer data; `identify(customerToken)` authenticates requests but does not populate local bucketing attributes. These attributes are evaluation data, not authorization.
|
|
181
181
|
|
|
182
|
-
`setAttributes()` replaces the complete object, so retain the bucketing fields on every update. Anonymous page/visual experiments instead default `id` and `deviceId` to the shared first-party device cookie; they do not automatically match an account-based experiment. Sticky capabilities differ by adapter: managed Local Run instructions receive server state, while pure local tools require their existing host persistence adapter for durable Sticky. No new shared state is introduced. See the [architecture boundary](../../docs/growthbook-sdk-delivery.md#跨消费方求值边界与分桶身份).
|
|
182
|
+
`setAttributes()` replaces the complete object, so retain the bucketing fields on every update. Anonymous page/visual experiments instead default `id` and `deviceId` to the shared first-party device cookie; they do not automatically match an account-based experiment. An open visual client rereads its payload every 60 seconds while visible, so a stopped experiment or disabled delivery reverts without a page reload. Sticky capabilities differ by adapter: managed Local Run instructions receive server state, while pure local tools require their existing host persistence adapter for durable Sticky. No new shared state is introduced. See the [architecture boundary](../../docs/growthbook-sdk-delivery.md#跨消费方求值边界与分桶身份).
|
|
183
183
|
|
|
184
184
|
### Server-side local Funnel evaluation
|
|
185
185
|
|
|
@@ -394,9 +394,9 @@ await entries.retry();
|
|
|
394
394
|
entries.destroy();
|
|
395
395
|
```
|
|
396
396
|
|
|
397
|
-
The host observes original button behavior, matches unique render/element guards and attempts automatic entries once per pathname visit. GOP selects the Funnel, checks entry publication, suppresses an existing Customer/Funnel Run and enforces the automatic-entry cooldown.
|
|
397
|
+
The host observes original button behavior, matches unique render/element guards and attempts automatic entries once per pathname visit. GOP selects the Funnel, checks entry publication, suppresses an existing Customer/Funnel Run and enforces the automatic-entry cooldown. With a full Customer Session, the host retains the original entry request and verified source target in tab-scoped `sessionStorage`. On reload it replays that exact request under the current Customer credential to recover the same Run, including background Waits and unresolved starts, without another Split allocation. Records are bound to API origin, App, environment, Customer and IAM release, and contain no Customer or Run credentials. Recovery waits for the original scene and also works when the accepted publication is paused or superseded. A bare-token session has no stable Customer binding and remains memory-only. Set `recoveryStorage: false` to disable persistence, or supply a `Storage` adapter; unavailable storage reports `recovery_unavailable`. When the page unloads, the host is destroyed or the Customer changes while a screen is shown, the host closes that Run (with `keepalive` on unload), so a later entry is not suppressed until the Run expires; Paywall, in-flight and background steps continue. When a Run is stopped from Console or expires, the host removes its UI and reports `run_ended`, whether the Run reads `closed` or its next command is refused with `FORBIDDEN`; a later trigger can then start again. An IAM binding supplies no Customer credential or business permission.
|
|
398
398
|
|
|
399
|
-
The entry scope is the route template plus render, covering every matching dynamic URL instance. Query/hash changes do not create a new visit. Supported anchor and inline-display changes recheck delayed scenes; hidden retained pages do not block the single active button. The clicked control itself must still be the unique active target; a replacement with the same selector cannot authorize an obsolete click. Multiple active targets remain refused. Configuration fetch/body reads default to a five-second deadline (`timeoutMs` overrides it), recover on the next 15-second poll, and discard late responses. Inspect `onStatus` for `identity_required`, `configuration_unavailable`, `incompatible` and `start_failed`. Definitively refused entries and accepted Runs whose first read is refused with a revoked credential allow the next matching entry in delivered order; transient read failures and pending unknown starts retain the original request for `retry()`.
|
|
399
|
+
The entry scope is the route template plus render, covering every matching dynamic URL instance. Query/hash changes do not create a new visit. Supported anchor and inline-display changes recheck delayed scenes; hidden retained pages do not block the single active button. The clicked control itself must still be the unique active target; a replacement with the same selector cannot authorize an obsolete click. Multiple active targets remain refused. Configuration fetch/body reads default to a five-second deadline (`timeoutMs` overrides it), recover on the next 15-second poll, and discard late responses. Inspect `onStatus` for `identity_required`, `configuration_unavailable`, `incompatible` and `start_failed`. Definitively refused entries and accepted Runs whose first read is refused with a revoked credential allow the next matching entry in delivered order; transient read failures and pending unknown starts retain the original request for `retry()`. Automatic entries present at most once per pathname visit: entries matched while a Run is shown, or after it ends, wait for the next visit, so dismissal or completion never chains another Funnel. Explicit button clicks still start. A Run that is paused or waiting on a timer/event step stays hidden, reports `run_background` and no longer blocks other entries; it shows again when it has a screen and yields its slot when another Run mounts. Original button navigation continues, so full-page navigation can prevent presentation.
|
|
400
400
|
|
|
401
401
|
An opted-in Split (`applyPageExperiment: true`) uses its accepted experiment variation for the merchant page. The entry host automatically shares `appManifestRelease` with `showFunnelRun`; manual hosts pass that option explicitly. `createFunnelPageExperiments({client, appManifestRelease})` is available for hosts without the standard UI. The consumer never rebuckets, reports use against the accepted receipt, and reverts on stop, completion or destruction. A separately installed visual consumer yields ownership of that experiment during the Run. This Web source feature requires matching GOP contracts and the IAM/Funnel database migration; installation alone does not promote runtime support.
|
|
402
402
|
|
package/README.zh-CN.md
CHANGED
|
@@ -191,7 +191,7 @@ Funnel、独立 Feature 和页面实验各自求值、各自使用结果。App
|
|
|
191
191
|
|
|
192
192
|
Customer 求值中的 `id` 是 Longplay Customer UUID(`customer.id`),`externalUserId` 是商户账号 ID(`customer.externalUserId`)。创建实验时明确选择 `hashAttribute`,每个消费方保持相同语义;不要把商户账号 ID 填进 `attributes.id`。本地属性来自可信后端给当前用户的 Customer 数据;`identify(customerToken)` 负责请求认证,不会自动补齐本地分桶属性。属性仅用于求值,不构成授权。
|
|
193
193
|
|
|
194
|
-
`setAttributes()` 替换整个对象,每次更新都保留分桶字段。匿名页面/视觉实验默认的 `id` 和 `deviceId` 来自共用的第一方设备 cookie
|
|
194
|
+
`setAttributes()` 替换整个对象,每次更新都保留分桶字段。匿名页面/视觉实验默认的 `id` 和 `deviceId` 来自共用的第一方设备 cookie,不自动与账号实验同组。已打开的页面在可见时每 60 秒重新读取视觉配置,实验停止或关闭投放后无需刷新页面即可撤销修改。各适配器的 Sticky 能力有区别:共用 Run 的 Local 指令读取服务端状态,纯本地工具的持久 Sticky 使用已有宿主适配器,不新增共享状态。完整要求见[架构边界](../../docs/growthbook-sdk-delivery.md#跨消费方求值边界与分桶身份)。
|
|
195
195
|
|
|
196
196
|
### 服务端 SDK 本地 Funnel 求值
|
|
197
197
|
|
|
@@ -305,7 +305,7 @@ npm 发布不部署 Web 服务、不应用数据库迁移,也不发布 Swift
|
|
|
305
305
|
|
|
306
306
|
`createIamFunnelEntries({scope, environmentId, baseUrl, appManifestRelease, session: longplay.session, container})` 安装一次后,通过 `start()` 启动监听,即可在 IAM 页面地图配置现有 Funnel Entry 节点的「进入屏幕」和「按钮/链接点击」入口。配置保存到 Funnel 草稿,随 Funnel 一起发布、暂停。`appManifestRelease` 必须来自当前构建的 IAM release descriptor。描述文件的请求头和正文读取共用两秒超时,fetch 忽略取消时也会释放等待。原页面点击处理继续执行;点击的原节点本身必须仍是唯一活动目标,具有相同选择器的替代节点不能证明旧点击有效。自动入口每次 pathname 访问尝试一次,查询参数、hash 和重新渲染不制造新访问。
|
|
307
307
|
|
|
308
|
-
服务端选择 Funnel,验证发布状态,并按原 Customer/Funnel 检查进行中的 Run 和自动入口冷却时间。未知响应或 Run 首次读取的暂时失败通过 `retry()`
|
|
308
|
+
服务端选择 Funnel,验证发布状态,并按原 Customer/Funnel 检查进行中的 Run 和自动入口冷却时间。未知响应或 Run 首次读取的暂时失败通过 `retry()` 复用内存中的原请求;完整 Customer Session 下,入口宿主将原 `entry_start` 请求及已验证目标保存到当前标签页的 `sessionStorage`,按 API origin、App、环境、Customer 和 IAM release 隔离,不保存 Customer 或 Run 凭据。刷新后回到原场景时,以当前 Customer 凭据重放同一请求,恢复原 Run、后台 Wait 和未知启动结果,不重新分组;原发布已暂停或换版也可恢复。裸 Token 会话仍仅保留内存状态;`recoveryStorage: false` 可关闭持久化,或传入 `Storage` 适配器;存储不可用时报告 `recovery_unavailable`。页面卸载、宿主销毁或 Customer 切换时,若正在展示普通屏幕,宿主会关闭该 Run(页面卸载时使用 `keepalive`),避免之后的入口在 Run 过期前一直被判为进行中。Paywall、进行中的请求和后台步骤不受影响。已接受 Run 在首次读取或离开页面后的关闭请求中被撤销凭据拒绝时,会释放入口等待。Run 被 Console 终止或过期后,无论读取到 `closed` 状态还是后续命令被 `FORBIDDEN` 拒绝,入口宿主都会移除界面并上报 `run_ended`,之后的入口可以重新启动。自动入口每次 pathname 访问最多展示一次:某个 Run 正在展示或已经展示后,同一访问内匹配的其他自动入口留到下一次访问,关闭或完成不会接着弹出另一个 Funnel;用户明确点击按钮仍可启动。Funnel 暂停或 Run 停在定时/事件等待步骤时,界面隐藏并上报 `run_background`,不再阻挡其他入口;之后有画面会重新显示,另一个 Run 挂载时让出位置。卸载时调用 `destroy()`。IAM 不提供 Customer 凭据或业务权限。
|
|
309
309
|
|
|
310
310
|
Split 开启 `applyPageExperiment` 后,页面直接使用该 Run 已接受的实验变体,不重新分桶。标准入口宿主自动向 `showFunnelRun` 传入 release;手动宿主传入 `appManifestRelease`,或使用 `createFunnelPageExperiments({client, appManifestRelease})`。停止、完成和销毁会清理效果,实际应用沿用原 receipt 的 GB used 上报。同一实验的独立 visual consumer 在 Funnel 持有分组期间让出控制。这些 Web 源码能力需要配套 GOP 合同和数据库迁移,安装 SDK 不等于运行时已发布。
|
|
311
311
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as u}from"./chunk-DSPLGTQI.js";import{b as d}from"./chunk-
|
|
1
|
+
import{a as u}from"./chunk-DSPLGTQI.js";import{b as d}from"./chunk-7XVAFQEE.js";function m(e){if(!/^[A-Za-z0-9_-]{1,64}$/.test(e))throw new Error("Invalid device cookie name");let t="";for(let i of document.cookie.split(";"))if(i.trim().startsWith(`${e}=`))try{t=decodeURIComponent(i.trim().slice(e.length+1))}catch{}return/^[A-Za-z0-9_-]{8,128}$/.test(t)||(t=crypto.randomUUID(),document.cookie=`${e}=${encodeURIComponent(t)}; path=/; max-age=${400*24*3600}; SameSite=Lax`),t}function y(){try{let e=sessionStorage.getItem("indiana_sid");return e||(e=crypto.randomUUID(),sessionStorage.setItem("indiana_sid",e)),e}catch{return}}function g(e=d){let t=new URL(e);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname))||t.username||t.password||t.search||t.hash)throw new Error("baseUrl must be an https origin without credentials");return t.origin}var o=new Set,s;function S(e){let t=()=>e();if(o.add(t),!s){let i=!0,a=history.pushState,p=history.replaceState,r=()=>{if(i)for(let n of[...o])o.has(n)&&u(n)},c=function(...n){a.apply(this,n),r()},h=function(...n){p.apply(this,n),r()};history.pushState=c,history.replaceState=h,addEventListener("popstate",r),addEventListener("hashchange",r),s=()=>{i=!1,history.pushState===c&&(history.pushState=a),history.replaceState===h&&(history.replaceState=p),removeEventListener("popstate",r),removeEventListener("hashchange",r)}}return()=>{o.delete(t)&&(o.size||(s?.(),s=void 0))}}export{m as a,y as b,g as c,S as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var s={name:"@tinkerlandai/longplay-sdk",version:"0.10.
|
|
1
|
+
var s={name:"@tinkerlandai/longplay-sdk",version:"0.10.8",description:"Framework-independent Longplay SDK for customer identity, entitlements, credits, offers and growth surfaces.",license:"UNLICENSED",repository:{type:"git",url:"git+https://github.com/tinkerlandai/Indiana.git",directory:"packages/sdk"},engines:{node:">=22"},publishConfig:{access:"public",tag:"beta"},type:"module",sideEffects:!1,files:["dist","README.md","README.zh-CN.md","CHANGELOG.md","THIRD_PARTY_NOTICES.md"],exports:{"./react-native":{types:"./dist/react-native.d.ts","react-native":"./dist/react-native.js",import:"./dist/react-native.js",default:"./dist/react-native.js"},".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./popup":{types:"./dist/popup.d.ts",import:"./dist/popup.js"},"./server":{types:"./dist/server.d.ts",import:"./dist/server.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.js"},"./native-shell":{types:"./dist/native-shell.d.ts",import:"./dist/native-shell.js"},"./page":{types:"./dist/page.d.ts",import:"./dist/page.js"},"./visual":{types:"./dist/visual.d.ts",import:"./dist/visual.js"}},scripts:{build:"tsup",prepack:"pnpm run build",typecheck:"tsc --noEmit",lint:"node ../../scripts/ci/lint.mjs --workspace packages/sdk"},dependencies:{"@ai-sdk/provider":"4.0.26","@types/json-schema":"7.0.15","css-tree":"^3.2.1","dom-mutator":"0.7.0",dompurify:"^3.4.15",zod:"4.6.6"},devDependencies:{"@indiana/contracts":"workspace:*","@openrouter/sdk":"^1.4.25","@types/css-tree":"^3.2.0",ai:"7.0.136",tsup:"^8.5.1",typescript:"^5.9.3","whatwg-url-minimum":"0.2.0"},peerDependencies:{"@openrouter/sdk":"^1.4.25"},peerDependenciesMeta:{"@openrouter/sdk":{optional:!0}}};var i="https://api.longplayai.com";export{s as a,i as b};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as u,b as Y,l as W,o as $}from"./chunk-Y3AGPHWF.js";import{N as Q,Qa as K,a as J,b as H,c as z,d as U,e as B,f as G,j,na as i,pa as L}from"./chunk-IAOOTBJV.js";import{qa as a}from"./chunk-ACF2FBUB.js";import{a as M}from"./chunk-G56XGVMS.js";var x=t=>{if(!Number.isSafeInteger(t)||t<0||t>=Number.MAX_SAFE_INTEGER)throw new a("INVALID_STATE","Installation sequence exhausted");return t+1},me=async t=>[...new Uint8Array(await crypto.subtle.digest("SHA-256",Uint8Array.from(t,e=>e.charCodeAt(0))))].map(e=>e.toString(16).padStart(2,"0")).join("");function V(t,e){return t.transaction(n=>{if(!Number.isSafeInteger(n.identitySeq)||n.identitySeq<0||!Number.isSafeInteger(n.addressSeq)||n.addressSeq<0||n.detachSeq!==null&&(!Number.isSafeInteger(n.detachSeq)||n.detachSeq<1||n.detachSeq>n.identitySeq))throw new a("INVALID_STATE","Installation journal is invalid");return e({...n})})}function X(t,e,n){let r=null,d=0,p=0,c=0,m=Promise.resolve();if(t&&(!n||M.parse(t.scope).projectId!==n.projectId||t.scope.environment!==n.environment))throw new a("SCOPE_MISMATCH","Push installation belongs to another scope");let A=()=>{if(!t)throw new a("NOT_CONFIGURED","Configure this client's native Push host first");return t},h=o=>{if(o!==d)throw new a("IDENTITY_CHANGED","Identity changed during Push operation")};async function T(o){let s=A();if(!s.sha256&&!globalThis.crypto?.subtle)throw new a("NOT_CONFIGURED","Configure native SHA-256 for this Push host");let l=s.sha256?await s.sha256(Uint8Array.from(o,f=>f.charCodeAt(0))):await me(o);if(!/^[a-f0-9]{64}$/.test(l))throw new a("INVALID_STATE","Push credential digest is invalid");return l}function C(o){let s=B.parse(o);if(s.installationId.toLowerCase()!==A().installationId.toLowerCase())throw new a("INVALID_RESPONSE","Push response belongs to another installation");return s}async function R(o,s){let l=A(),f={installationId:l.installationId,publicKey:l.publicKey,issuedAt:new Date().toISOString(),...s},g=await l.sign(G(o,l.scope,f));return{...f,signature:g}}let k=(o,s,l)=>e.requestWithCredential?e.requestWithCredential(o,s,l):e.request(o,s);async function S(){let o=A(),s=d,l=r?await(e.session?.access()??r):null,f=V(o,y=>y),g;if(f.detachSeq!==null){let y=f.detachSeq,b=J.parse(await R("detach",{sequence:y,platform:o.platform}));try{let w=await e.request("push/installations/detach",{...o.scope,...b},"POST",{installationDetach:!0});if(!w||typeof w!="object"||!("installation"in w))throw new a("INVALID_RESPONSE","Push detach acknowledgement is invalid");let _=C(w.installation);if(_.bound||_.identitySeq!==y)throw new a("INVALID_RESPONSE","Push detach acknowledgement does not match its intent")}catch(w){if(w instanceof a&&w.status===404)g=w;else if(!(w instanceof a)||w.status!==412)throw w}g||V(o,w=>({...w,detachSeq:w.detachSeq===y?null:w.detachSeq}))}if(h(s),!l){if(g)throw g;return null}let E=i.bindPushInstallation,N=E.request.parse(await R("bind",{sequence:c,platform:o.platform,credentialDigest:await T(l)}));h(s);let D=E.response.parse(await k(E.path,N,l));h(s);let v=C(D.installation);if(!v.bound||v.identitySeq!==c)throw new a("INVALID_RESPONSE","Push binding acknowledgement does not match its intent");return g&&f.detachSeq!==null&&c>f.detachSeq&&V(o,y=>({...y,detachSeq:y.detachSeq===f.detachSeq?null:y.detachSeq})),v}async function P(){A();let o=d,s=r?await(e.session?.access()??r):null;if(!s)throw new a("NOT_IDENTIFIED","Identify before reading this installation");let l=i.readPushInstallation,f=l.request.parse(await R("read",{credentialDigest:await T(s)}));h(o);let g=l.response.parse(await k(l.path,f,s));return h(o),C(g.installation)}function O(o=S){let s=m.catch(()=>{}).then(o);return m=s,s.catch(l=>{try{t?.onError?.(l instanceof Error?l:new Error("Push synchronization failed"))}catch{}}),s}async function q(o,s,l){let f=A(),g=s.identity,E=s.observation,N=r?await(e.session?.access()??r):null;if(h(g),E!==p)throw new a("INVALID_STATE","Push observation changed during recovery");if(!N)throw new a("NOT_IDENTIFIED","Identify before recovering a Push address");if(!o.connectionId||!o.kind||!o.token||!["granted","provisional"].includes(o.permission))throw new a("INVALID_REQUEST","Recovery needs a provider token and notification permission");return await O(async()=>{if(h(g),await S(),h(g),E!==p)throw new a("INVALID_STATE","Push observation changed during recovery");let D=V(f,_=>l?_:{..._,addressSeq:x(_.addressSeq)}),y=await R(l?"recovery_confirm":"recovery_request",{...o,sequence:D.addressSeq,credentialDigest:await T(N),...l?{challenge:l}:{}}),b=l?z.parse(y):H.parse(y);if(h(g),E!==p)throw new a("INVALID_STATE","Push observation changed during recovery");let w=await k(`push/installations/recovery/${l?"confirm":"request"}`,b,N);if(h(g),E!==p||V(f,_=>_).addressSeq!==D.addressSeq)throw new a("INVALID_STATE","Push observation changed during recovery");if(l){let _=i.updatePushAddress.response.parse(w),F=C(_.installation);if(!F.bound||F.identitySeq!==c||F.addressSeq!==D.addressSeq||F.connectionId!==o.connectionId||F.addressStatus!=="active")throw new a("INVALID_RESPONSE","Push recovery acknowledgement does not match its intent");return F}if(!w||typeof w!="object"||!("recovery"in w))throw new a("INVALID_RESPONSE","Push recovery acknowledgement is invalid");return U.parse(w.recovery)})}return{recoveryObserver(){A();let o={identity:d,observation:++p};return{async request(s){return U.parse(await q(s,o))},async confirm(s,l){return B.parse(await q(l,o,s))}}},identify(o){if(!t)return;c=V(t,l=>({...l,identitySeq:x(l.identitySeq)})).identitySeq,r=o,d++,p++},reset(){if(t)try{V(t,o=>{let s=x(o.identitySeq);return{...o,identitySeq:s,detachSeq:s}})}finally{r=null,d++,p++}},start(){t&&O()},async sync(){return await O()},read:P,async recover(){let o=A(),s=d,l=c;return p++,await O(async()=>{h(s);let f=await P();return h(s),c=V(o,E=>{if(E.identitySeq!==l)throw new a("IDENTITY_CHANGED","A newer installation intent exists");return{...E,identitySeq:x(Math.max(E.identitySeq,f.identitySeq)),addressSeq:Math.max(E.addressSeq,f.addressSeq)}}).identitySeq,await S()})},tokenObserver(){A();let o=++p,s=d;return async l=>{if(o!==p||s!==d)return null;let f=A(),g=r?await(e.session?.access()??r):null;if(!g)throw new a("NOT_IDENTIFIED","Identify before registering a Push token");if(await O(),h(s),o!==p)return null;let E=V(f,y=>({...y,addressSeq:x(y.addressSeq)})),N=i.updatePushAddress,D=N.request.parse(await R("address",{...l,sequence:E.addressSeq,credentialDigest:await T(g)}));if(h(s),o!==p)return null;let v=N.response.parse(await k(N.path,D,g));return h(s),C(v.installation)}}}}function Z(t,e){return{messaging:{async preference(n){let r=i.readMessagingPreference;return r.response.parse(await t(r.path,r.request.parse({channel:n}))).preference},async setPreference(n){let r=i.setMessagingPreference;return r.response.parse(await t(r.path,r.request.parse(n))).preference}},push:{sync:e.sync,read:e.read,recover:e.recover,tokenObserver:e.tokenObserver,recoveryObserver:e.recoveryObserver,async preference(){let n=i.readMessagingPreference;return n.response.parse(await t(n.path,{channel:"push"})).preference},async setPreference(n){let r=i.setMessagingPreference;return r.response.parse(await t(r.path,r.request.parse({...n,channel:"push"}))).preference}}}}function ee(t,e,n={}){let r=!!t.session.peek(),d=new Set,p=c=>{for(let m of d)try{m(c)}catch{}};return t.session.subscribeIdentity(()=>{r=!!t.session.peek(),p(r),n.afterChange?.()},()=>{r=!1,e()}),{isIdentified:()=>r,methods:{subscribeIdentity(c){return d.add(c),()=>{d.delete(c)}},identify(c){let m=typeof c=="string"?c:c.accessToken;if(!j.test(m))throw new a("INVALID_TOKEN","Browser SDK requires a customer session");n.beforeIdentify?.(m),t.identify(c)},reset(){try{n.beforeReset?.()}finally{t.reset()}}}}}function I(t){if(t!==null&&typeof t=="object"&&"customerId"in t)throw new a("INVALID_REQUEST","Customer requests use the verified session identity")}function te(t){return{async checkEntitlement(e){I(e);let n=i.checkEntitlement;return u(t,n,e)},async readHoldings(e={}){let n=i.readHoldings;return u(t,{...n,request:n.request.omit({customerId:!0})},e)}}}function ne(t){return{async readLedger(e){let n=i.readLedger;return u(t,n,{query:e})},async readCreditStatement(e){I(e);let n=i.readCreditStatement;return u(t,n,e)},async quoteBalance(e){I(e);let n=i.quoteBalance;return u(t,n,{command:e})}}}function re(t){return{async setupPayment(e){I(e);let n=i.setupPayment;return u(t,n,e)},async readPaymentSetup(e){I(e);let n=i.readPaymentSetup;return u(t,n,e)},async readBillingInvoice(e){I(e);let n=i.readBillingInvoice;return u(t,n,e)},async readBillingControls(e={}){I(e);let n=i.readBillingControls;return u(t,n,e)},async prepareBillingAuthorization(e){I(e);let n=i.prepareBillingAuthorization;return u(t,n,e)},async confirmBillingAuthorization(e){I(e);let n=i.confirmBillingAuthorization;return u(t,n,e)},async setBillingCoupons(e){I(e);let n=i.setBillingCoupons;return u(t,n,e,{request:"Invalid billing coupon list",response:"Invalid billing coupon receipt"})},async revokeBillingAuthorization(e){I(e);let n=i.revokeBillingAuthorization;return u(t,n,e)},async listBillingInvoices(e={after:null,limit:25}){I(e);let n=i.listBillingInvoices;return u(t,n,e)},async confirmBillingAdjustment(e){I(e);let n=i.confirmBillingAdjustment;return u(t,n,e)}}}function ie(t){return{async previewUpdate(e){I(e);let n=i.previewUpdate;return u(t,n,e)},async update(e){I(e);let n=i.update;return u(t,n,e)},async readSubscriptionUpdate(e){I(e);let n=i.readSubscriptionUpdate;return u(t,n,e)},async restoreNativePurchase(e){I(e);let n=i.restoreNativePurchase;return u(t,n,e)},async previewAttach(e){I(e);let n=i.previewAttach;return u(t,n,e)},async attach(e){I(e);let n=i.attach;return u(t,n,e)},async readSubscriptionOperation(e){I(e);let n=i.readSubscriptionOperation;return u(t,n,e)}}}function oe(t){return{async redeemReward(e){return I(e),(await u(t,i.redeemReward,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid reward redemption",response:"Invalid reward receipt"})).redemption},async claimRewardProduct(e){return I(e),(await u(t,i.claimRewardProduct,e,{request:"Invalid reward product claim",response:"Invalid reward product checkout"})).checkout},async createReferralCode(e){return I(e),(await u(t,i.createReferralCode,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid referral program",response:"Invalid referral code"})).referralCode},async redeemCoupon(e,n=crypto.randomUUID()){let r=await u(t,i.redeemCoupon,{code:e,requestId:n},{request:"Invalid coupon code",response:"Invalid Coupon receipt"});return{offer:r.offer,reason:r.reason}},async claimCoupon(e,n=crypto.randomUUID()){let r=await u(t,i.grantOffer,{couponId:e,requestId:n},{request:"Invalid Coupon claim",response:"Invalid Coupon receipt"});return{offer:r.offer,reason:r.reason}},async listOffers(){return(await u(t,i.listOffers,{},{response:"Invalid offers response"})).offers}}}function se(t){return{...te(t),...ne(t),...re(t),...ie(t),...oe(t)}}function ae(t){return{async resolveContent(e){I(e);let n=i.resolveContent;return u(t,n,e)},async resolvePaywall(e){I(e);let n=i.resolvePaywall;return u(t,n,e)},async resolveOffering(e){I(e);let n=i.resolveOffering;return u(t,n,e)}}}var ce=t=>new TextEncoder().encode(JSON.stringify(t)).length,ue=16384;function de(t,e){let n=0,r,d=S=>{r={config:structuredClone(S),until:Date.now()+3e4}},p=[],c=null,m;function A(){if(!e())throw new a("NOT_IDENTIFIED","Call identify before using Features or events")}function h(){m||!p.length||(m=setTimeout(()=>{m=void 0,C().catch(()=>{}).finally(h)},5e3),typeof m=="object"&&"unref"in m&&m.unref())}function T(S,P={},O={}){if(A(),r&&Date.now()<r.until&&!Q(r.config,S))return;k();let q=i.trackEvents.request.parse({events:[{eventUuid:crypto.randomUUID(),timestamp:new Date().toISOString(),name:S,properties:P,...O}]}).events[0];if(ce({events:[q]})>ue)throw new a("INVALID_REQUEST","Event exceeds the delivery size limit");if(p.length>=500)throw new a("EVENT_QUEUE_FULL","Flush pending events before tracking more");p.push(structuredClone(q)),h()}async function C(S=!1){if(A(),c)return c;let P=n,O=(async()=>{let q={inserted:0,duplicates:0,rejected:0,skipped:0},o=p.length;for(;o&&P===n;){let s=[];for(let g of p.slice(0,Math.min(o,100))){if(s.length&&ce({events:[...s,g]})>ue)break;s.push(g)}let l=i.trackEvents,f=await u(t,l,{events:s},void 0,{keepalive:S});if(P!==n)throw new a("IDENTITY_CHANGED","Event identity changed during delivery");if(f.inserted+f.duplicates+f.rejected+f.skipped!==s.length)throw new a("INVALID_RESPONSE","Incomplete event acknowledgement");d(f.analyticsConfig),p.splice(0,s.length),o-=s.length,q.inserted+=f.inserted,q.duplicates+=f.duplicates,q.rejected+=f.rejected,q.skipped+=f.skipped}return q})();c=O;try{return await O}finally{c===O&&(c=null)}}let R;function k(){if(R||typeof document>"u")return;let S=()=>{document.visibilityState==="hidden"&&e()&&p.length&&C(!0).catch(()=>{})};document.addEventListener("visibilitychange",S),R=()=>document.removeEventListener("visibilitychange",S)}return{rememberConfiguration:d,track(S,P,O={}){return k(),T(S,P,O)},flush:C,reset(){n++,r=void 0,clearTimeout(m),m=void 0,p=[],c=null},detachVisibility(){R?.(),R=void 0}}}function pe(t){let e=t.merchandise;if(typeof t.merchandiseId=="string")return{internalId:t.merchandiseId};if(!(!e||typeof e!="object"||Array.isArray(e))){if(typeof e.internalId=="string")return{internalId:e.internalId};if(typeof e.externalId=="string")return{id:e.externalId};if(typeof e.id=="string")return{id:e.id}}}function ye(t){let e=pe(t),{merchandiseId:n,merchandise:r,...d}=t;return{...d,...e?{merchandise:e}:{}}}function le(t,e,n,r,d){if(d&&r&&(d.scope.projectId!==r.projectId||d.scope.environment!==r.environment))throw new a("SCOPE_MISMATCH","Configuration belongs to another App/environment");let p=0,c=new Set;function m(){if(!e())throw new a("NOT_IDENTIFIED","Call identify before using Features or events")}async function A(h={}){d||m();let T=p,C=!1,R=async()=>{if(C||T!==p)throw new a("IDENTITY_CHANGED","Feature identity changed");let v=i.getFeatures,y=d?{scope:{projectId:d.scope.projectId,environment:d.scope.environment},payload:await d.features()}:await u(t,v,{});if(T!==p)throw new a("IDENTITY_CHANGED","Feature identity changed");if(r&&(y.scope.projectId!==r.projectId||y.scope.environment!==r.environment))throw new a("INVALID_RESPONSE","Feature response scope changed");return n.rememberConfiguration(y.payload.analyticsConfig),y},k=await R(),S=!0,P,O=v=>{try{h.onError?.(v)}catch{}},q=(v,y,b)=>{try{let w=pe(b);n.track(v,y,w?{merchandise:w}:{})}catch(w){O(w)}},o=Y({assertUsable:d?.assertFeatures,scope:k.scope,attributes:h.attributes,onError:h.onError,load:async()=>S?(S=!1,k.payload):(await R()).payload,evaluateRemote:async v=>{if(T!==p)throw new a("IDENTITY_CHANGED","Feature identity changed");let y=i.evaluateFeatures,b=await u(t,y,{...v,attributes:ye(v.attributes)});if(b.scope.projectId!==k.scope.projectId||b.scope.environment!==k.scope.environment)throw new a("INVALID_RESPONSE","Remote Feature response scope changed");return{generation:b.generation,evaluatedAt:b.evaluatedAt,expiresAt:b.expiresAt,features:b.features,...b.merchandiseContext?{merchandiseContext:b.merchandiseContext}:{}}},onExperimentViewed:(v,y,b)=>q("Experiment Viewed",{experimentId:v.key,variationId:y.key},b),onFeatureUsage:(v,y,b)=>q("Feature Evaluated",{feature:v,value:y.value,source:y.source,ruleId:y.ruleId,...y.experimentResult?{variationId:y.experimentResult.key}:{}},b)}),s=o.refresh;function l(){clearTimeout(P),!d&&(C||T!==p||!o.expiresAt||(P=setTimeout(()=>{f().catch(O)},Math.min(2147483647,Math.max(1e3,Date.parse(o.expiresAt)-Date.now()))),typeof P=="object"&&"unref"in P&&P.unref()))}async function f(){try{return await s()}finally{l()}}let g=()=>{C||f().catch(O)},E=o.subscribe(l),N=d?.subscribe(()=>{!C&&d.fresh&&f().catch(O)});function D(){C||(C=!0,clearTimeout(P),typeof window<"u"&&window.removeEventListener("focus",g),E(),N?.(),o.reset(),c.delete(D))}c.add(D);try{await o.init(),(h.attributes?.merchandise||h.attributes?.merchandiseId)&&await o.refreshRemote()}catch(v){throw D(),v}return l(),!d&&typeof window<"u"&&window.addEventListener("focus",g),Object.assign(o,{refresh:f,destroy:D})}return{features:A,reset(h){p++,h();for(let T of c)T()}}}import{z as Ie}from"zod";function fe(t,e){let n="source"in e?{funnelId:e.source.id,funnelVersionId:e.source.versionId}:"versionId"in e?{funnelId:e.funnelId,funnelVersionId:e.versionId}:e,r=Ie.object({funnelId:L.shape.id,funnelVersionId:L.shape.versionId.optional()}).safeParse(n);if(!r.success)throw new a("INVALID_REQUEST","A valid Funnel source is required");let d=Object.freeze(r.data);function p(c){if("customerId"in c)throw new a("INVALID_REQUEST","Customer identity cannot be overridden");if("funnelId"in c&&c.funnelId!==void 0&&c.funnelId!==d.funnelId||"funnelVersionId"in c&&c.funnelVersionId!==void 0&&c.funnelVersionId!==d.funnelVersionId)throw new a("SCOPE_MISMATCH","The original Funnel source cannot change");return{...c,...d}}return{async claimCoupon(c,m=crypto.randomUUID()){let A=i.grantOffer,h=await u(t,A,p({couponId:c,requestId:m}));return{offer:h.offer,reason:h.reason}},async resolveOffering(c){let m=i.resolveOffering;return u(t,m,p(c))},async resolvePaywall(c){let m=i.resolvePaywall;return u(t,m,p(c))},async previewAttach(c){let m=i.previewAttach;return u(t,m,p(c))}}}function Pt(t){return he(t)}function he(t){let e=K(t),n=e.request,r=X(t.push,e,t.scope??t.configuration?.scope),d=ee(e,()=>{c.reset(p.reset),p.detachVisibility()},{beforeIdentify:r.identify,beforeReset:r.reset,afterChange:r.start}),p=de(n,d.isIdentified),c=le(n,d.isIdentified,p,t.scope,t.configuration);return{session:e.session,...Z(n,r),...se(n),...ae(n),forFunnel(m){return fe(n,m)},async features(m={}){return c.features(m)},track(m,A,h={}){return p.track(m,A,h)},flush(){return p.flush()},...d.methods}}function Nt(t){if(!j.test(t.customerToken))throw new a("INVALID_TOKEN","A customer credential is required");if(!t.scope)throw new a("INVALID_REQUEST","An explicit App and environment scope is required");let e=$({...t,scope:t.scope,apiKey:t.customerToken});return{async start(n){let r=await e.start(n),d=W({...t,runToken:r.runToken});d.identify(t.customerToken);let p=r.run.instruction?.type==="evaluate_segment"?await d.get():r;return{...r,...p,controller:d}}}}export{Pt as a,he as b,Nt as c};
|
|
1
|
+
import{a as u,b as Y,l as W,o as $}from"./chunk-RP2P3FU4.js";import{N as Q,Ra as K,a as J,b as H,c as z,d as U,e as B,f as G,j,na as i,pa as L}from"./chunk-U4UEOR5W.js";import{qa as a}from"./chunk-ACF2FBUB.js";import{a as M}from"./chunk-G56XGVMS.js";var x=t=>{if(!Number.isSafeInteger(t)||t<0||t>=Number.MAX_SAFE_INTEGER)throw new a("INVALID_STATE","Installation sequence exhausted");return t+1},me=async t=>[...new Uint8Array(await crypto.subtle.digest("SHA-256",Uint8Array.from(t,e=>e.charCodeAt(0))))].map(e=>e.toString(16).padStart(2,"0")).join("");function V(t,e){return t.transaction(n=>{if(!Number.isSafeInteger(n.identitySeq)||n.identitySeq<0||!Number.isSafeInteger(n.addressSeq)||n.addressSeq<0||n.detachSeq!==null&&(!Number.isSafeInteger(n.detachSeq)||n.detachSeq<1||n.detachSeq>n.identitySeq))throw new a("INVALID_STATE","Installation journal is invalid");return e({...n})})}function X(t,e,n){let r=null,d=0,p=0,c=0,m=Promise.resolve();if(t&&(!n||M.parse(t.scope).projectId!==n.projectId||t.scope.environment!==n.environment))throw new a("SCOPE_MISMATCH","Push installation belongs to another scope");let A=()=>{if(!t)throw new a("NOT_CONFIGURED","Configure this client's native Push host first");return t},h=o=>{if(o!==d)throw new a("IDENTITY_CHANGED","Identity changed during Push operation")};async function T(o){let s=A();if(!s.sha256&&!globalThis.crypto?.subtle)throw new a("NOT_CONFIGURED","Configure native SHA-256 for this Push host");let l=s.sha256?await s.sha256(Uint8Array.from(o,f=>f.charCodeAt(0))):await me(o);if(!/^[a-f0-9]{64}$/.test(l))throw new a("INVALID_STATE","Push credential digest is invalid");return l}function C(o){let s=B.parse(o);if(s.installationId.toLowerCase()!==A().installationId.toLowerCase())throw new a("INVALID_RESPONSE","Push response belongs to another installation");return s}async function R(o,s){let l=A(),f={installationId:l.installationId,publicKey:l.publicKey,issuedAt:new Date().toISOString(),...s},g=await l.sign(G(o,l.scope,f));return{...f,signature:g}}let k=(o,s,l)=>e.requestWithCredential?e.requestWithCredential(o,s,l):e.request(o,s);async function S(){let o=A(),s=d,l=r?await(e.session?.access()??r):null,f=V(o,y=>y),g;if(f.detachSeq!==null){let y=f.detachSeq,b=J.parse(await R("detach",{sequence:y,platform:o.platform}));try{let w=await e.request("push/installations/detach",{...o.scope,...b},"POST",{installationDetach:!0});if(!w||typeof w!="object"||!("installation"in w))throw new a("INVALID_RESPONSE","Push detach acknowledgement is invalid");let _=C(w.installation);if(_.bound||_.identitySeq!==y)throw new a("INVALID_RESPONSE","Push detach acknowledgement does not match its intent")}catch(w){if(w instanceof a&&w.status===404)g=w;else if(!(w instanceof a)||w.status!==412)throw w}g||V(o,w=>({...w,detachSeq:w.detachSeq===y?null:w.detachSeq}))}if(h(s),!l){if(g)throw g;return null}let E=i.bindPushInstallation,N=E.request.parse(await R("bind",{sequence:c,platform:o.platform,credentialDigest:await T(l)}));h(s);let D=E.response.parse(await k(E.path,N,l));h(s);let v=C(D.installation);if(!v.bound||v.identitySeq!==c)throw new a("INVALID_RESPONSE","Push binding acknowledgement does not match its intent");return g&&f.detachSeq!==null&&c>f.detachSeq&&V(o,y=>({...y,detachSeq:y.detachSeq===f.detachSeq?null:y.detachSeq})),v}async function P(){A();let o=d,s=r?await(e.session?.access()??r):null;if(!s)throw new a("NOT_IDENTIFIED","Identify before reading this installation");let l=i.readPushInstallation,f=l.request.parse(await R("read",{credentialDigest:await T(s)}));h(o);let g=l.response.parse(await k(l.path,f,s));return h(o),C(g.installation)}function O(o=S){let s=m.catch(()=>{}).then(o);return m=s,s.catch(l=>{try{t?.onError?.(l instanceof Error?l:new Error("Push synchronization failed"))}catch{}}),s}async function q(o,s,l){let f=A(),g=s.identity,E=s.observation,N=r?await(e.session?.access()??r):null;if(h(g),E!==p)throw new a("INVALID_STATE","Push observation changed during recovery");if(!N)throw new a("NOT_IDENTIFIED","Identify before recovering a Push address");if(!o.connectionId||!o.kind||!o.token||!["granted","provisional"].includes(o.permission))throw new a("INVALID_REQUEST","Recovery needs a provider token and notification permission");return await O(async()=>{if(h(g),await S(),h(g),E!==p)throw new a("INVALID_STATE","Push observation changed during recovery");let D=V(f,_=>l?_:{..._,addressSeq:x(_.addressSeq)}),y=await R(l?"recovery_confirm":"recovery_request",{...o,sequence:D.addressSeq,credentialDigest:await T(N),...l?{challenge:l}:{}}),b=l?z.parse(y):H.parse(y);if(h(g),E!==p)throw new a("INVALID_STATE","Push observation changed during recovery");let w=await k(`push/installations/recovery/${l?"confirm":"request"}`,b,N);if(h(g),E!==p||V(f,_=>_).addressSeq!==D.addressSeq)throw new a("INVALID_STATE","Push observation changed during recovery");if(l){let _=i.updatePushAddress.response.parse(w),F=C(_.installation);if(!F.bound||F.identitySeq!==c||F.addressSeq!==D.addressSeq||F.connectionId!==o.connectionId||F.addressStatus!=="active")throw new a("INVALID_RESPONSE","Push recovery acknowledgement does not match its intent");return F}if(!w||typeof w!="object"||!("recovery"in w))throw new a("INVALID_RESPONSE","Push recovery acknowledgement is invalid");return U.parse(w.recovery)})}return{recoveryObserver(){A();let o={identity:d,observation:++p};return{async request(s){return U.parse(await q(s,o))},async confirm(s,l){return B.parse(await q(l,o,s))}}},identify(o){if(!t)return;c=V(t,l=>({...l,identitySeq:x(l.identitySeq)})).identitySeq,r=o,d++,p++},reset(){if(t)try{V(t,o=>{let s=x(o.identitySeq);return{...o,identitySeq:s,detachSeq:s}})}finally{r=null,d++,p++}},start(){t&&O()},async sync(){return await O()},read:P,async recover(){let o=A(),s=d,l=c;return p++,await O(async()=>{h(s);let f=await P();return h(s),c=V(o,E=>{if(E.identitySeq!==l)throw new a("IDENTITY_CHANGED","A newer installation intent exists");return{...E,identitySeq:x(Math.max(E.identitySeq,f.identitySeq)),addressSeq:Math.max(E.addressSeq,f.addressSeq)}}).identitySeq,await S()})},tokenObserver(){A();let o=++p,s=d;return async l=>{if(o!==p||s!==d)return null;let f=A(),g=r?await(e.session?.access()??r):null;if(!g)throw new a("NOT_IDENTIFIED","Identify before registering a Push token");if(await O(),h(s),o!==p)return null;let E=V(f,y=>({...y,addressSeq:x(y.addressSeq)})),N=i.updatePushAddress,D=N.request.parse(await R("address",{...l,sequence:E.addressSeq,credentialDigest:await T(g)}));if(h(s),o!==p)return null;let v=N.response.parse(await k(N.path,D,g));return h(s),C(v.installation)}}}}function Z(t,e){return{messaging:{async preference(n){let r=i.readMessagingPreference;return r.response.parse(await t(r.path,r.request.parse({channel:n}))).preference},async setPreference(n){let r=i.setMessagingPreference;return r.response.parse(await t(r.path,r.request.parse(n))).preference}},push:{sync:e.sync,read:e.read,recover:e.recover,tokenObserver:e.tokenObserver,recoveryObserver:e.recoveryObserver,async preference(){let n=i.readMessagingPreference;return n.response.parse(await t(n.path,{channel:"push"})).preference},async setPreference(n){let r=i.setMessagingPreference;return r.response.parse(await t(r.path,r.request.parse({...n,channel:"push"}))).preference}}}}function ee(t,e,n={}){let r=!!t.session.peek(),d=new Set,p=c=>{for(let m of d)try{m(c)}catch{}};return t.session.subscribeIdentity(()=>{r=!!t.session.peek(),p(r),n.afterChange?.()},()=>{r=!1,e()}),{isIdentified:()=>r,methods:{subscribeIdentity(c){return d.add(c),()=>{d.delete(c)}},identify(c){let m=typeof c=="string"?c:c.accessToken;if(!j.test(m))throw new a("INVALID_TOKEN","Browser SDK requires a customer session");n.beforeIdentify?.(m),t.identify(c)},reset(){try{n.beforeReset?.()}finally{t.reset()}}}}}function I(t){if(t!==null&&typeof t=="object"&&"customerId"in t)throw new a("INVALID_REQUEST","Customer requests use the verified session identity")}function te(t){return{async checkEntitlement(e){I(e);let n=i.checkEntitlement;return u(t,n,e)},async readHoldings(e={}){let n=i.readHoldings;return u(t,{...n,request:n.request.omit({customerId:!0})},e)}}}function ne(t){return{async readLedger(e){let n=i.readLedger;return u(t,n,{query:e})},async readCreditStatement(e){I(e);let n=i.readCreditStatement;return u(t,n,e)},async quoteBalance(e){I(e);let n=i.quoteBalance;return u(t,n,{command:e})}}}function re(t){return{async setupPayment(e){I(e);let n=i.setupPayment;return u(t,n,e)},async readPaymentSetup(e){I(e);let n=i.readPaymentSetup;return u(t,n,e)},async readBillingInvoice(e){I(e);let n=i.readBillingInvoice;return u(t,n,e)},async readBillingControls(e={}){I(e);let n=i.readBillingControls;return u(t,n,e)},async prepareBillingAuthorization(e){I(e);let n=i.prepareBillingAuthorization;return u(t,n,e)},async confirmBillingAuthorization(e){I(e);let n=i.confirmBillingAuthorization;return u(t,n,e)},async setBillingCoupons(e){I(e);let n=i.setBillingCoupons;return u(t,n,e,{request:"Invalid billing coupon list",response:"Invalid billing coupon receipt"})},async revokeBillingAuthorization(e){I(e);let n=i.revokeBillingAuthorization;return u(t,n,e)},async listBillingInvoices(e={after:null,limit:25}){I(e);let n=i.listBillingInvoices;return u(t,n,e)},async confirmBillingAdjustment(e){I(e);let n=i.confirmBillingAdjustment;return u(t,n,e)}}}function ie(t){return{async previewUpdate(e){I(e);let n=i.previewUpdate;return u(t,n,e)},async update(e){I(e);let n=i.update;return u(t,n,e)},async readSubscriptionUpdate(e){I(e);let n=i.readSubscriptionUpdate;return u(t,n,e)},async restoreNativePurchase(e){I(e);let n=i.restoreNativePurchase;return u(t,n,e)},async previewAttach(e){I(e);let n=i.previewAttach;return u(t,n,e)},async attach(e){I(e);let n=i.attach;return u(t,n,e)},async readSubscriptionOperation(e){I(e);let n=i.readSubscriptionOperation;return u(t,n,e)}}}function oe(t){return{async redeemReward(e){return I(e),(await u(t,i.redeemReward,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid reward redemption",response:"Invalid reward receipt"})).redemption},async claimRewardProduct(e){return I(e),(await u(t,i.claimRewardProduct,e,{request:"Invalid reward product claim",response:"Invalid reward product checkout"})).checkout},async createReferralCode(e){return I(e),(await u(t,i.createReferralCode,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid referral program",response:"Invalid referral code"})).referralCode},async redeemCoupon(e,n=crypto.randomUUID()){let r=await u(t,i.redeemCoupon,{code:e,requestId:n},{request:"Invalid coupon code",response:"Invalid Coupon receipt"});return{offer:r.offer,reason:r.reason}},async claimCoupon(e,n=crypto.randomUUID()){let r=await u(t,i.grantOffer,{couponId:e,requestId:n},{request:"Invalid Coupon claim",response:"Invalid Coupon receipt"});return{offer:r.offer,reason:r.reason}},async listOffers(){return(await u(t,i.listOffers,{},{response:"Invalid offers response"})).offers}}}function se(t){return{...te(t),...ne(t),...re(t),...ie(t),...oe(t)}}function ae(t){return{async resolveContent(e){I(e);let n=i.resolveContent;return u(t,n,e)},async resolvePaywall(e){I(e);let n=i.resolvePaywall;return u(t,n,e)},async resolveOffering(e){I(e);let n=i.resolveOffering;return u(t,n,e)}}}var ce=t=>new TextEncoder().encode(JSON.stringify(t)).length,ue=16384;function de(t,e){let n=0,r,d=S=>{r={config:structuredClone(S),until:Date.now()+3e4}},p=[],c=null,m;function A(){if(!e())throw new a("NOT_IDENTIFIED","Call identify before using Features or events")}function h(){m||!p.length||(m=setTimeout(()=>{m=void 0,C().catch(()=>{}).finally(h)},5e3),typeof m=="object"&&"unref"in m&&m.unref())}function T(S,P={},O={}){if(A(),r&&Date.now()<r.until&&!Q(r.config,S))return;k();let q=i.trackEvents.request.parse({events:[{eventUuid:crypto.randomUUID(),timestamp:new Date().toISOString(),name:S,properties:P,...O}]}).events[0];if(ce({events:[q]})>ue)throw new a("INVALID_REQUEST","Event exceeds the delivery size limit");if(p.length>=500)throw new a("EVENT_QUEUE_FULL","Flush pending events before tracking more");p.push(structuredClone(q)),h()}async function C(S=!1){if(A(),c)return c;let P=n,O=(async()=>{let q={inserted:0,duplicates:0,rejected:0,skipped:0},o=p.length;for(;o&&P===n;){let s=[];for(let g of p.slice(0,Math.min(o,100))){if(s.length&&ce({events:[...s,g]})>ue)break;s.push(g)}let l=i.trackEvents,f=await u(t,l,{events:s},void 0,{keepalive:S});if(P!==n)throw new a("IDENTITY_CHANGED","Event identity changed during delivery");if(f.inserted+f.duplicates+f.rejected+f.skipped!==s.length)throw new a("INVALID_RESPONSE","Incomplete event acknowledgement");d(f.analyticsConfig),p.splice(0,s.length),o-=s.length,q.inserted+=f.inserted,q.duplicates+=f.duplicates,q.rejected+=f.rejected,q.skipped+=f.skipped}return q})();c=O;try{return await O}finally{c===O&&(c=null)}}let R;function k(){if(R||typeof document>"u")return;let S=()=>{document.visibilityState==="hidden"&&e()&&p.length&&C(!0).catch(()=>{})};document.addEventListener("visibilitychange",S),R=()=>document.removeEventListener("visibilitychange",S)}return{rememberConfiguration:d,track(S,P,O={}){return k(),T(S,P,O)},flush:C,reset(){n++,r=void 0,clearTimeout(m),m=void 0,p=[],c=null},detachVisibility(){R?.(),R=void 0}}}function pe(t){let e=t.merchandise;if(typeof t.merchandiseId=="string")return{internalId:t.merchandiseId};if(!(!e||typeof e!="object"||Array.isArray(e))){if(typeof e.internalId=="string")return{internalId:e.internalId};if(typeof e.externalId=="string")return{id:e.externalId};if(typeof e.id=="string")return{id:e.id}}}function ye(t){let e=pe(t),{merchandiseId:n,merchandise:r,...d}=t;return{...d,...e?{merchandise:e}:{}}}function le(t,e,n,r,d){if(d&&r&&(d.scope.projectId!==r.projectId||d.scope.environment!==r.environment))throw new a("SCOPE_MISMATCH","Configuration belongs to another App/environment");let p=0,c=new Set;function m(){if(!e())throw new a("NOT_IDENTIFIED","Call identify before using Features or events")}async function A(h={}){d||m();let T=p,C=!1,R=async()=>{if(C||T!==p)throw new a("IDENTITY_CHANGED","Feature identity changed");let v=i.getFeatures,y=d?{scope:{projectId:d.scope.projectId,environment:d.scope.environment},payload:await d.features()}:await u(t,v,{});if(T!==p)throw new a("IDENTITY_CHANGED","Feature identity changed");if(r&&(y.scope.projectId!==r.projectId||y.scope.environment!==r.environment))throw new a("INVALID_RESPONSE","Feature response scope changed");return n.rememberConfiguration(y.payload.analyticsConfig),y},k=await R(),S=!0,P,O=v=>{try{h.onError?.(v)}catch{}},q=(v,y,b)=>{try{let w=pe(b);n.track(v,y,w?{merchandise:w}:{})}catch(w){O(w)}},o=Y({assertUsable:d?.assertFeatures,scope:k.scope,attributes:h.attributes,onError:h.onError,load:async()=>S?(S=!1,k.payload):(await R()).payload,evaluateRemote:async v=>{if(T!==p)throw new a("IDENTITY_CHANGED","Feature identity changed");let y=i.evaluateFeatures,b=await u(t,y,{...v,attributes:ye(v.attributes)});if(b.scope.projectId!==k.scope.projectId||b.scope.environment!==k.scope.environment)throw new a("INVALID_RESPONSE","Remote Feature response scope changed");return{generation:b.generation,evaluatedAt:b.evaluatedAt,expiresAt:b.expiresAt,features:b.features,...b.merchandiseContext?{merchandiseContext:b.merchandiseContext}:{}}},onExperimentViewed:(v,y,b)=>q("Experiment Viewed",{experimentId:v.key,variationId:y.key},b),onFeatureUsage:(v,y,b)=>q("Feature Evaluated",{feature:v,value:y.value,source:y.source,ruleId:y.ruleId,...y.experimentResult?{variationId:y.experimentResult.key}:{}},b)}),s=o.refresh;function l(){clearTimeout(P),!d&&(C||T!==p||!o.expiresAt||(P=setTimeout(()=>{f().catch(O)},Math.min(2147483647,Math.max(1e3,Date.parse(o.expiresAt)-Date.now()))),typeof P=="object"&&"unref"in P&&P.unref()))}async function f(){try{return await s()}finally{l()}}let g=()=>{C||f().catch(O)},E=o.subscribe(l),N=d?.subscribe(()=>{!C&&d.fresh&&f().catch(O)});function D(){C||(C=!0,clearTimeout(P),typeof window<"u"&&window.removeEventListener("focus",g),E(),N?.(),o.reset(),c.delete(D))}c.add(D);try{await o.init(),(h.attributes?.merchandise||h.attributes?.merchandiseId)&&await o.refreshRemote()}catch(v){throw D(),v}return l(),!d&&typeof window<"u"&&window.addEventListener("focus",g),Object.assign(o,{refresh:f,destroy:D})}return{features:A,reset(h){p++,h();for(let T of c)T()}}}import{z as Ie}from"zod";function fe(t,e){let n="source"in e?{funnelId:e.source.id,funnelVersionId:e.source.versionId}:"versionId"in e?{funnelId:e.funnelId,funnelVersionId:e.versionId}:e,r=Ie.object({funnelId:L.shape.id,funnelVersionId:L.shape.versionId.optional()}).safeParse(n);if(!r.success)throw new a("INVALID_REQUEST","A valid Funnel source is required");let d=Object.freeze(r.data);function p(c){if("customerId"in c)throw new a("INVALID_REQUEST","Customer identity cannot be overridden");if("funnelId"in c&&c.funnelId!==void 0&&c.funnelId!==d.funnelId||"funnelVersionId"in c&&c.funnelVersionId!==void 0&&c.funnelVersionId!==d.funnelVersionId)throw new a("SCOPE_MISMATCH","The original Funnel source cannot change");return{...c,...d}}return{async claimCoupon(c,m=crypto.randomUUID()){let A=i.grantOffer,h=await u(t,A,p({couponId:c,requestId:m}));return{offer:h.offer,reason:h.reason}},async resolveOffering(c){let m=i.resolveOffering;return u(t,m,p(c))},async resolvePaywall(c){let m=i.resolvePaywall;return u(t,m,p(c))},async previewAttach(c){let m=i.previewAttach;return u(t,m,p(c))}}}function Pt(t){return he(t)}function he(t){let e=K(t),n=e.request,r=X(t.push,e,t.scope??t.configuration?.scope),d=ee(e,()=>{c.reset(p.reset),p.detachVisibility()},{beforeIdentify:r.identify,beforeReset:r.reset,afterChange:r.start}),p=de(n,d.isIdentified),c=le(n,d.isIdentified,p,t.scope,t.configuration);return{session:e.session,...Z(n,r),...se(n),...ae(n),forFunnel(m){return fe(n,m)},async features(m={}){return c.features(m)},track(m,A,h={}){return p.track(m,A,h)},flush(){return p.flush()},...d.methods}}function Nt(t){if(!j.test(t.customerToken))throw new a("INVALID_TOKEN","A customer credential is required");if(!t.scope)throw new a("INVALID_REQUEST","An explicit App and environment scope is required");let e=$({...t,scope:t.scope,apiKey:t.customerToken});return{async start(n){let r=await e.start(n),d=W({...t,runToken:r.runToken});d.identify(t.customerToken);let p=r.run.instruction?.type==="evaluate_segment"?await d.get():r;return{...r,...p,controller:d}}}}export{Pt as a,he as b,Nt as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as j,b as N,c as $,d as Y}from"./chunk-
|
|
1
|
+
import{a as j,b as N,c as $,d as Y}from"./chunk-5ZS3TNC4.js";import{a as D}from"./chunk-DSPLGTQI.js";import{a as O}from"./chunk-7XVAFQEE.js";import{b as U,e as _,g as C}from"./chunk-XSVQHPQT.js";var te=e=>new TextEncoder().encode(JSON.stringify({events:e})).length;function re(e,t){let n=e,r=o=>Number.isInteger(o)&&o>=0;return!!n&&typeof n=="object"&&r(n.inserted)&&r(n.duplicates)&&r(n.skipped)&&Array.isArray(n.rejected)&&n.inserted+n.duplicates+n.skipped+n.rejected.length===t}function V(e){let t=[],n,r=(a,i)=>e.log?.(`${e.label} ${a}`,i);function o(a){n===void 0&&t.length&&(n=setTimeout(()=>{u()},a))}async function s(a){let i;try{i=await e.fetch(e.endpoint,{method:"POST",body:JSON.stringify({events:a}),headers:{"Content-Type":"text/plain"},keepalive:!0,credentials:"omit"})}catch(p){return r("not sent",{error:p}),!1}if(i.status===408||i.status===429||i.status>=500)return r("not sent",{status:i.status}),!1;if(!i.ok)return r("rejected",{status:i.status,events:a.length}),!0;let f;try{f=await i.json()}catch{f=void 0}return re(f,a.length)?(f.rejected.length&&r("rejected",{rejected:f.rejected}),!0):(r("not acknowledged",{status:i.status}),!1)}function u(){clearTimeout(n),n=void 0;let a=[];for(;t.length&&a.length<20&&(!a.length||te([...a,t[0]].map(i=>i.event))<=65536);)a.push(t.shift());return a.length?s(a.map(i=>i.event)).then(i=>{if(i)return o(1e3);let f=a.filter(p=>++p.attempts<5);f.length<a.length&&r("dropped after retries",{events:a.length-f.length}),t.unshift(...f),o(5e3)}):Promise.resolve()}return{push(a){t.push({event:a,attempts:0}),t.length>=20?u():o(1e3)},flush:u}}async function q(e,t,n,r={}){let o=r.message??"Invalid SDK JSON response",s=e.headers.get("content-length");if(!e.ok||!/^application\/json(?:;|$)/i.test(e.headers.get("content-type")??"")||s!==null&&(!/^\d+$/.test(s)||Number(s)>t)||!e.body)throw e.body?.cancel().catch(()=>{}),Error(o);let u=e.body.getReader(),a=[],i=0,f=!1,p=()=>{},g=new Promise((v,h)=>{p=()=>h(Error(o)),n.addEventListener("abort",p,{once:!0}),n.aborted&&p()});try{for(;;){let m=await Promise.race([u.read(),g]);if(m.done){f=!0;break}if(i+=m.value.byteLength,i>t)throw Error(o);a.push(m.value)}let v=new Uint8Array(i),h=0;for(let m of a)v.set(m,h),h+=m.length;return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(v))}finally{n.removeEventListener("abort",p),f||u.cancel().catch(()=>{}),u.releaseLock()}}async function B(e,t){let n=e?.body;if(!n)return;let r=n.getReader(),o=0,s=!1,u,a=new Promise((p,g)=>{u=setTimeout(()=>g(Error("Exposure response timeout")),2e3)}),i=()=>{},f=new Promise((p,g)=>{i=()=>g(t?.reason),t?.addEventListener("abort",i,{once:!0}),t?.aborted&&i()});try{for(;;){let p=await Promise.race([r.read(),a,f]);if(p.done){s=!0;return}if(o+=p.value.byteLength,o>16384)throw Error("Exposure response budget")}}finally{clearTimeout(u),t?.removeEventListener("abort",i),s||r.cancel().catch(()=>{}),r.releaseLock()}}var fe=2*1024*1024,J=256*1024;async function G(e,t,n,r){let o=()=>{},s=new Promise((u,a)=>{o=()=>a(r.reason),r.addEventListener("abort",o,{once:!0}),r.aborted&&o()});try{let u=e(t,{...n,signal:r});return u.then(a=>{r.aborted&&a.body?.cancel().catch(()=>{})},()=>{}),await Promise.race([u,s])}finally{r.removeEventListener("abort",o)}}async function pe(e,t,n,r=!1){if(new TextEncoder().encode(n).byteLength>65536)throw Error("Exposure request budget");let o=new URL(t);o.searchParams.set("sdkVersion",O.version);let s=new AbortController,u=setTimeout(()=>s.abort(Error("Exposure request timeout")),5e3);try{let a=await G(e,o.href,{method:"POST",headers:{"Content-Type":"text/plain"},body:n,credentials:"omit",keepalive:r,redirect:"error"},s.signal);await B(a,s.signal)}finally{clearTimeout(u)}}function M(e){let t,n=!1;return{async read(r,o){if(n)throw Error("Experiment client stopped");t?.abort(Error("Experiment request superseded"));let s=new AbortController;t=s;let{signal:u}=s,a=setTimeout(()=>s.abort(Error("Experiment request timeout")),5e3);try{let i=await G(e,r,{cache:"no-cache",credentials:"omit",redirect:"error"},u),f=await q(i,o,u);return u.throwIfAborted(),f}finally{clearTimeout(a),t===s&&(t=void 0)}},destroy(){n=!0,t?.abort(Error("Experiment client stopped")),t=void 0}}}/*!
|
|
2
2
|
Portions ported from GrowthBook sdk-js @ ed29827 (GrowthBook.ts auto experiments, util.ts mergeQueryStrings,
|
|
3
3
|
plugins/auto-attributes.ts). Copyright (c) GrowthBook, Inc. MIT License.
|
|
4
4
|
*/function ne(e,t){let n,r;try{n=new URL(e),r=new URL(t)}catch{return t}return n.searchParams.forEach((o,s)=>{r.searchParams.has(s)||r.searchParams.set(s,o)}),r.toString()}function oe(e,t){let n=navigator.userAgent,r=new URLSearchParams(t.search),o={};for(let s of["source","medium","campaign","term","content"]){let u=r.get(`utm_${s}`);u!==null&&(o[`utm${s[0].toUpperCase()}${s.slice(1)}`]=u)}return{id:e,deviceId:e,url:t.href,path:t.pathname,host:t.host,query:t.search,pageTitle:typeof document>"u"?"":document.title,browser:/Edg/.test(n)?"edge":/Chrome/.test(n)?"chrome":/Firefox/.test(n)?"firefox":/Safari/.test(n)?"safari":"unknown",deviceType:/Mobi/.test(n)?"mobile":"desktop",...o}}function ie(e){let t=e;if(!(!!t&&typeof t=="object"&&typeof t.environmentId=="string"&&typeof t.trackExposures=="boolean"&&/^[a-f0-9]{64}$/.test(t.generation??"")&&Array.isArray(t.experiments)&&t.experiments.length<=100&&t.experiments.every(r=>!!r&&!["namespace","status","url","groups"].some(o=>Object.hasOwn(r,o))&&(r.hashVersion===void 0||r.hashVersion===2)&&typeof r.key=="string"&&Array.isArray(r.variations)&&r.variations.length>=2&&r.variations.every(o=>!!o&&typeof o.urlRedirect=="string")&&(r.urlPatterns===void 0||Array.isArray(r.urlPatterns)))&&!!t.savedGroups&&typeof t.savedGroups=="object"&&!Array.isArray(t.savedGroups)))throw new Error("Invalid page experiment payload");return t}function be(e){if(e.configuration&&e.configuration.scope.environmentId!==e.environmentId)throw new Error("Page configuration belongs to another App environment");let t=$(e.baseUrl);if(!/^[0-9a-f-]{36}$/i.test(e.environmentId))throw new Error("environmentId must be the App environment ID");let n=e.fetch??globalThis.fetch.bind(globalThis),r=M(async(c,d)=>{let l=await n(c,d);if(!l.ok)throw l.body?.cancel().catch(()=>{}),new Error(`Page experiments unavailable (${l.status})`);return l}),o=e.log?(c,d)=>D(e.log,c,d):void 0,s=`${t}/api/v1/page-experiments/${e.environmentId}`,u=j(e.deviceIdCookie??"indiana_did"),a=N(),i=null,f={...e.attributes??{}},p="",g=!1,v=!1,h=0,m=0,w=new Map,T=V({endpoint:`${s}/events`,fetch:n,log:o,label:"Exposure"}),P=T.flush,E={trackedExperiments:new Set,log:o,onExperimentViewed:(c,d)=>{e.trackExposures===!1||i?.trackExposures===!1||T.push({eventUuid:crypto.randomUUID(),timestamp:new Date().toISOString(),deviceId:u,...a?{sessionId:a}:{},url:location.href,pageTitle:document.title.slice(0,512),experimentKey:c.key,variationKey:d.key})}},H=()=>{E.url=location.href,E.attributes={...oe(u,location),...f}};function Q(c){if(!e.disableCrossOriginUrlRedirects)return!1;try{let d=new URL(location.href);return c.variations.some(l=>{if(!l.urlRedirect)return!1;let y=new URL(l.urlRedirect);return y.protocol!==d.protocol||y.host!==d.host})}catch{return!0}}function K(c,d){let l=e.configuration?.snapshot?.generation,y=m,z=location.href;p=c;let W=e.navigate??(x=>location.replace(x)),Z=e.navigateDelay??(e.navigate?0:100),ee=e.maxNavigateDelay??1e3;Promise.all([Promise.race([d,new Promise(x=>setTimeout(x,ee))]),new Promise(x=>setTimeout(x,Z))]).then(()=>{!g&&y===m&&location.href===z&&(!e.configuration||e.configuration.fresh&&e.configuration.snapshot?.generation===l)&&W(c)})}function b(){if(!(!i||g||e.configuration&&!e.configuration.fresh)){H();for(let c of i.experiments){if(Q(c)){o?.("Auto experiment blocked",{id:c.key});continue}let d;try{d=C(c,E)}catch(l){o?.("Skipping page experiment",{id:c.key,error:String(l)});continue}if(w.set(c.key,d),!!d.inExperiment){if(d.value.urlRedirect){let l=c.persistQueryString?ne(location.href,d.value.urlRedirect):d.value.urlRedirect;U(l,c.urlPatterns??[])?o?.("Skipping redirect because original URL matches redirect URL",{id:c.key}):l!==p&&K(l,P())}break}}}}let R="",F=()=>{location.href!==R&&(m++,R=location.href,p="",b())},A,S;function X(){A??=Y(F),addEventListener("pagehide",L)}let L=()=>{P()};async function k(){if(g)return!1;let c=++h,d;try{d=e.configuration?await e.configuration.pageExperiments():await r.read(s,J)}catch(y){if(g||c!==h)return!1;throw y}if(g||c!==h)return!1;let l=ie(d);if(l.environmentId.toLowerCase()!==e.environmentId.toLowerCase())throw new Error("Page experiment payload scope changed");return i?.trackExposures===!1&&l.trackExposures&&E.trackedExperiments?.clear(),i=l,E.savedGroups=_(l.savedGroups),!0}function I(){g||(S??=e.configuration?.subscribe(()=>{!g&&e.configuration?.fresh&&k().then(c=>{c&&b()}).catch(c=>o?.("Page configuration unavailable",{error:String(c)}))}),X(),R=location.href)}return{async start(){v||g||(v=!0,await k()&&(I(),b()))},async refresh(){await k()&&(m++,v&&I(),p="",b())},setAttributes(c){m++,p="",f={...c},b()},getResults(){return new Map(w)},get generation(){return i?.generation??null},destroy(){g||(g=!0,h++,r.destroy(),S?.(),A?.(),removeEventListener("pagehide",L),i=null,w.clear(),P())}}}export{fe as a,pe as b,M as c,ne as d,oe as e,ie as f,be as g};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as t}from"./chunk-RP2P3FU4.js";import{Ga as n}from"./chunk-U4UEOR5W.js";function r(e,o,a){return n(e,o,a,t)}export{r as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ia as E,ja as M,ka as j,la as O,ma as T}from"./chunk-
|
|
1
|
+
import{ia as E,ja as M,ka as j,la as O,ma as T}from"./chunk-U4UEOR5W.js";import{k as w,qa as u}from"./chunk-ACF2FBUB.js";import{z as t}from"zod";var _=E,V=t.string().regex(/^(0|[1-9]\d{0,5})(\.\d{1,12})?$/),C=t.strictObject(Object.fromEntries(_.map(i=>[i,t.number().int().nonnegative().max(1e9)]))),L=M,D=j,q=t.strictObject({modelId:L,source:t.enum(["models.dev","custom"]),fetchedAt:t.iso.datetime(),rates:O,contextTier:t.number().int().nonnegative(),markupPercent:D}),U=t.strictObject({pricing:q,tokens:C,quantity:w,digest:t.string().regex(/^[a-f0-9]{64}$/)}),z=i=>{let[s,o=""]=i.split(".");return BigInt(s)*10n**12n+BigInt(o.padEnd(12,"0"))};function $(i){if(typeof i!="number"||!Number.isFinite(i)||i<0)throw new u("AI_PRICE_UNAVAILABLE","A published token price is missing");let s=String(i),o=s.includes("e")?i.toFixed(12).replace(/0+$/,"").replace(/\.$/,""):s;if(Number(o)!==i||!V.safeParse(o).success)throw new u("AI_PRICE_UNAVAILABLE","Published price exceeds the supported precision");return o}var R=t.strictObject({input:t.number().nonnegative(),output:t.number().nonnegative(),cache_read:t.number().nonnegative().optional(),cache_write:t.number().nonnegative().optional(),reasoning:t.number().nonnegative().optional(),input_audio:t.number().nonnegative().optional(),output_audio:t.number().nonnegative().optional()}),F=R.extend({context_over_200k:t.unknown().optional(),tiers:t.array(R.extend({tier:t.strictObject({type:t.literal("context"),size:t.number().int().nonnegative()})})).max(20).refine(i=>new Set(i.map(s=>s.tier.size)).size===i.length).optional()});async function N(i,s,o){let d=new TextEncoder().encode(JSON.stringify({pricing:i,tokens:s,quantity:o}));return[...new Uint8Array(await crypto.subtle.digest("SHA-256",d))].map(m=>m.toString(16).padStart(2,"0")).join("")}function B(i,s){let o=0n;for(let c of _){if(!s[c])continue;let f=i.rates[c];if(f===void 0)throw new u("AI_PRICE_UNAVAILABLE",`No published price for ${c}; report exclusive token pools`);o+=z(f)*BigInt(s[c])}let[d,m="0"]=String(i.markupPercent).split("e"),r=(d.split(".")[1]?.length??0)-Number(m),e=10n**BigInt(Math.max(r,0)),n=BigInt(d.replace(".",""))*10n**BigInt(Math.max(-r,0)),g=100n*e+n,l=100n*e*1000000n,a=(o*g+l-1n)/l;return w.parse(`${a/1000000n}.${(a%1000000n).toString().padStart(6,"0")}`)}function K(i={}){if(typeof window<"u")throw new u("SERVER_ONLY","AI token pricing belongs on your backend");let s=T.parse({defaultMarkup:i.defaultMarkup??0,providerMarkups:i.providerMarkups??{},modelMarkups:i.modelMarkups??{},customModels:i.customModels??{}}),o=null,d=0;async function m(){if(!o||Date.now()>=d){d=Date.now()+15*6e4;let r=(async()=>{let e=await(i.fetch??fetch)("https://models.dev/api.json",{signal:AbortSignal.timeout(3e4)});if(!e.ok)throw new u("AI_PRICE_UNAVAILABLE","Models.dev pricing is unavailable");return{data:t.record(t.string(),t.object({models:t.record(t.string(),t.unknown())})).parse(await e.json()),fetchedAt:new Date().toISOString()}})().catch(e=>{throw o===r&&(o=null),e});o=r}return o}return{refreshPrices(){o=null,d=0},async quoteTokens(r){let e=L.parse(r.modelId),n=C.parse(r.tokens),[g,...l]=e.split("/"),a=s.customModels[e],c,f,p,y=0;if(a?.input!==void 0&&a.output!==void 0&&_.every(A=>n[A]===0||a[A]!==void 0))c={...a,input:a.input,output:a.output},f="custom",p=new Date().toISOString();else{let A=await m(),x=A.data[g]?.models[l.join("/")];if(!x)throw new u("AI_PRICE_UNAVAILABLE","Unknown model; configure a complete custom price");let{cost:I}=t.object({cost:F}).parse(x),P=n.input+n.cache_read+n.cache_write+n.input_audio;if(I.tiers===void 0&&I.context_over_200k!==void 0&&P>2e5)throw new u("AI_PRICE_UNAVAILABLE","A current context tier is required for this model");let b=I.tiers?.filter(k=>P>k.tier.size).sort((k,Q)=>Q.tier.size-k.tier.size)[0],v=b??I;b&&(y=b.tier.size),c=Object.fromEntries(_.filter(k=>v[k]!==void 0).map(k=>[k,$(v[k])])),c={...c,...a},f=a?"custom":"models.dev",p=A.fetchedAt}let h=q.parse({modelId:e,source:f,fetchedAt:p,rates:c,contextTier:y,markupPercent:s.modelMarkups[e]??s.providerMarkups[g]??s.defaultMarkup}),S=B(h,n);return U.parse({pricing:h,tokens:n,quantity:S,digest:await N(h,n,S)})},async trackTokens(r,e){let n=U.parse(e.quote);if(n.quantity!==B(n.pricing,n.tokens)||n.digest!==await N(n.pricing,n.tokens,n.quantity))throw new u("INVALID_REQUEST","AI quote changed after pricing");let g=e.properties??{},l=e.providerCostUsd===void 0?void 0:t.string().regex(/^(0|[1-9]\d{0,11})(\.\d{1,18})?$/).parse(e.providerCostUsd),a=e.generationId===void 0?void 0:t.string().min(1).max(120).parse(e.generationId),c=8+ +(l!==void 0)+ +(a!==void 0);if(Object.keys(g).some(p=>p.startsWith("ai_")))throw new u("INVALID_REQUEST","AI tracking reserves ai_ event properties");if(Object.keys(g).length>16-c)throw new u("INVALID_REQUEST","AI tracking properties exceed the available event budget");let f={operation:"consume",internal_feature_id:e.internal_feature_id,quantity:n.quantity,idempotencyKey:e.idempotencyKey,properties:{...g,...l!==void 0?{ai_provider_cost_usd:l}:{},...a!==void 0?{ai_generation_id:a}:{},ai_model:n.pricing.modelId,ai_source:n.pricing.source,ai_price_at:n.pricing.fetchedAt,ai_quote_hash:n.digest,ai_markup:String(n.pricing.markupPercent),ai_tier:String(n.pricing.contextTier),ai_tokens:_.map(p=>n.tokens[p]).join(","),ai_rates:"v1:"+_.map(p=>n.pricing.rates[p]===void 0?"-":z(n.pricing.rates[p]).toString(36)).join(",")},...e.entityId?{entityId:e.entityId}:{}};return r.mutateBalance({customerId:e.customerId,command:f})}}}async function Y(i,s,o={}){let{config:d,model_markups:m}=await i.readAiPricing(s);return K({defaultMarkup:d.default_markup??0,providerMarkups:Object.fromEntries(Object.entries(d.provider_markups??{}).map(([r,e])=>[r,e.markup])),modelMarkups:Object.fromEntries(Object.entries(m??{}).filter(([,r])=>r.markup!==void 0).map(([r,e])=>[r,e.markup])),customModels:Object.fromEntries(Object.entries(m??{}).filter(([,r])=>r.input_cost!==void 0||r.output_cost!==void 0).map(([r,e])=>[r,{...e.input_cost!==void 0?{input:String(e.input_cost)}:{},...e.output_cost!==void 0?{output:String(e.output_cost)}:{}}])),...o})}export{q as a,U as b,K as c,Y as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as Ie}from"./chunk-MOWYD2TV.js";import{a as ce,b as ye,c as ge,d as ve,e as he}from"./chunk-SBPTOOYB.js";import{M as me,Y as ue}from"./chunk-U4UEOR5W.js";import{ea as fe,oa as we,qa as y}from"./chunk-ACF2FBUB.js";import{b as be,e as Ee}from"./chunk-SLUA7ABW.js";import{d as Ce}from"./chunk-5ZS3TNC4.js";import{a as B}from"./chunk-DSPLGTQI.js";import{b as pe}from"./chunk-XSVQHPQT.js";function Pe(e){let h=e.view;if(!h?.paywall)throw new y("INVALID_REQUEST","The current node is not a Paywall");let t=h.paywall.receiptId,P=h.nodeId,c=h.visit,m=h.paywall.resolution,d=m,w="document"in m?m:null;function a(n){if(!ye(n,m))throw new y("INVALID_RESPONSE","The pinned Paywall binding changed")}let o=h.paywall.quote,D=h.paywall.operation,I=!1,L=new AbortController,f=h.paywall.purchaseRequestId,r=0,p=h.paywall.selectionGeneration??0,k=h.paywall.canReselect===!0,T=null,b=new Map,q=new Map,S=new Map;function R(n){if(n.purchase&&n.purchase.receiptId!==t)throw new y("INVALID_RESPONSE","Purchase receipt changed");let s=n.run.paywall;return n.purchase??(s?.receiptId===t?s:null)}function F(){if(I)throw new y("IDENTITY_CHANGED","Paywall presentation has closed")}function A(n,s,l){if(F(),s!==r||l!==void 0&&o?.operationId!==l)return!1;let C=p,u=n.run.paywall;if(u?.receiptId===t){if((u.selectionGeneration??0)<p)return!1;p=u.selectionGeneration??0,k=u.canReselect===!0,a(u.resolution)}let v=R(n),g=p>C,N=g?v?.quote??null:v?.quote??o,_=v?.operation??(N?.operationId===o?.operationId?D:null);return N&&_&&ge(_,{operationId:N.operationId},"Purchase operation changed"),u?.receiptId===t&&(d=u.resolution,w="document"in d?d:w?{...d,document:w.document,offering:w.offering,capabilities:ce(d.capabilities,w.capabilities)}:null),(g||N?.operationId!==o?.operationId)&&(r++,u?.receiptId===t&&(f=u.purchaseRequestId)),o=N,D=he(D,_,!0),!0}function j(n,s,l){return new Promise((C,u)=>{let v=!1,g=()=>{clearTimeout(x),L.signal.removeEventListener("abort",M)},N=z=>{v||(v=!0,g(),C(z))},_=z=>{v||(v=!0,g(),u(z))},M=()=>_(new y("IDENTITY_CHANGED","Paywall presentation has closed")),x=setTimeout(()=>_(new y("COMMAND_PENDING","The purchase command is still pending; retry the original request",202,l)),Math.max(0,s-Date.now()));L.signal.addEventListener("abort",M,{once:!0}),L.signal.aborted&&M(),n.then(N,_)})}function G(n){return new Promise(s=>{let l=()=>{clearTimeout(C),L.signal.removeEventListener("abort",l),s()},C=setTimeout(l,n);L.signal.addEventListener("abort",l,{once:!0}),L.signal.aborted&&l()})}async function W(n,s,l){F();let C=b.get(n);if(!C){let g=e.pendingCommands?.find(N=>N.requestId===n)??e.pendingCommand;if(g?.operation==="submit"&&g.requestId===n&&g.nodeId===P&&g.visit===c){s.type==="paywall_quote"&&g.input.type==="paywall_quote"&&g.input.predecessor&&!s.predecessor&&(s={...s,predecessor:g.input.predecessor});let N=ue.parse(g),_=ue.parse({...g,input:s});if(_.operation!=="submit"||N.operation!=="submit"||JSON.stringify(_.input)!==JSON.stringify(N.input))throw new y("CONFLICT","A restored purchase request cannot change its input");s=_.input,C=N,b.set(n,C)}}if(C){if(JSON.stringify(C.input)!==JSON.stringify(s))throw new y("CONFLICT","A purchase request cannot change its input")}else{let g=e.view;if(!g||g.nodeId!==P||g.visit!==c||g.paywall?.receiptId!==t)throw new y("PRECONDITION_FAILED","The Paywall visit has changed");C={operation:"submit",requestId:n,nodeId:P,visit:c,revision:g.revision,input:s},b.set(n,C)}let u=Date.now()+3e4,v=await j(e.submit(C),u,n);for(;v.run.pendingRequest?.requestId===n&&Date.now()<u&&!I&&(await G(Math.min(1e3,u-Date.now())),!(I||Date.now()>=u));)v=await j(e.resume(n),u,n);if(I)throw new y("IDENTITY_CHANGED","Paywall presentation has closed");if(v.run.pendingRequest?.requestId===n)throw new y("COMMAND_PENDING","The purchase command is still pending; retry the original request",202,n);if(!A(v,l,s.type==="paywall_confirm"||s.type==="paywall_cancel"?s.operationId:void 0))throw new y("PRECONDITION_FAILED","The purchase selection has changed")}async function J(n){if(!o)throw new y("INVALID_REQUEST","A quoted purchase is required");let s=`${n}:${o.operationId}`,l=q.get(s);if(!l){let C=n==="confirm"?"paywall_confirm":"paywall_cancel",u=e.pendingCommands?.find(v=>v.operation==="submit"&&v.input.type===C&&"operationId"in v.input&&v.input.operationId===o.operationId)??e.pendingCommand;l=u?.operation==="submit"&&u.input.type===C&&"operationId"in u.input&&u.input.operationId===o.operationId?u.requestId:crypto.randomUUID(),q.set(s,l)}if(await W(l,{type:n==="confirm"?"paywall_confirm":"paywall_cancel",operationId:o.operationId},r),!D)throw new y("INVALID_RESPONSE","The accepted purchase result is missing");return structuredClone(D)}return{get view(){return structuredClone(w)},get quote(){return o?structuredClone(o):null},get operation(){return D?structuredClone(D):null},get webViewUrl(){return e.webViewUrl},get canReselect(){return k},async refresh(){F();let n=r,s=await e.get();if(A(s,n),s.run.paywall?.receiptId!==t)throw new y("PRECONDITION_FAILED","Paywall presentation has changed");if(!w){if("document"in d||!e.resolvePaywall)throw new y("INVALID_RESPONSE","Public Paywall reader is unavailable");let l=await e.resolvePaywall(d);F(),a(l),w={...d,document:l.document,offering:l.offering,capabilities:ce(d.capabilities,l.capabilities)}}return structuredClone(w)},preview(n){if(!w)return Promise.reject(new y("PRECONDITION_FAILED","Load the Paywall presentation first"));if(f&&f!==n.requestId&&(T||!k))return Promise.reject(new y("COMMAND_PENDING","Retry the original purchase before starting another"));let s=w.document.buttons[n.actionId],l=s?.type==="checkout"?me(s.product,n.selection,w.capabilities):null;if(!l)return Promise.reject(new y("PRODUCT_UNAVAILABLE","Choose an available Product in this purchase area"));let C=we(w.document.screen,l,n.selection,w.capabilities),u=JSON.stringify({actionId:n.actionId,product:l,featureQuantities:C,offerId:n.offerId,nativeOffer:n.nativeOffer});if(S.has(n.requestId)&&S.get(n.requestId)!==u)return Promise.reject(new y("CONFLICT","A purchase request cannot change its quantities or Product"));if(S.set(n.requestId,u),f===n.requestId&&T)return T;let v=f!==n.requestId&&p>0?{operationId:o?.operationId??null,generation:p}:void 0;if(v&&(!k||p<=0))return Promise.reject(new y("COMMAND_PENDING","Original purchase requires authoritative termination"));f!==n.requestId&&r++;let g=r;f=n.requestId;let N=(async()=>{if(await W(n.requestId,{type:"paywall_quote",actionId:n.actionId,productVersionId:l,...Object.keys(C).length?{featureQuantities:C}:{},...v?{predecessor:v}:{},...n.offerId?{offerId:n.offerId}:{},...n.nativeOffer?{nativeOffer:n.nativeOffer}:{}},g),!o)throw new y("INVALID_RESPONSE","The accepted quote is missing");return ve(o,{productVersionId:l,featureQuantities:C},"The selected purchase changed"),structuredClone(o)})();return T=N,N.then(()=>{T===N&&(T=null)},_=>{T===N&&(T=null),f===n.requestId&&e.pendingCommand?.requestId!==n.requestId&&_ instanceof y&&_.status!==void 0&&_.status<500&&![401,425].includes(_.status)&&(f=null)}),N},confirm:()=>J("confirm"),cancel:()=>J("cancel"),async read(){if(F(),!o)throw new y("INVALID_REQUEST","A quoted purchase is required");let n=o.operationId,s=r,l=e.pendingCommands?.find(g=>g.operation==="submit"&&(g.input.type==="paywall_confirm"||g.input.type==="paywall_cancel")&&g.input.operationId===n)??e.pendingCommand;l?.operation==="submit"&&(l.input.type==="paywall_confirm"||l.input.type==="paywall_cancel")&&l.input.operationId===n&&await e.settle?.(l.requestId);let C=await e.get(void 0,{receiptId:t,operationId:n});F();let u=R(C);if(u?.quote&&u.quote.operationId!==n||u?.operation&&u.operation.operationId!==n)throw new y("INVALID_RESPONSE","Purchase operation changed");let v=A(C,s,n)?D:u?.operation;if(!v)throw new y("INVALID_RESPONSE","The current purchase result is missing");return structuredClone(v)},destroy(){I=!0,L.abort(),b.clear(),q.clear(),S.clear()}}}function Re(e){let h=new Set,t=new Set,P=null;function c(m){if(e.reviewing||h.has(m)||t.has(m)||e.stopped)return;t.add(m);let d=async()=>{if(e.reviewing||e.stopped||e.key!==m){t.delete(m);return}if(e.busy||e.client.pendingCommand){setTimeout(()=>{d()},250);return}let w=(async()=>{let o=e.client.view,D=e.expected(),I=D.requestId,L=!1;try{await e.client.submit({operation:"shown",...D})}catch(f){if(!(f instanceof y)||f.code!=="CONFLICT"||f.status!==409||e.client.pendingCommand)throw f;await e.client.get();let r=e.client.view;if(e.stopped||e.reviewing||e.key!==m||!r||!o||r.id!==o.id||r.source.versionId!==o.source.versionId||r.nodeId!==D.nodeId||r.visit!==D.visit||r.revision<=D.revision||r.stopped||!r.screen||!["running","waiting"].includes(r.status)||e.client.pendingCommand)throw f;let p=e.expected();I=p.requestId,await e.client.submit({operation:"shown",...p})}for(;!e.stopped&&e.key===m&&e.client.pendingCommand?.requestId===I;){if(!e.client.settle)throw new y("COMMAND_PENDING","The original display acknowledgement is still pending");await e.client.settle(I),L=!0,e.client.pendingCommand?.requestId===I&&await new Promise(f=>setTimeout(f,1500))}e.stopped||e.key!==m||(L&&await e.client.get(),!(e.stopped||e.key!==m)&&h.add(m))})();P=w;let a=()=>{P===w&&(P=null),t.delete(m)};w.then(a,o=>{a(),e.busy||e.fail(o)})};d()}return{report:c,get inFlight(){return P}}}function De(e){let h={},t=new Map;async function P(c){let m=e.client.view,d=m?.screen,w=d?.customerData.nodes[c.nodeId];if(e.stopped||e.busy||!m||!d||!w)return;if(!["refresh","next","previous","filter","sources_next","sources_previous"].includes(c.action)){let r=e.document,p=r?fe(r,c.nodeId):null,k=p?.type==="customer_data"?p.data.outputs?.[c.action]:void 0;k&&d.outputs.includes(k)?await e.perform(()=>e.client.submit({operation:"submit",...e.expected(),input:{type:"screen",output:k,answers:e.answers,selection:c.value?{[c.nodeId]:c.value}:{}}})):await e.onIntent?.(c,m);return}let o=c.action.startsWith("sources_")?w.resources.find(r=>r.key===c.value):null;if(c.action.startsWith("sources_")&&!o)throw new y("INVALID_REQUEST","Choose a current resource");let D=`${m.visit}:${c.nodeId}:${o?.key??""}`,I=t.get(D)??[null],f=h[c.nodeId]??{page:1,after:null,filter:"all",...o?{resourceKey:o.key}:{}};if(c.action==="filter"){let r=c.value;if(!r||!(w.source==="offer_history"?["all","issued","reserved","redeemed","expired","revoked"]:["all","purchase","refund","source","usage","debt","settlement"]).includes(r))throw new y("INVALID_REQUEST","Unknown data filter");f={page:1,after:null,filter:r},I.splice(0,I.length,null)}else if(c.action==="next"||c.action==="sources_next"){let r=o?.sources.at(-1),p=o?r?{kind:"ledger",cursor:{at:r.detail[0],id:r.id,type:"source"}}:null:d.dataCursors[c.nodeId];if(!p||!o&&!w.hasNext)return;I[f.page]=p,f={...f,page:f.page+1,after:p}}else if(c.action==="previous"||c.action==="sources_previous"){if(f.page<=1)return;f={...f,page:f.page-1,after:I[f.page-2]??null}}t.set(D,I),h={...h,[c.nodeId]:f},await e.perform(()=>e.client.get({nodeId:m.nodeId,visit:m.visit,revision:m.revision,components:h}))}return{get queries(){return h},intent:P,reset(){h={},t.clear()}}}function Se(e){let{doc:h,holder:t,reviewHolder:P,mountScreenPreview:c}=e,m=!1,d,w=0,a=null,o="",D=new Map,I=r=>r?`${r.id}:${r.nodeId}:${r.visit}:${r.revision}:${r.paywall?.quote?.operationId??""}`:"";async function L(r){if(e.stopped||!e.client.review)return;m||(o=I(e.client.view),D.set(o,structuredClone(e.answers))),m=!0,d=r,t.hidden=!0,e.suspend(!0),P.hidden=!1;let p=++w;try{let k=await e.client.review(r);if(e.stopped||p!==w||!m)return;if(!k.review)throw new y("INVALID_RESPONSE","Historical projection is missing");a?.destroy(),a=null,P.replaceChildren();let T=k.run.locale.startsWith("zh"),b=h.createElement("p");b.textContent=T?"\u53EA\u8BFB\u56DE\u770B":"Read-only history",P.append(b);for(let[R,F]of k.review.pages.entries()){let A=h.createElement("button");A.type="button",A.textContent=T?`\u7B2C ${R+1} \u9875`:`Page ${R+1}`,A.onclick=()=>{L(F.receiptId)},P.append(A)}if(k.review.page){let R=k.review.page,F=h.createElement("div");if(F.inert=!0,P.append(F),a=c(F,{mode:"live",rendererUrl:e.client.webViewUrl,title:R.document.name,onAction:()=>{},onAnswers:()=>{},onCustomerDataIntent:()=>{},onRendered:()=>{},onEscape:()=>{f()}}),a.update(R.document,k.run.locale,{serverInput:{bindings:R.inputs,answers:R.answers,values:R.values}}),await a.ready,e.stopped||p!==w||!m)return}let q=T?{issued:"\u5DF2\u9886\u53D6",reserved:"\u5DF2\u9884\u7559",redeemed:"\u5DF2\u4F7F\u7528",expired:"\u5DF2\u8FC7\u671F",revoked:"\u5DF2\u64A4\u9500",unknown:"\u72B6\u6001\u5F85\u786E\u8BA4"}:{issued:"Issued",reserved:"Reserved",redeemed:"Used",expired:"Expired",revoked:"Revoked",unknown:"Status unconfirmed"},S=T?{pending:"\u5904\u7406\u4E2D",complete:"\u5DF2\u5B8C\u6210",cancelled:"\u5DF2\u53D6\u6D88",failed:"\u5931\u8D25",unknown:"\u72B6\u6001\u5F85\u786E\u8BA4"}:{pending:"Processing",complete:"Completed",cancelled:"Cancelled",failed:"Failed",unknown:"Status unconfirmed"};for(let R of[...k.review.coupons.map((F,A)=>`${T?"\u4F18\u60E0\u5238":"Coupon"} ${A+1}: ${q[F.status]}`),...k.review.purchases.map((F,A)=>`${T?"\u8D2D\u4E70":"Purchase"} ${A+1}: ${S[F.status]}`)]){let F=h.createElement("p");F.textContent=R,P.append(F)}e.client.view&&await e.enqueue(e.client.view)}catch(k){if(p!==w||e.stopped)return;a?.destroy(),a=null,P.replaceChildren(),e.fail(k)}}async function f(){if(!m||e.stopped||!e.client.review)return;let r=++w;try{if(await e.client.review(),e.stopped||r!==w)return;m=!1,w++,a?.destroy(),a=null,P.replaceChildren(),P.hidden=!0,t.hidden=!1;let p=e.client.view;I(p)!==o?(D.set(o,structuredClone(e.answers)),e.resetScreen()):(D.delete(o),e.suspend(!1)),p&&await e.enqueue(p)}catch(p){if(r!==w||e.stopped)return;a?.destroy(),a=null,P.replaceChildren(),e.fail(p)}}return{get active(){return m},get receipt(){return d},open:L,exit:f,get drafts(){return new Map([...D].map(([r,p])=>[r,structuredClone(p)]))},stop(){m=!1,w++,a?.destroy(),a=null,P.replaceChildren(),P.hidden=!0,t.hidden=!1}}}function Fe(e){if(!e.client.pageExperiments)throw new Error("The Run controller does not support page experiments");let h=e.client.pageExperiments.bind(e.client),t=!1,P=!1,c=0,m=!1,d=!1,w,a=new Map,o=new Set,D={},I=new Map,L=be(e.appManifestRelease),f=()=>{for(let q of a.values())q.effect.revert();a.clear();for(let q of I.values())q();I.clear()};function r(q){if(t||o.has(q))return;o.add(q);let S=c;h(e.appManifestRelease,[q]).catch(R=>{o.delete(q),!t&&S===c&&B(e.onError,R)})}async function p(){if(t)return;let q=e.client.view;if(!q||q.stopped||!["running","waiting"].includes(q.status)){c++,f();return}if(m){d=!0;return}m=!0;let S=++c,R=`${q.id}:${q.visit}:${q.revision}`,F=location.href;try{let[A,{applyVisualVariation:j}]=await Promise.all([h(e.appManifestRelease),import("./visual-dom-OIXANRP3.js")]),G=e.client.view;if(t||S!==c||!G||G.stopped||!["running","waiting"].includes(G.status)||`${G.id}:${G.visit}:${G.revision}`!==R||location.href!==F)return;let W=new Set,J=new Set;for(let n of A.assignments){let s=`${A.payload.environmentId}:${n.experimentKey}`;if(J.add(s),I.has(s)||I.set(s,Ee(s,D)),!!n.inExperiment)for(let l of A.payload.experiments){if(l.key!==n.experimentKey||!pe(location.href,l.urlPatterns??[]))continue;let C=l.meta?.findIndex(M=>M.key===n.variationKey)??-1,u=l.variations[C];if(!u?.renderGuard)continue;let v=n.receiptId+":"+l.changeId,g=JSON.stringify([n.variationKey,u]);W.add(v);let N=a.get(v);if(N?.signature===g){N.effect.applied&&r(n.receiptId);continue}a.get(v)?.effect.revert(),a.delete(v);let _=j(u,{requireUniqueTargets:!0,boundVariations:l.variations,allowJs:!1,onApplied:()=>r(n.receiptId),onError:M=>B(e.onError,M)});a.set(v,{signature:g,effect:_}),_.applied&&r(n.receiptId)}}for(let[n,s]of a)W.has(n)||(s.effect.revert(),a.delete(n));for(let[n,s]of I)J.has(n)||(s(),I.delete(n))}catch(A){S===c&&f(),!t&&S===c&&B(e.onError,A)}finally{m=!1,d&&!t&&(d=!1,p())}}let k=e.client.subscribe(()=>{c++,p()}),T=Ce(()=>{c++,f(),p()}),b=async()=>{await p(),t||(w=setTimeout(()=>{b()},15e3))};return{async start(){P||t||(P=!0,await b())},refresh:p,destroy(){t=!0,c++,clearTimeout(w),k(),T(),f(),L.destroy()}}}async function an(e,h){let t=h,{mountScreenPreview:P}=await import("./screen-renderer-NLB3FAQJ.js"),{showPaywall:c}=await import("./paywall-CDR4GZMX.js"),m=t.appManifestRelease?Fe({client:t.client,appManifestRelease:t.appManifestRelease,onError:t.onError}):void 0;m?.start();let d=e.ownerDocument,w=d.activeElement,a=d.createElement("section"),o=d.createElement("div"),D=d.createElement("div"),I=d.createElement("div"),L=d.createElement("button");I.hidden=!0,L.type="button";let f=d.createElement("p"),r=d.createElement("p"),p=d.createElement("button"),k=d.createElement("button"),T=d.createElement("button"),b=d.createElement("dialog"),q;a.dataset.indianaFunnel="",a.setAttribute("aria-busy","false"),a.style.cssText="box-sizing:border-box;width:100%;min-width:0;font:14px/1.5 system-ui,sans-serif;color:#172033;background:#fff",D.style.cssText="display:flex;gap:12px;align-items:center;flex-wrap:wrap;padding:12px 20px",f.setAttribute("role","status"),r.setAttribute("role","alert"),r.hidden=!0,p.type=k.type=T.type="button",D.append(p,f,r,T,L,k),a.append(o,I,D),e.append(a);let S=null,R=null,F=null,A="",j="",G="",W="",J="",n=!1,s=0,l=!1,C="",u=null,v=Promise.resolve(),g=null,N=null,_=new Set,M={},x=(i,E=null)=>{n||(N=E,r.textContent=i instanceof Error?i.message:"Request failed",r.hidden=!1,T.hidden=t.client.pendingCommand===null,B(t.onError,i))};function z(){let i=t.client.view;if(!i)throw new y("INVALID_REQUEST","No current Run is available");return{requestId:crypto.randomUUID(),nodeId:i.nodeId,visit:i.visit,revision:i.revision}}let V=Se({client:t.client,doc:d,holder:o,reviewHolder:I,mountScreenPreview:P,get stopped(){return n},get answers(){return M},suspend(i){R?.setSuspended(i)},resetScreen(){A="",j="",G=""},enqueue:K,fail:x}),Z=Re({client:t.client,expected:z,fail:x,get stopped(){return n},get reviewing(){return V.active},get key(){return A},get busy(){return s}}),te=De({client:t.client,expected:z,perform:Y,onIntent:t.onCustomerDataIntent,get stopped(){return n},get busy(){return s},get document(){return S?.document},get answers(){return M}}),se=i=>i&&(i.screen||i.paywall)?`${i.id}:${i.nodeId}:${i.visit}`:"";function ee(){let i=t.client.view;p.disabled=!V.active&&(s>0||!!t.client.pendingCommand||!i?.canBack||i.stopped||!["running","waiting"].includes(i.status)||!se(i)||j!==se(i))}async function Y(i,E=!1){if(!(s&&!E||n||V.active&&!E)){s++,a.setAttribute("aria-busy","true"),ee(),r.hidden=!0,N=null;try{if(!E&&Z.inFlight){let O=t.client.view;await Z.inFlight;let $=t.client.view;if(!O||!$||$.id!==O.id||$.nodeId!==O.nodeId||$.visit!==O.visit||$.stopped||!["running","waiting"].includes($.status))throw new y("PRECONDITION_FAILED","The screen changed while its display was acknowledged")}if(n)return;let Q=await i();n||await K(t.client.view??Q.run)}catch(Q){x(Q,t.client.pendingCommand?.requestId??null)}finally{s=Math.max(0,s-1),a.setAttribute("aria-busy",String(s>0)),n||(T.hidden=t.client.pendingCommand===null,ee())}}}function ie(){u&&clearTimeout(u),!(n||!F||!["running","waiting"].includes(F.status)&&!t.client.pendingCommand)&&(u=setTimeout(()=>{u=null,de().finally(ie)},F.pendingRequest||t.client.pendingCommand?1500:5e3))}async function de(){if(!(n||l||s)){if(V.active){await V.open(V.receipt);return}l=!0;try{let i=t.client.pendingCommand;i&&t.client.settle&&await t.client.settle(i.requestId);let E=t.client.view,Q=te.queries,O=await t.client.get(E?.screen&&Object.keys(Q).length?{nodeId:E.nodeId,visit:E.visit,revision:E.revision,components:Q}:void 0);!n&&Q===te.queries&&await K(t.client.view??O.run)}catch(i){x(i)}finally{l=!1}}}function Ne(i){let E=i.screen?.presentation;if(!E||E.type==="inline"){b.open&&b.close(),a.parentElement!==e&&e.append(a);return}a.parentElement!==b&&(b.append(a),e.append(b));let Q={sm:420,md:640,lg:900};b.style.cssText=`padding:0;border:0;max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);overflow:auto;width:${"size"in E?Q[E.size]+"px":"100vw"}`,b.setAttribute("aria-label",(q?.screen===i.screen?.content.document.name?q?.label:void 0)??S?.document?.name??i.screen?.content.document.name??"Funnel"),b.open||(b.showModal(),Ie(b,E.type))}async function Oe(i){if(n)return;F=i,N&&t.client.pendingCommand?.requestId!==N&&(r.hidden=!0,N=null);let E=i.locale.startsWith("zh");if(L.textContent=E?"\u56DE\u770B":"History",L.hidden=!t.client.review,p.textContent=V.active?E?"\u8FD4\u56DE\u5F53\u524D":"Return to current":E?"\u8FD4\u56DE":"Back",k.textContent=E?"\u5173\u95ED":"Close",T.textContent=E?"\u91CD\u8BD5":"Retry",ee(),T.hidden=t.client.pendingCommand===null,f.textContent=i.pendingRequest?E?"\u6B63\u5728\u5904\u7406":"Processing":i.instruction?.type==="wait"?E?"\u7B49\u5F85\u4E2D":"Waiting":"",C!==`${i.revision}:${i.visit}:${i.status}:${i.stopped}`&&(C=`${i.revision}:${i.visit}:${i.status}:${i.stopped}`,B(t.onState,structuredClone(i))),!i.pendingRequest&&["closed","ineligible","failed"].includes(i.status)){ne();return}if(i.stopped||t.client.configurationReady===!1){V.stop(),S?.destroy(),S=null,R?.destroy(),R=null,o.replaceChildren(),A="",j="",G="",J="",b.open&&b.close(),a.hidden=!0,ie();return}if(a.hidden=!1,V.active){ie();return}let Q=se(i);if(Q!==A&&(j="",S?.destroy(),S=null,R?.destroy(),R=null,o.replaceChildren(),A=Q,G="",J="",M={...i.answers},te.reset()),Ne(i),i.screen){let $=i.screen.content;S||(S=P(o,{mode:"live",rendererUrl:t.client.webViewUrl,title:$.document.name,onAction(U,ae={},le={}){if(V.active)return;M={...M,...le};let Ae=Object.fromEntries((i.screen?.inputs??[]).filter(({variable:oe})=>Object.hasOwn(M,oe)).map(({variable:oe})=>[oe,M[oe]]));Y(()=>t.client.submit({operation:"submit",...z(),input:{type:"screen",output:U,answers:Ae,selection:ae}}))},onAnswers:U=>{V.active||(M={...M,...U})},onCustomerDataIntent:U=>{V.active||te.intent(U).catch(x)},onEscape:()=>{V.active||re()},onError:U=>x(new Error(U)),onRendered:U=>{if(!U)return Z.report(Q);q={screen:$.document.name,label:U},b.open&&b.setAttribute("aria-label",U),Z.report(Q)}}));let H={capabilities:i.screen.capabilities,customerData:i.screen.customerData,parameters:i.parameters,serverInput:{bindings:i.screen.inputs,answers:M,values:i.screen.values}},X=JSON.stringify([$,i.locale,H.parameters,i.screen.inputs,i.screen.values]);if(X!==G)S.update($.document,i.locale,H),G=X,W=JSON.stringify(H.capabilities),J=JSON.stringify(H.customerData);else{let U=JSON.stringify(H.capabilities);U!==W&&(S.updateCapabilities(H.capabilities),W=U),JSON.stringify(H.customerData)!==J&&(S.updateCustomerData(H.customerData),J=JSON.stringify(H.customerData))}await S.ready}else if(i.paywall&&!R){let $=await c(o,{canInteract:()=>!V.active&&!n,start:async()=>Pe(t.client),onPurchase:t.onPurchase,onCheckoutUrl:t.onCheckoutUrl,resolveOfferId:t.resolveOfferId,onEvent:t.onEvent,onOpenUrl:H=>t.onOpenUrl?t.onOpenUrl({receiptId:i.paywall.receiptId,url:H,openIn:"same_window"}):d.defaultView?.location.assign(H),onAction:async H=>{if(V.active)return;let X=await t.client.submit({operation:"submit",requestId:crypto.randomUUID(),nodeId:i.nodeId,visit:i.visit,revision:i.revision,input:{type:"screen",output:H,answers:{}}});await K(t.client.view??X.run)},onError:x,onDismiss:()=>{!V.active&&!n&&t.client.view?.visit===i.visit&&re()}});n?$.host?.destroy():(R=$.host,R?.setSuspended(V.active)),Z.report(Q)}if(n)return;j=Q,ee();let O=i.instruction;if(O&&(O.type==="open_url"||O.type==="event")&&!_.has(O.receiptId)){let $=d.createElement("button");$.type="button",$.textContent=O.type==="open_url"?`${E?"\u524D\u5F80":"Continue to"} ${new URL(O.url).host}`:E?"\u7EE7\u7EED":"Continue",$.onclick=()=>{let H=z(),X=O.type==="open_url"&&!t.onOpenUrl&&O.openIn==="new_window"?ke(O.url):null;Y(async()=>{let U="success";if(O.type==="open_url")if(t.onOpenUrl)try{U=await t.onOpenUrl({receiptId:O.receiptId,url:O.url,openIn:O.openIn})===!1?"failed":"opened"}catch(le){B(t.onError,le),U="failed"}else U=O.openIn==="new_window"&&!X?"failed":"opened";if(O.type==="event"){if(!t.onEvent)throw new y("EVENT_HANDLER_REQUIRED","Provide the event handler");await t.onEvent(O.event)}if(n||t.client.view?.nodeId!==H.nodeId||t.client.view.visit!==H.visit)throw new y("PRECONDITION_FAILED","The client action visit changed");let ae=await t.client.submit({operation:"submit",...H,input:{type:"client_action",receiptId:O.receiptId,outcome:U}});return _.add(O.receiptId),O.type==="open_url"&&!t.onOpenUrl&&O.openIn==="same_window"&&d.defaultView?.location.assign(O.url),ae})},o.replaceChildren($)}!i.pendingRequest&&i.status==="completed"&&!_.has(`complete:${i.id}`)&&(_.add(`complete:${i.id}`),B(t.onComplete,structuredClone(i))),ie()}function ke(i){let E=d.defaultView?.open(i,"_blank")??null;return E&&(E.opener=null),E}function K(i){return ee(),v=v.catch(()=>{}).then(()=>Oe(i)),v}let Te=t.client.subscribe(i=>{t.client.configurationReady===!1&&(a.hidden=!0,S?.destroy(),S=null,R?.destroy(),R=null,o.replaceChildren(),A="",j="",G="",J="",b.open&&b.close()),K(i).catch(x)}),qe=t.client.subscribeError?.(x);function re(){return g||(n?Promise.resolve():t.client.view&&!["running","waiting"].includes(t.client.view.status)?(ne(),Promise.resolve()):(g=Y(()=>t.client.submit({operation:"close",...z()}),!0).then(()=>{t.client.view?.status==="closed"&&ne()}).finally(()=>{g=null}),g))}function ne(){m?.destroy(),!n&&(n=!0,u&&clearTimeout(u),Te(),qe?.(),S?.destroy(),V.stop(),R?.destroy(),b.close(),b.remove(),a.remove(),w instanceof HTMLElement&&w.isConnected&&w.focus(),B(t.onDismiss,F?structuredClone(F):null))}p.onclick=()=>{if(!p.disabled){if(V.active){V.exit();return}Y(()=>t.client.submit({operation:"back",...z()}))}},L.onclick=()=>{V.open()},k.onclick=()=>{re()},T.onclick=()=>{Y(()=>t.client.retry())},b.addEventListener("cancel",i=>{i.preventDefault(),re()});try{let i=await t.client.get();await K(t.client.view??i.run)}catch(i){throw ne(),i}return{destroy:ne,refresh:de,review:V.open,exitReview:V.exit,get unappliedDrafts(){return V.drafts}}}export{Fe as a,an as b};
|