@stacksjs/mobile 0.75.97 → 0.75.99
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/README.md +24 -0
- package/dist/bridge.d.ts +90 -0
- package/dist/controls.d.ts +41 -0
- package/dist/events.d.ts +28 -0
- package/dist/gestures.d.ts +38 -2
- package/dist/index.d.ts +668 -25
- package/dist/index.js +55 -1
- package/dist/native.d.ts +218 -0
- package/dist/navigation.d.ts +11 -0
- package/dist/refresh-control.d.ts +12 -0
- package/dist/sheet-gesture.d.ts +66 -0
- package/dist/sheets.d.ts +72 -0
- package/dist/shell.d.ts +21 -0
- package/dist/tab-bar.d.ts +23 -0
- package/dist/types.d.ts +18 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1 +1,55 @@
|
|
|
1
|
-
import{appReview as wt,biometrics as Tt,camera as Rt,deepLinks as q,device as Et,haptics as Lt,health as kt,keepAwake as Mt,lifecycle as Pt,liveActivities as _t,location as It,network as Nt,notifications as Ot,permissions as Ht,pushNotifications as Ct,secureStorage as Kt,share as $t,speech as Ft,splash as Dt,watchConnectivity as Bt}from"craft-native/mobile";import{haptics as Q}from"craft-native/mobile";function _(){if(typeof window>"u")return;return window}function L(t=_()){if(!t)return 0;if(typeof t.scrollY==="number")return t.scrollY;return t.document?.scrollingElement?.scrollTop??0}function ue(t,e=_()){if(!e)return()=>{};let r=!1,n=typeof requestAnimationFrame==="function"?requestAnimationFrame:(o)=>setTimeout(o,16),i=()=>{if(r)return;r=!0,n(()=>{r=!1,t(L(e))})};return t(L(e)),e.addEventListener("scroll",i,{passive:!0}),()=>e.removeEventListener("scroll",i)}function Z(t,e){let r=Math.max(0,-t),n=t<=0?Math.max(0,e)*0.5:0;return Math.round(Math.max(r,n))}function de(t){let e=t.host??_();if(!e)return()=>{};let r=t.threshold??72,n=null,i=!1,o=!1,s=typeof requestAnimationFrame==="function"?requestAnimationFrame:(m)=>setTimeout(m,16),a=null,l=(m)=>{a=null,t.onPull?.(m,i)},c=(m)=>{let S=a!==null;if(a=m,S)return;s(()=>{if(a!==null)l(a)})},h=(m)=>{let S=m.touches?.[0];return S?S.clientY:null},d=(m)=>{if(o||L(e)>0)return;n=h(m),i=!1},f=(m)=>{if(n===null)return;let S=h(m);if(S===null)return;let x=Z(L(e),S-n);if(!i&&x>=r)i=!0,Promise.resolve(Q.impact("medium")).catch(()=>{});else if(i&&x<r*0.8)i=!1;c(x)},y=async()=>{if(n===null)return;if(n=null,!i){l(0);return}i=!1,o=!0,l(r);try{await t.onRefresh()}finally{o=!1,l(0)}},p=()=>{if(n===null)return;n=null,i=!1,l(0)};return e.addEventListener("touchstart",d,{passive:!0}),e.addEventListener("touchmove",f,{passive:!0}),e.addEventListener("touchend",y),e.addEventListener("touchcancel",p),()=>{a=null,e.removeEventListener("touchstart",d),e.removeEventListener("touchmove",f),e.removeEventListener("touchend",y),e.removeEventListener("touchcancel",p)}}function H(){if(typeof window>"u")return;return window}var N="__stxPushed",tt="__stxScroll";function et(t=H()){let e=t?.history?.state;if(e===null||e===void 0)return!1;if(typeof e!=="object")return!0;let r=e;if(N in r)return r[N]===!0;return!(tt in r)}function pe(t=H()){if(!et(t))return!1;return t.history.back(),!0}function me(t,e,r=50){let n=t[t.length-1];if(t.length>=2&&t[t.length-2].path===e)t.pop();else if(!n||n.path!==e)t.push({path:e,title:""});if(t.length>r)t.splice(0,t.length-r);return{current:t[t.length-1],previous:t[t.length-2]??null}}function ge(t,e,r=12){let n=t?.title.trim()??"";return n&&n.length<=r?n:e}function he(){if(typeof window>"u")return[];let t=window;return t.__stacksNavTrail??=[]}function nt(t,e=rt()){let r;try{r=new URL(t)}catch{return null}let n=`${r.search}${r.hash}`;if(r.protocol==="http:"||r.protocol==="https:"){if(!e||r.origin!==e)return null;return`${r.pathname||"/"}${n}`}return`${`/${[r.host,r.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${n}`}function rt(){if(typeof window>"u")return;return window.location?.origin}var O="stacks-mobile-deep-link";function ye(t,e){let r=(n)=>{let i=nt(n);if(i)t(i)};return e.getInitialURL().then((n)=>{if(!n)return;try{if(sessionStorage.getItem(O)===n)return;sessionStorage.setItem(O,n)}catch{}r(n)}).catch(()=>{}),e.onLink((n,i)=>{if(i?.initial)return;r(n)})}var ve=30;function it(t,e){let r=Math.PI/180,n=(e.latitude-t.latitude)*r,i=(e.longitude-t.longitude)*r,o=Math.sin(n/2)**2+Math.cos(t.latitude*r)*Math.cos(e.latitude*r)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function ot(t,e=25){let r=new Set;return t.filter((n)=>Number.isFinite(n.latitude)&&Number.isFinite(n.longitude)&&Number.isFinite(n.timestamp)&&n.accuracy>=0&&n.accuracy<=e).sort((n,i)=>n.timestamp-i.timestamp).filter((n)=>{if(r.has(n.timestamp))return!1;return r.add(n.timestamp),!0})}function C(t,e={}){let r=ot(t,e.maxAccuracyM??25),n=e.paceWindowS??30,i=[],o=0,s=0,a=null;for(let d of r){let f=i[i.length-1],y=a?(d.timestamp-a.timestamp)/1000:0;if(a=d,!f){i.push({fix:d,cumM:0});continue}if(y>30){i.push({fix:d,cumM:o});continue}let p=(d.timestamp-f.fix.timestamp)/1000,m=it(f.fix,d),S=Math.min(10,Math.max(3,f.fix.accuracy,d.accuracy));if(m<S)continue;if(o+=m,p>0&&m/p>=0.5)s+=p;i.push({fix:d,cumM:o})}let l=i[i.length-1],c=null,h=null;if(l){let d=l.fix.timestamp-n*1000,f=i.find((m)=>m.fix.timestamp>=d)??l,y=l.cumM-f.cumM,p=(l.fix.timestamp-f.fix.timestamp)/1000;if(y>=20&&p>0)h=y/p,c=p/(y/1000)}return{distanceM:o,movingS:s,paceSPerKm:c,averagePaceSPerKm:o>=50&&s>0?s/(o/1000):null,speedMps:h,accuracyM:r.length?r[r.length-1].accuracy:t.length?t[t.length-1].accuracy??null:null,fixes:r.length}}function Se(t){if(!t||!Number.isFinite(t)||t>3600)return"–";let e=Math.round(t);return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}function Ae(t){return t&&Number.isFinite(t)?(t*3.6).toFixed(1):"–"}var K={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function xe(t){let e=t.location,r=t.intervalMs??3000,n=K,i=null,o=()=>typeof document<"u"&&document.visibilityState==="hidden";async function s(){let c=await e.readRecording();return n=C(c,t),t.onUpdate?.(n),n}function a(){l(),i=setInterval(()=>{if(!o())s().catch(()=>{})},r)}function l(){if(i)clearInterval(i);i=null}return{get stats(){return n},async start(){return await e.startRecording({enableHighAccuracy:!0,...t.locationOptions}),n=K,t.onUpdate?.(n),a(),n},async attach(){let c=await e.getRecordingState().catch(()=>null);if(!c?.active)return null;if(await s().catch(()=>{}),!c.paused)a();return c},async pause(){l(),await e.pauseRecording(),await s().catch(()=>{})},async resume(){await e.resumeRecording(),a()},async stop(){l();let h=(await e.stopRecording())?.locations??[];return n=C(h,t),t.onUpdate?.(n),h},refresh:s}}var Te=150;function st(t,e){let r=Math.PI/180,n=(e.latitude-t.latitude)*r,i=(e.longitude-t.longitude)*r,o=Math.sin(n/2)**2+Math.cos(t.latitude*r)*Math.cos(e.latitude*r)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function k(t,e){let r=[...t].sort((n,i)=>n-i);return r[Math.min(r.length-1,Math.floor(e*r.length))]}function Re(t,e){let r=(t||[]).filter((s)=>Number.isFinite(s?.latitude)&&Number.isFinite(s?.longitude)),n=r.map((s)=>Number(s.accuracy)).filter((s)=>Number.isFinite(s)&&s>=0),i=n.length?k(n,0.5):Number.POSITIVE_INFINITY,o=0;if(r.length){let s={latitude:k(r.map((a)=>a.latitude),0.5),longitude:k(r.map((a)=>a.longitude),0.5)};o=k(r.map((a)=>st(s,a)),0.8)}if(r.length>=10&&o>150&&i<=15)return"outside";if(e<150)return"unsure";if(r.length<3||i>30||o<25)return"indoors";if(o<50&&i>10)return"indoors";return"unsure"}function Ee(t){let r=String(t||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d+)?)\s*(km|k|m|mi)?$/);if(!r)return null;let n=Number(r[1]),i=r[2]||(n>100?"m":"km"),o=i==="m"?n/1000:i==="mi"?n*1.609344:n;return o>0&&o<1000?Math.round(o*1000)/1000:null}var ke=64;var at=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,lt=/^(?:0|[1-9]\d*)$/;function D(t){let e=[],r=[],n=t&&typeof t==="object"&&!Array.isArray(t)?t:{};for(let[i,o]of Object.entries(n)){let s=o&&typeof o==="object"?o:null;if(!s){r.push(`spotlight kind "${i}" is not an object`);continue}let{slots:a,route:l}=s,c=typeof s.noun==="string"&&s.noun.trim()?s.noun.trim():"Item";if(!at.test(i)||i.includes("-slot-")){r.push(`spotlight kind "${i}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof a!=="number"||!Number.isInteger(a)||a<=0||a>64){r.push(`spotlight kind "${i}" needs slots between 1 and 64, not ${String(a)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){r.push(`spotlight kind "${i}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}e.push({name:i,slots:a,route:l,noun:c})}return{kinds:e,problems:r}}function R(t,e){return t.find((r)=>r.name===e)??null}function T(t,e,r){let n=R(t,e);if(!n||!Number.isInteger(r)||r<0||r>=n.slots)return null;return`${e}-slot-${r}`}function ct(t,e){if(typeof e!=="string")return null;let r=e.lastIndexOf("-slot-");if(r<=0)return null;let n=e.slice(0,r),i=e.slice(r+6);if(!lt.test(i))return null;let o=Number(i);return T(t,n,o)===e?{kind:n,slot:o}:null}function B(t){return t.flatMap((e)=>Array.from({length:e.slots},(r,n)=>`${e.name}-slot-${n}`))}function Me(t,e){let r=t&&typeof t==="object"?t:{};if(r.enabled===!1)return[];let i=[...(Array.isArray(r.activityTypes)?r.activityTypes.filter((o)=>typeof o==="string"&&o.trim().length>0):[]).map((o)=>o.trim()),...B(D(r.kinds).kinds)];return[...new Set(i)].map((o)=>`${e}.${o}`)}function U(t,e,r){let n=typeof r.name==="string"?r.name.replace(/\s+/g," ").trim():"";if(!n)return`${R(t,e)?.noun??"Item"} #${r.id}`;return n.length>120?`${n.slice(0,119).trimEnd()}…`:n}function ut(t,e,r,n,i=Date.now()){let o=R(t,r);if(!o||!Number.isInteger(n.id)||n.id<=0)return null;let s=e.filter((p)=>p.kind===r),a=U(t,r,n),l=s.find((p)=>p.itemId===n.id)??null,c=l?null:mt(s,o.slots),h=l||c!==null?null:gt(s),d=l?.slot??c??h?.slot;if(d===void 0||d===null)return null;let f={kind:r,slot:d,itemId:n.id,title:a,donatedAt:i},y=e.filter((p)=>p.kind!==r||p.slot!==d&&p.itemId!==n.id);return{entries:G(t,[...y,f]),entry:f,evicted:h,changed:!l||l.title!==a}}function dt(t,e,r){let n=t.find((i)=>i.kind===e&&i.itemId===r)??null;return{entries:n?t.filter((i)=>i!==n):[...t],removed:n}}function ft(t,e,r){let n=ct(t,r);if(!n)return null;let i=e.find((s)=>s.kind===n.kind&&s.slot===n.slot),o=R(t,n.kind)?.route;return i&&o?o.replace(":id",String(i.itemId)):null}function pt(t,e){if(!Array.isArray(e))return[];let r=new Map,n=new Set;for(let i of e){if(!i||typeof i!=="object")continue;let o=i,{kind:s,slot:a,itemId:l,title:c,donatedAt:h}=o;if(typeof s!=="string"||typeof a!=="number"||T(t,s,a)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let d=`${s}-slot-${a}`,f=`${s}#${l}`;if(r.has(d)||n.has(f))continue;r.set(d,{kind:s,slot:a,itemId:l,title:typeof c==="string"&&c.trim()?c:U(t,s,{id:l}),donatedAt:typeof h==="number"&&Number.isFinite(h)&&h>0?h:0}),n.add(f)}return G(t,[...r.values()])}function G(t,e){let r=new Map(t.map((n,i)=>[n.name,i]));return[...e].sort((n,i)=>(r.get(n.kind)??0)-(r.get(i.kind)??0)||n.slot-i.slot)}function mt(t,e){let r=new Set(t.map((n)=>n.slot));for(let n=0;n<e;n++)if(!r.has(n))return n;return null}function gt(t){return t.reduce((e,r)=>!e||r.donatedAt<e.donatedAt?r:e,null)}function ht(){let t=globalThis.craft;return t&&typeof t==="object"?t.siri:void 0}var yt="stacks_spotlight_index",bt=3000;function Pe(t){let e=t.onProblem??((u)=>console.warn(`[spotlight] ${u}`)),r=Array.isArray(t.kinds)?{kinds:[...t.kinds],problems:[]}:D(t.kinds);for(let u of r.problems)e(u);let n=t.enabled===!1?[]:r.kinds,i=t.storageKey??yt,o=t.legacyStorageKeys??[],s=t.timeoutMs??bt,a=t.now??(()=>Date.now()),l=t.bridge??ht,c=null;function h(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function d(){if(c)return c;c=[];let u=h();if(!u)return c;try{let g=[i,...o].map((b)=>u.getItem(b)).find((b)=>b);c=g?pt(n,JSON.parse(g)):[]}catch{c=[]}return c}function f(u){c=u;let g=h();if(!g)return;try{g.setItem(i,JSON.stringify(u));for(let b of o)g.removeItem(b)}catch{}}async function y(u){if(!u)return null;let g;try{return await Promise.race([u,new Promise((b)=>{g=setTimeout(()=>b(null),s)})])}catch{return null}finally{if(g!==void 0)clearTimeout(g)}}let p=Promise.resolve();function m(u){let g=p.then(u,u);return p=g.catch(()=>{return}),g}async function S(u,g){let b=l()?.register;if(!b||n.length===0)return!1;return m(async()=>{let v=ut(n,d(),u,g,a()),A=v&&T(n,u,v.entry.slot);if(!v||!A)return!1;if(!v.changed)return f(v.entries),!0;let w=await y(b(v.entry.title,A))!==null;if(w)f(v.entries);return w})}async function x(u,g){let b=l()?.remove;if(!b)return!1;return m(async()=>{let{entries:v,removed:A}=dt(d(),u,g);if(!A)return!1;let w=T(n,u,A.slot),z=w?await y(b(w))!==null:!1;return f(v),z})}async function J(u,g){let b=R(n,u)?.slots;if(!b||!l()?.register)return 0;let v=0;for(let A of[...g].slice(0,b).reverse())if(await S(u,A))v++;return v}async function X(){let u=l()?.remove;if(!u)return f([]),0;return m(async()=>{let g=0;for(let b of d()){let v=T(n,b.kind,b.slot);if(v&&await y(u(v))!==null)g++}return f([]),g})}return{kinds:n,index:S,sync:J,remove:x,clear:X,routeFor:(u)=>ft(n,d(),u),entries:()=>d(),activityTypes:(u)=>B(n).map((g)=>`${u}.${g}`),reset:()=>{c=null}}}var F=["craftShortcut","craftSiriShortcut"];function _e(t,e){let r=(n)=>{let i=n.detail,o=typeof i==="string"?i:i&&typeof i==="object"?i.action??i.type:null,s=typeof o==="string"?t.routeFor(o):null;if(s)e(s)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let n of F)globalThis.addEventListener(n,r);return()=>{for(let n of F)globalThis.removeEventListener(n,r)}}import{tabBar as vt}from"craft-native/mobile";var St=vt;function At(t){return Array.from(t.querySelectorAll("a[data-native-tab]")).map((e)=>({id:e.getAttribute("href")||"",title:e.getAttribute("data-native-tab")||e.getAttribute("aria-label")||"",symbol:e.getAttribute("data-native-tab-symbol")||"circle",badge:(e.querySelector(".native-tab-badge")?.textContent||"").trim(),current:e.hasAttribute("data-stx-nav-current")||e.classList.contains("is-active")})).filter((e)=>e.id&&e.title)}function xt(t){return{tabs:t.map(({id:r,title:n,symbol:i,badge:o})=>o?{id:r,title:n,symbol:i,badge:o}:{id:r,title:n,symbol:i}),selected:t.find((r)=>r.current)?.id}}function j(t){let e=t.trim();return/^#[0-9a-f]{6}$/i.test(e)?e:void 0}function Oe(t,e={}){let r=e.api??St;if(!r.isAvailable())return null;let n=e.hidden??(()=>Boolean(t.ownerDocument?.querySelector("[data-native-hide-tab-bar]"))),i=typeof getComputedStyle==="function"?getComputedStyle(t):null,o=j(i?.getPropertyValue("--native-tab-active")||""),s=j(i?.getPropertyValue("--native-tab-active-dark")||""),a="",l=()=>{if(n()){if(a!=="hidden")r.hide();a="hidden";return}let{tabs:f,selected:y}=xt(At(t)),p=JSON.stringify({tabs:f,selected:y});if(p===a)return;let m=a&&a!=="hidden"?JSON.parse(a):null;if(m&&y&&JSON.stringify(m.tabs)===JSON.stringify(f))r.select(y);else r.set(f,{selected:y,tint:o,tintDark:s});a=p},c=typeof MutationObserver==="function"?new MutationObserver(l):null;c?.observe(t,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let h=r.onSelect((f)=>{Array.from(t.querySelectorAll("a[data-native-tab]")).find((p)=>p.getAttribute("href")===f)?.click()}),d=()=>l();if(typeof window<"u")window.addEventListener("stx:load",d);return l(),()=>{if(c?.disconnect(),h(),typeof window<"u")window.removeEventListener("stx:load",d);r.hide()}}var Ut=Tt,Gt=Rt,jt=Et,M=Lt,qt=Pt,Yt=It,Vt=Ot,Wt=Ht,Jt=Kt,Xt=$t,zt=wt;function Y(t){if(typeof t==="string")return t.trim()||null;if(!t||typeof t!=="object")return null;let e=t.url;return typeof e==="string"&&e.trim()?e:null}var Qt={async getInitialURL(){if(!await V())return null;return Y(await q.getInitialURL?.())},onLink(t){let e=null,r=!1,n=()=>{if(r)return;e=q.onLink?.((i,o)=>{let s=Y(i);if(s)t(s,{initial:o?.initial===!0})})??null};if(E()?.craft)n();else V().then(n);return()=>{r=!0,e?.()}}},Zt=Mt,te=Ft,ee=Nt,ne=Ct,re=kt,ie=_t,oe=Bt,Ke=Dt;function E(){if(typeof window>"u")return;return window}function P(){let t=E()?.craft;if(!t||typeof t!=="object")return null;if(!("platform"in t)||t.platform!=="ios"&&t.platform!=="android")return null;let e="capabilities"in t?t.capabilities:void 0,r=e&&typeof e==="object"&&!Array.isArray(e)?Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n==="boolean")):{};return{platform:t.platform,capabilities:r}}function I(){return P()!==null}function W(){if(typeof window>"u")return!1;let t=window;if(t.CraftAndroid)return!0;let e=typeof navigator>"u"?"":navigator.userAgent;return Boolean(t.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(e)}function se(t=2000){if(I()||W())return Promise.resolve(!0);let e=E(),r=e;if(!e||!(r?.craft||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let i=()=>{clearTimeout(o),e.removeEventListener("craftReady",i),n(I())},o=setTimeout(i,t);e.addEventListener("craftReady",i,{once:!0})})}function V(t=15000){let e=E();if(e?.craft)return Promise.resolve(!0);let r=e;if(!e||!(W()||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let i=()=>{clearTimeout(o),e.removeEventListener("craftReady",i),n(Boolean(e.craft))},o=setTimeout(i,t);e.addEventListener("craftReady",i)})}function ae(t){let e=E();if(!e)return()=>{};if(P()){let n=!1;return queueMicrotask(()=>{if(!n)t(new Event("craftReady"))}),()=>{n=!0}}let r=(n)=>{if(!P())return;e.removeEventListener("craftReady",r),t(n)};return e.addEventListener("craftReady",r),()=>e.removeEventListener("craftReady",r)}async function le(t){await M.impact("light");try{let e=await t();return await M.notification("success"),e}catch(e){throw await M.notification("error"),e}}var $e={get nativeBridge(){return P()},biometrics:Ut,camera:Gt,device:jt,haptics:M,lifecycle:qt,location:Yt,notifications:Vt,permissions:Wt,secureStorage:Jt,share:Xt,appReview:zt,deepLinks:Qt,keepAwake:Zt,speech:te,network:ee,pushNotifications:ne,health:re,liveActivities:ie,watchConnectivity:oe,isNativeMobile:I,whenNative:se,onReady:ae,withFeedback:le};export{Te as INDOOR_CHECK_AFTER_S,ke as MAX_SPOTLIGHT_SLOTS_PER_KIND,ve as ROUTE_GAP_S,zt as appReview,ge as backLabelFor,Ut as biometrics,Gt as camera,et as canGoBack,xe as createRouteRecorder,Pe as createSpotlightIndex,nt as deepLinkPath,Qt as deepLinks,jt as device,me as enterNavTrail,it as fixDistance,ye as followDeepLinks,P as getNativeMobileBridge,pe as goBack,M as haptics,W as hasNativeMobileHost,re as health,Re as indoorVerdict,I as isNativeMobile,Zt as keepAwake,qt as lifecycle,ie as liveActivities,Yt as location,Oe as mirrorTabBar,$e as mobile,xt as nativeTabs,he as navTrail,ee as network,Y as normalizeDeepLinkURL,Vt as notifications,ue as observePageScroll,de as observePullToRefresh,ae as onMobileReady,_e as onSpotlightTap,Se as paceLabel,L as pageScrollTop,Wt as permissions,ut as placeSpotlightItem,Z as pullDistance,ne as pushNotifications,pt as readSpotlightEntries,D as readSpotlightKinds,At as readTabLinks,dt as removeSpotlightItem,C as routeStats,Jt as secureStorage,Xt as share,te as speech,Ae as speedLabel,Ke as splash,T as spotlightAction,B as spotlightActions,Me as spotlightActivityTypes,ht as spotlightBridge,R as spotlightKind,ft as spotlightRoute,ct as spotlightSlot,U as spotlightTitle,St as tabBar,Ee as typedDistanceKm,ot as usableFixes,oe as watchConnectivity,V as whenBridgeReady,se as whenNativeMobile,le as withNativeFeedback};
|
|
1
|
+
import{appReview as hn,biometrics as be,camera as Q,deepLinks as ct,device as O,haptics as Z,health as U,keepAwake as ut,lifecycle as bn,liveActivities as ve,location as P,network as dt,notifications as ee,permissions as W,pushNotifications as ye,secureStorage as te,share as pt,speech as xe,splash as vn,watchConnectivity as Y}from"craft-native/mobile";var Kn=2500;function x(){if(typeof window>"u")return;return window}function bt(){let e=x()?.craft;return e&&typeof e==="object"?e:void 0}function vt(){return typeof navigator>"u"?"":navigator.userAgent||""}function ie(){let e=x();if(!e)return!1;if(e.CraftAndroid)return!0;return Boolean(e.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(vt())}function j(){let e=x();if(!e||e.craft)return!1;return ie()||Boolean(e.webkit?.messageHandlers?.craft)}function I(e=15000){let t=x();if(t?.craft)return Promise.resolve(!0);if(!t||!j())return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(Boolean(t.craft))},o=setTimeout(r,e);t.addEventListener("craftReady",r)})}function yt(e,t){if(!e)return null;let n=t.split("."),r=e;for(let i of n.slice(0,-1))if(r=r?.[i],!r||typeof r!=="object"&&typeof r!=="function")return null;let o=r?.[n[n.length-1]];return typeof o==="function"?o.bind(r):null}function T(e){return yt(bt(),e)}async function xt(e,t=2500){let n=T(e);if(n||!j())return n;return await I(t),T(e)}async function b(e,t,n,r={}){let o=await xt(e,r.timeoutMs);if(!o)return n();try{return await o(...t)}catch(i){if(r.fallbackOnError)return n();throw i}}async function g(e,t=2500){if(j())await I(t);return e()}function ae(e,t=2500){let n,r=!1;if(!j())n=e();else I(t).then(()=>{if(!r)n=e()});return()=>{if(r=!0,typeof n==="function")n()}}function R(e,t){let n=x();if(!n)return()=>{};let r=(o)=>t(o.detail??{});return n.addEventListener(e,r),()=>n.removeEventListener(e,r)}var we="native-dialog-styles",St=`
|
|
2
|
+
.native-dialog { position: fixed; inset: 0; z-index: 2147483000; font-size: var(--native-font-size, 17px); font-family: var(--native-font-family, -apple-system, system-ui, sans-serif); -webkit-tap-highlight-color: transparent; }
|
|
3
|
+
.native-dialog-backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 0.3); opacity: 0; transition: opacity 220ms ease; }
|
|
4
|
+
.native-dialog--menu .native-dialog-backdrop { background: rgb(0 0 0 / 0.12); -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%); }
|
|
5
|
+
.native-dialog.is-open .native-dialog-backdrop { opacity: 1; }
|
|
6
|
+
.native-dialog-panel { position: absolute; outline: none; }
|
|
7
|
+
.native-dialog--sheet .native-dialog-panel { right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; gap: 0.47em; max-width: 32rem; margin: 0 auto; padding: 0 0.47em calc(0.47em + env(safe-area-inset-bottom, 0px)); transform: translateY(110%); transition: transform 380ms cubic-bezier(0.32, 0.72, 0, 1); }
|
|
8
|
+
.native-dialog--sheet.is-open .native-dialog-panel { transform: none; }
|
|
9
|
+
.native-dialog--alert .native-dialog-panel { top: 50%; left: 50%; width: min(16.5em, calc(100vw - 3rem)); transform: translate(-50%, -50%) scale(1.12); opacity: 0; transition: transform 260ms cubic-bezier(0.2, 0.9, 0.3, 1.05), opacity 200ms ease; }
|
|
10
|
+
.native-dialog--alert.is-open .native-dialog-panel { transform: translate(-50%, -50%); opacity: 1; }
|
|
11
|
+
.native-dialog-group { overflow: hidden; border-radius: 0.8em; background: var(--native-dialog-background, rgb(242 242 247 / 0.92)); -webkit-backdrop-filter: blur(24px) saturate(180%); backdrop-filter: blur(24px) saturate(180%); }
|
|
12
|
+
.native-dialog-header { padding: 0.85em 1em; text-align: center; }
|
|
13
|
+
.native-dialog--sheet .native-dialog-header { border-bottom: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); }
|
|
14
|
+
.native-dialog-title { margin: 0; font-size: 0.765em; font-weight: 600; color: var(--native-secondary-label, rgb(60 60 67 / 0.6)); }
|
|
15
|
+
.native-dialog--alert .native-dialog-title { font-size: 1em; color: inherit; }
|
|
16
|
+
.native-dialog-message { margin: 0.25em 0 0; font-size: 0.765em; color: var(--native-secondary-label, rgb(60 60 67 / 0.6)); }
|
|
17
|
+
.native-dialog--alert .native-dialog-message { color: inherit; }
|
|
18
|
+
.native-dialog-actions { display: flex; flex-direction: column; }
|
|
19
|
+
.native-dialog--alert .native-dialog-actions { border-top: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); }
|
|
20
|
+
.native-dialog--alert .native-dialog-actions.is-row { flex-direction: row; }
|
|
21
|
+
.native-dialog-action { width: 100%; min-height: 3.3em; padding: 0 1em; border: 0; border-top: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); color: var(--native-accent, rgb(0 122 255)); background: transparent; font: inherit; font-size: 1.18em; cursor: pointer; }
|
|
22
|
+
.native-dialog--alert .native-dialog-action { min-height: 2.6em; font-size: 1em; }
|
|
23
|
+
.native-dialog-action:first-child { border-top: 0; }
|
|
24
|
+
.native-dialog-actions.is-row .native-dialog-action { flex: 1; border-top: 0; border-left: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); }
|
|
25
|
+
.native-dialog-actions.is-row .native-dialog-action:first-child { border-left: 0; }
|
|
26
|
+
.native-dialog-action.is-cancel { font-weight: 600; }
|
|
27
|
+
.native-dialog-action.is-destructive { color: var(--native-destructive, rgb(255 59 48)); }
|
|
28
|
+
.native-dialog-action:active, .native-dialog-action:focus-visible { background: var(--native-pressed, rgb(0 0 0 / 0.08)); outline: none; }
|
|
29
|
+
.native-menu { position: absolute; width: min(15.5em, calc(100vw - 1.5rem)); overflow: hidden; border-radius: 0.8em; background: var(--native-dialog-background, rgb(242 242 247 / 0.92)); box-shadow: 0 10px 40px rgb(0 0 0 / 0.2); -webkit-backdrop-filter: blur(24px) saturate(180%); backdrop-filter: blur(24px) saturate(180%); transform: scale(0.6); transform-origin: var(--native-menu-origin, top left); opacity: 0; transition: transform 300ms cubic-bezier(0.2, 0.9, 0.3, 1.1), opacity 160ms ease; }
|
|
30
|
+
.native-dialog.is-open .native-menu { transform: none; opacity: 1; }
|
|
31
|
+
.native-menu-title { margin: 0; padding: 0.6em 1em; border-bottom: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); font-size: 0.765em; color: var(--native-secondary-label, rgb(60 60 67 / 0.6)); }
|
|
32
|
+
.native-menu-item { display: flex; gap: 0.75em; align-items: center; justify-content: space-between; width: 100%; min-height: 2.6em; padding: 0 1em; border: 0; border-top: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); color: inherit; background: transparent; font: inherit; text-align: left; cursor: pointer; }
|
|
33
|
+
.native-menu-item:first-of-type { border-top: 0; }
|
|
34
|
+
.native-menu-item.is-destructive { color: var(--native-destructive, rgb(255 59 48)); }
|
|
35
|
+
.native-menu-item:disabled { opacity: 0.35; }
|
|
36
|
+
.native-menu-item:active, .native-menu-item:focus-visible { background: var(--native-pressed, rgb(0 0 0 / 0.08)); outline: none; }
|
|
37
|
+
.native-menu-icon { flex-shrink: 0; width: 1.1em; height: 1.1em; }
|
|
38
|
+
.dark .native-dialog-group, .dark .native-menu { background: var(--native-dialog-background-dark, rgb(44 44 46 / 0.9)); color: rgb(255 255 255); }
|
|
39
|
+
.dark .native-dialog-action { color: var(--native-accent-dark, rgb(10 132 255)); }
|
|
40
|
+
.dark .native-dialog-action.is-destructive, .dark .native-menu-item.is-destructive { color: var(--native-destructive-dark, rgb(255 69 58)); }
|
|
41
|
+
.dark .native-dialog-title, .dark .native-dialog-message, .dark .native-menu-title { color: rgb(235 235 245 / 0.6); }
|
|
42
|
+
.dark .native-dialog--alert .native-dialog-title, .dark .native-dialog--alert .native-dialog-message { color: rgb(255 255 255); }
|
|
43
|
+
.dark .native-dialog-action, .dark .native-menu-item, .dark .native-dialog-header, .dark .native-menu-title, .dark .native-dialog-actions { border-color: rgb(84 84 88 / 0.6); }
|
|
44
|
+
.dark .native-dialog-action:active, .dark .native-menu-item:active { background: rgb(255 255 255 / 0.1); }
|
|
45
|
+
@media (prefers-reduced-motion: reduce) {
|
|
46
|
+
.native-dialog-backdrop, .native-dialog-panel, .native-menu { transition: opacity 150ms ease; }
|
|
47
|
+
.native-dialog--sheet .native-dialog-panel, .native-dialog--alert .native-dialog-panel, .native-menu { transform: none; }
|
|
48
|
+
.native-dialog--alert .native-dialog-panel { transform: translate(-50%, -50%); }
|
|
49
|
+
}
|
|
50
|
+
:root[data-native-reduce-motion] .native-dialog--sheet .native-dialog-panel, :root[data-native-reduce-motion] .native-menu { transform: none; transition: opacity 150ms ease; }
|
|
51
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
52
|
+
.native-dialog-group, .native-menu { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--native-dialog-solid, rgb(242 242 247)); }
|
|
53
|
+
.dark .native-dialog-group, .dark .native-menu { background: var(--native-dialog-solid-dark, rgb(44 44 46)); }
|
|
54
|
+
}
|
|
55
|
+
`;function ke(){return x()?.document}function wt(e){if(e.getElementById(we))return;let t=e.createElement("style");t.id=we,t.textContent=St,(e.head??e.documentElement).appendChild(t)}var kt=0;function w(e,t,n,r){let o=e.createElement(t);if(o.className=n,r!==void 0)o.textContent=r;return o}var Ae='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function At(e,t){if(t.key!=="Tab")return;let n=Array.from(e.querySelectorAll(Ae));if(n.length===0){t.preventDefault();return}let r=n[0],o=n[n.length-1],i=e.ownerDocument.activeElement;if(t.shiftKey&&(i===r||!e.contains(i)))t.preventDefault(),o.focus();else if(!t.shiftKey&&(i===o||!e.contains(i)))t.preventDefault(),r.focus()}function Ee(e,t,n,r){wt(e);let o=x(),i=e.activeElement,a=w(e,"div",`native-dialog native-dialog--${t}`);return a.setAttribute("data-native-dialog",t),a.appendChild(w(e,"div","native-dialog-backdrop")),new Promise((s)=>{let l=!1,d=(h)=>{if(l)return;l=!0,a.classList.remove("is-open"),e.removeEventListener("keydown",p,!0),setTimeout(()=>{if(a.remove(),i&&typeof i.focus==="function")i.focus()},260),s(h)},p=(h)=>{if(h.key==="Escape"){h.preventDefault(),d(r());return}At(c,h)},c=n({root:a,settle:d});a.appendChild(c),e.body.appendChild(a),e.addEventListener("keydown",p,!0);let m=o;(typeof m?.requestAnimationFrame==="function"?(h)=>m.requestAnimationFrame(()=>m.requestAnimationFrame(h)):(h)=>setTimeout(h,16))(()=>{if(!l)a.classList.add("is-open")}),(c.querySelector("[data-native-autofocus]")??c.querySelector(Ae))?.focus()})}function se(e){let t=ke();if(!t?.body)return Promise.resolve(null);let n=`native-dialog-${++kt}`,r=e.actions.find((a)=>a.style==="cancel"),o=e.variant==="sheet"?e.actions.filter((a)=>a.style!=="cancel"):e.actions,i=e.variant==="sheet"?r??{id:"__cancel",title:e.cancelLabel||"Cancel",style:"cancel"}:void 0;return Ee(t,e.variant,({root:a,settle:s})=>{let l=(u)=>u.style==="cancel"?null:u.id,d=w(t,"div","native-dialog-panel");d.setAttribute("role","alertdialog"),d.setAttribute("aria-modal","true"),d.tabIndex=-1;let p=w(t,"div","native-dialog-group");if(e.title||e.message){let u=w(t,"div","native-dialog-header");if(e.title){let f=w(t,"p","native-dialog-title",e.title);f.id=`${n}-title`,u.appendChild(f),d.setAttribute("aria-labelledby",f.id)}if(e.message){let f=w(t,"p","native-dialog-message",e.message);f.id=`${n}-message`,u.appendChild(f),d.setAttribute("aria-describedby",f.id)}p.appendChild(u)}let c=w(t,"div","native-dialog-actions");if(e.variant==="alert"&&o.length===2)c.classList.add("is-row");for(let u of o){let f=w(t,"button",`native-dialog-action${u.style==="destructive"?" is-destructive":""}${u.style==="cancel"?" is-cancel":""}`,u.title);f.type="button",f.setAttribute("data-action-id",u.id),f.addEventListener("click",()=>s(l(u))),c.appendChild(f)}if(p.appendChild(c),d.appendChild(p),i){let u=w(t,"div","native-dialog-group"),f=w(t,"button","native-dialog-action is-cancel",i.title);f.type="button",f.setAttribute("data-action-id",i.id),f.addEventListener("click",()=>s(null)),u.appendChild(f),d.appendChild(u)}let m=a.querySelector(".native-dialog-backdrop");if(e.variant==="sheet")m?.addEventListener("click",()=>s(null));return d},()=>{if(e.variant==="sheet")return null;if(r)return null;return o.length===1?o[0].id:null})}async function Te(e){await se({variant:"alert",title:e.title,message:e.message,actions:[{id:"ok",title:e.okLabel||"OK"}]})}async function Le(e){return await se({variant:"alert",title:e.title,message:e.message,actions:[{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"},{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"}]})==="confirm"}function Re(e){return se({variant:"sheet",title:e.title,message:e.message,actions:e.actions,cancelLabel:e.cancelLabel})}function Et(e,t,n){let i=Math.max(12,Math.min(e.x,n.width-t.width-12)),a=e.y+e.height+8,s=a+t.height<=n.height-12,l=e.y-8-t.height,d=s||l<12?Math.max(12,Math.min(a,n.height-t.height-12)):l,p=e.x+e.width/2>n.width/2?"right":"left";return{top:d,left:i,origin:`${s||l<12?"top":"bottom"} ${p}`}}function Pe(e){let t=ke();if(!t?.body)return Promise.resolve(null);let n=x();return Ee(t,"menu",({root:r,settle:o})=>{let i=w(t,"div","native-menu native-dialog-panel");if(i.setAttribute("role","menu"),e.title)i.appendChild(w(t,"p","native-menu-title",e.title)),i.setAttribute("aria-label",e.title);for(let a of e.items){let s=w(t,"button",`native-menu-item${a.destructive?" is-destructive":""}`);if(s.type="button",s.setAttribute("role","menuitem"),s.setAttribute("data-action-id",a.id),a.disabled)s.disabled=!0;if(s.appendChild(w(t,"span","native-menu-label",a.title)),a.icon){let l=w(t,"i",`native-menu-icon ${a.icon}`);l.setAttribute("aria-hidden","true"),s.appendChild(l)}s.addEventListener("click",()=>o(a.id)),i.appendChild(s)}return r.querySelector(".native-dialog-backdrop")?.addEventListener("click",()=>o(null)),queueMicrotask(()=>{let a=i.getBoundingClientRect?.(),s=Et(e.anchor,{width:a?.width||248,height:a?.height||e.items.length*44},{width:n?.innerWidth||390,height:n?.innerHeight||844});i.style.top=`${s.top}px`,i.style.left=`${s.left}px`,i.style.setProperty("--native-menu-origin",s.origin)}),i},()=>null)}var Ie=()=>!0,E=()=>!1,L=()=>null;function Me(){return x()?.navigator??(typeof navigator>"u"?void 0:navigator)}function de(e){return{x:Math.round(e.x??e.left??0),y:Math.round(e.y??e.top??0),width:Math.round(e.width),height:Math.round(e.height)}}var _={alert:(e)=>b("dialog.alert",[e],()=>Te(e),{fallbackOnError:!0}).then(()=>{}),confirm:(e)=>b("dialog.confirm",[e],()=>Le(e),{fallbackOnError:!0}).then(Boolean),actionSheet:async(e)=>{let t={...e,anchor:e.anchor?de(e.anchor):void 0},n=await b("dialog.actionSheet",[t],()=>Re(e),{fallbackOnError:!0});if(typeof n!=="string")return null;return e.actions.find((r)=>r.id===n)?.style==="cancel"?null:n}};function jn(){return(e)=>_.actionSheet(e)}async function zn(e){if((e.style??(e.destructive?"sheet":"alert"))==="alert")return _.confirm(e);return await _.actionSheet({title:e.title,message:e.message,anchor:e.anchor,actions:[{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"},{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"}]})==="confirm"}var pe={show:async(e)=>{let t={title:e.title,anchor:de(e.anchor),items:e.items.map(({id:r,title:o,symbol:i,destructive:a,disabled:s})=>({id:r,title:o,symbol:i,destructive:a,disabled:s}))},n=await b("contextMenu.show",[t],()=>Pe(e),{fallbackOnError:!0});return typeof n==="string"?n:null}};function Gn(e,t){return pe.show({...t,anchor:de(e.getBoundingClientRect())})}function Tt(e,t){let n=x();if(!n)return{cancelled:!0};if(typeof n.craft?.openURL==="function")return Promise.resolve(n.craft.openURL(e)).catch(()=>{}),{cancelled:!1};if(t.mode==="auth")return n.location?.assign(e),{cancelled:!1};if(!(typeof n.open==="function"?n.open(e,"_blank","noopener"):null))n.location?.assign(e);return{cancelled:!1}}var Ne={open:async(e,t={})=>{let n=await b("browser.open",[e,t],()=>Tt(e,t),{fallbackOnError:!0});if(!n||typeof n!=="object")return{cancelled:!1};let{url:r,cancelled:o}=n;return typeof r==="string"?{url:r,cancelled:Boolean(o)}:{cancelled:Boolean(o)}}},le=new Map,ce=new Map;function Ce(e,t){return`${e}|${t.pointSize??""}|${t.weight??""}|${t.color??""}|${t.scale??""}`}var He={isAvailable:()=>T("symbols.image")!==null,image:(e,t={})=>{let n=Ce(e,t),r=le.get(n);if(r)return r;let o=b("symbols.image",[e,t],L).then((i)=>typeof i==="string"&&i.startsWith("data:")?i:null,L).then((i)=>(ce.set(n,i),i));return le.set(n,o),o},cached:(e,t={})=>ce.get(Ce(e,t)),clearCache:()=>{le.clear(),ce.clear()}},z={setStyle:(e)=>b("statusBar.setStyle",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1)},D={setUnderPageColor:(e)=>b("chrome.setUnderPageColor",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1),setKeyboardAccessory:(e)=>b("chrome.setKeyboardAccessory",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1)},M={isAvailable:()=>T("refresh.enable")!==null,enable:(e)=>b("refresh.enable",[e??{}],E,{fallbackOnError:!0}).then((t)=>t!==!1),disable:()=>b("refresh.disable",[],E,{fallbackOnError:!0}).then((e)=>e!==!1),end:()=>b("refresh.end",[],E,{fallbackOnError:!0}).then((e)=>e!==!1),onRefresh:(e)=>R("craftRefresh",()=>e())},B={complete:(e)=>b("background.complete",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1)},_e={write:(e)=>b("clipboard.write",[e],async()=>{let t=Me()?.clipboard;if(!t?.writeText)return!1;return t.writeText(e).then(Ie,E)},{fallbackOnError:!0}).then((t)=>t!==!1),read:()=>b("clipboard.read",[],async()=>{let e=Me()?.clipboard;if(!e?.readText)return null;return e.readText().catch(L)},{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null)},De={isAvailable:()=>T("db.query")!==null,query:(e,t=[])=>b("db.query",[e,t],L).then((n)=>Array.isArray(n)?n:null),execute:(e,t=[])=>b("db.execute",[e,t],L).then((n)=>{if(!n||typeof n!=="object")return null;let{rowsAffected:r,lastInsertId:o}=n;return{rowsAffected:Number(r)||0,lastInsertId:Number(o)||0}})};function ue(e,t){let n=x()?.document;if(!n?.body)return null;let r=n.createElement("a");return r.href=e,r.download=t,r.rel="noopener",r.style.display="none",n.body.appendChild(r),r.click(),r.remove(),t}function Lt(e){let t=x()?.document;if(!t?.body)return Promise.resolve(null);return new Promise((n)=>{let r=t.createElement("input");if(r.type="file",r.style.display="none",e.length)r.accept=e.map((i)=>i.includes("/")||i.startsWith(".")?i:`.${i}`).join(",");let o=(i)=>{r.remove(),n(i)};r.addEventListener("cancel",()=>o(null)),r.addEventListener("change",()=>{let i=r.files?.[0];if(!i)return o(null);let a=new FileReader;a.onload=()=>o({name:i.name,mimeType:i.type||void 0,data:typeof a.result==="string"?a.result:void 0}),a.onerror=()=>o({name:i.name,mimeType:i.type||void 0}),a.readAsDataURL(i)}),t.body.appendChild(r),r.click()})}var Be={openPDF:(e,t=0)=>b("openPDF",[e,t],()=>{let n=x();return Boolean(n?.open?.(e,"_blank","noopener"))}).then((n)=>n!==!1),takeScreenshot:()=>b("takeScreenshot",[],L,{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null),scanQRCode:()=>b("scanQRCode",[],L).then((e)=>{if(!e||typeof e!=="object")return null;let{type:t,data:n}=e;return typeof n==="string"?{type:String(t??""),data:n}:null},L),pickFile:(e=[])=>b("pickFile",[e],()=>Lt(e)).then((t)=>{if(!t||typeof t!=="object")return null;let n=t;if(typeof n.name!=="string")return null;return{name:n.name,path:typeof n.path==="string"?n.path:void 0,data:typeof n.data==="string"?n.data:void 0,mimeType:typeof n.mimeType==="string"?n.mimeType:void 0}},L),saveFile:(e,t,n)=>b("saveFile",[e,t,n],()=>{if(e.startsWith("data:"))return ue(e,t);let r=new Blob([e],{type:n||"text/plain"}),o=URL.createObjectURL(r),i=ue(o,t);return setTimeout(()=>URL.revokeObjectURL(o),1000),i}).then((r)=>typeof r==="string"?r:null),downloadFile:(e,t)=>b("downloadFile",[e,t],()=>ue(e,t)).then((n)=>typeof n==="string"?n:null)},Fe={set:(e)=>b("shortcuts.set",[e.map(({symbol:t,...n})=>t?{...n,iconName:t}:n)],E).then((t)=>t!==!1),clear:()=>b("shortcuts.clear",[],E).then((e)=>e!==!1),onShortcut:(e)=>R("craftShortcut",(t)=>{if(typeof t.type==="string")e(t.type)})},Ke={update:(e)=>b("widget.update",[e],E).then((t)=>t!==!1),reload:()=>b("widget.reload",[],E).then((e)=>e!==!1)},Rt={portrait:"portrait-primary",portraitUpsideDown:"portrait-secondary",landscape:"landscape",landscapeLeft:"landscape-primary",landscapeRight:"landscape-secondary"};function Oe(){return x()?.screen?.orientation}var $e={lock:(e)=>b("lockOrientation",[e],()=>{let t=Oe();return t?.lock?t.lock(Rt[e]).then(Ie,E):!1}).then((t)=>t!==!1),unlock:()=>b("unlockOrientation",[],()=>(Oe()?.unlock?.(),!0)).then((e)=>e!==!1)},qe={signInWithApple:()=>b("signInWithApple",[],L).then((e)=>{if(!e||typeof e!=="object"||typeof e.userId!=="string")return null;return e})},Ue={isAvailable:()=>T("iap.purchase")!==null,products:(e)=>b("iap.getProducts",[e],()=>[]).then((t)=>Array.isArray(t)?t:[]),purchase:(e)=>b("iap.purchase",[e],L).then((t)=>t&&typeof t==="object"?t:null,(t)=>{if(/cancel/i.test(String(t?.message??t)))return null;throw t}),restore:()=>b("iap.restore",[],()=>[]).then((e)=>Array.isArray(e)?e:[])};function Jn(e,t){let n=t.delay??500,r=t.tolerance??10,o=null,i=null,a=!1,s=()=>{if(o)clearTimeout(o);if(o=null,i&&!a)t.onPressEnd?.();i=null},l=(m)=>{let u=m;if(u.button!==void 0&&u.button!==0)return;a=!1,i={x:u.clientX,y:u.clientY},t.onPressStart?.(),o=setTimeout(()=>{if(o=null,!i)return;a=!0,t.onLongPress({...i}),i=null},n)},d=(m)=>{if(!i)return;let u=m;if(Math.hypot(u.clientX-i.x,u.clientY-i.y)>r)s()},p=(m)=>{if(!a)return;a=!1,m.preventDefault(),m.stopPropagation()},c=(m)=>m.preventDefault();return e.addEventListener("pointerdown",l),e.addEventListener("pointermove",d),e.addEventListener("pointerup",s),e.addEventListener("pointercancel",s),e.addEventListener("pointerleave",s),e.addEventListener("click",p,!0),e.addEventListener("contextmenu",c),()=>{s(),e.removeEventListener("pointerdown",l),e.removeEventListener("pointermove",d),e.removeEventListener("pointerup",s),e.removeEventListener("pointercancel",s),e.removeEventListener("pointerleave",s),e.removeEventListener("click",p,!0),e.removeEventListener("contextmenu",c)}}function Pt(e,t,n){if(n<=1||t.width<=0)return 0;let r=Math.floor((e-t.left)/t.width*n);return Math.max(0,Math.min(n-1,r))}function Qn(e,t){let n=null,r=null,o=!1,i=0,a=(u)=>{let f=e.getBoundingClientRect();return Pt(u,{left:f.left+2,width:f.width-4},t.count())},s=(u)=>{let f=u;if(f.button!==void 0&&f.button!==0)return;let h=a(f.clientX);if(h!==t.selected())return;n=h,i=h,o=!1,r=f.pointerId;try{e.setPointerCapture?.(f.pointerId)}catch{}t.onPress?.(!0)},l=(u)=>{if(n===null)return;let f=a(u.clientX);if(f===i)return;o=!0,i=f,t.onScrub(f)},d=(u)=>{if(n===null)return;if(r!==null)try{e.releasePointerCapture?.(r)}catch{}if(t.onPress?.(!1),u&&o)t.onCommit(i);else if(o)t.onScrub(n);n=null,r=null},p=(u)=>{if(!o)return;o=!1,u.preventDefault(),u.stopPropagation()},c=()=>d(!0),m=()=>d(!1);return e.addEventListener("pointerdown",s),e.addEventListener("pointermove",l),e.addEventListener("pointerup",c),e.addEventListener("pointercancel",m),e.addEventListener("click",p,!0),()=>{e.removeEventListener("pointerdown",s),e.removeEventListener("pointermove",l),e.removeEventListener("pointerup",c),e.removeEventListener("pointercancel",m),e.removeEventListener("click",p,!0)}}function Zn(e,t,n){if(n<=0)return null;switch(e){case"ArrowRight":case"ArrowDown":return(t+1)%n;case"ArrowLeft":case"ArrowUp":return(t-1+n)%n;case"Home":return 0;case"End":return n-1;default:return null}}function er(e,t){e.querySelectorAll('[role="tab"]')[t]?.focus()}function tr(e){let t=(n)=>{if(!n.target?.closest?.("[data-native-pressable]"))return;let o=T("haptics.prepare");if(o)Promise.resolve().then(()=>o("impact")).catch(()=>{})};return e.addEventListener("touchstart",t,{passive:!0,capture:!0}),()=>e.removeEventListener("touchstart",t,{capture:!0})}function fe(e){let t=x();try{return Boolean(t?.matchMedia?.(e).matches)}catch{return!1}}function We(e){return e!==null&&e!==void 0&&e!=="false"&&e!=="0"}function Ye(){let e=x()?.document?.documentElement,t=Number.parseFloat(e?.style?.getPropertyValue("--craft-font-scale")||"");return{fontScale:Number.isFinite(t)&&t>0?t:1,reduceMotion:We(e?.getAttribute("data-craft-reduce-motion"))||fe("(prefers-reduced-motion: reduce)"),reduceTransparency:We(e?.getAttribute("data-craft-reduce-transparency"))||fe("(prefers-reduced-transparency: reduce)"),colorScheme:e?.classList?.contains("dark")||fe("(prefers-color-scheme: dark)")?"dark":"light"}}function Mt(e){let t=Ye(),n=Number(e?.fontScale);return{contentSizeCategory:typeof e?.contentSizeCategory==="string"?e.contentSizeCategory:void 0,fontScale:Number.isFinite(n)&&n>0?n:t.fontScale,reduceMotion:typeof e?.reduceMotion==="boolean"?e.reduceMotion:t.reduceMotion,reduceTransparency:typeof e?.reduceTransparency==="boolean"?e.reduceTransparency:t.reduceTransparency,colorScheme:e?.colorScheme==="dark"||e?.colorScheme==="light"?e.colorScheme:t.colorScheme}}function je(e,t={}){if(t.immediate!==!1)e(Ye());return R("craftAppearance",(n)=>e(Mt(n)))}function ir(e){return R("craftResume",(t)=>e({backgroundedMs:Number(t.backgroundedMs)||0}))}function ar(e){return R("craftMemoryWarning",()=>e())}function ze(e){return(t)=>{Promise.resolve().then(()=>e(t)).then(()=>B.complete(!0),()=>B.complete(!1))}}function sr(e){let t=ze(e);return R("craftSilentPush",(n)=>t(n.payload??{}))}function lr(e){let t=ze(()=>e());return R("craftBackgroundRefresh",()=>t(void 0))}import{haptics as Ct}from"craft-native/mobile";function me(){if(typeof window>"u")return;return window}function F(e=me()){if(!e)return 0;if(typeof e.scrollY==="number")return e.scrollY;if(typeof e.scrollTop==="number")return e.scrollTop;return e.document?.scrollingElement?.scrollTop??0}function Ot(e,t=me()){if(!t)return()=>{};let n=!1,r=typeof requestAnimationFrame==="function"?requestAnimationFrame:(i)=>setTimeout(i,16),o=()=>{if(n)return;n=!0,r(()=>{n=!1,e(F(t))})};return e(F(t)),t.addEventListener("scroll",o,{passive:!0}),()=>t.removeEventListener("scroll",o)}function It(e,t){let n=Math.max(0,-e),r=e<=0?Math.max(0,t)*0.5:0;return Math.round(Math.max(n,r))}function dr(e){let t=e.host??me();if(!t)return()=>{};let n=e.threshold??72,r=null,o=!1,i=!1,a=typeof requestAnimationFrame==="function"?requestAnimationFrame:(h)=>setTimeout(h,16),s=null,l=(h)=>{s=null,e.onPull?.(h,o,{bounce:Math.min(h,Math.max(0,-F(t)))})},d=(h)=>{let A=s!==null;if(s=h,A)return;a(()=>{if(s!==null)l(s)})},p=(h)=>{let A=h.touches?.[0];return A?A.clientY:null},c=(h)=>{if(i||F(t)>0)return;r=p(h),o=!1},m=(h)=>{if(r===null)return;let A=p(h);if(A===null)return;let N=It(F(t),A-r);if(!o&&N>=n)o=!0,Promise.resolve(Ct.impact("medium")).catch(()=>{});else if(o&&N<n*0.8)o=!1;d(N)},u=async()=>{if(r===null)return;if(r=null,!o){l(0);return}o=!1,i=!0,l(n);try{await e.onRefresh()}finally{i=!1,l(0)}},f=()=>{if(r===null)return;r=null,o=!1,l(0)};return t.addEventListener("touchstart",c,{passive:!0}),t.addEventListener("touchmove",m,{passive:!0}),t.addEventListener("touchend",u),t.addEventListener("touchcancel",f),()=>{s=null,t.removeEventListener("touchstart",c),t.removeEventListener("touchmove",m),t.removeEventListener("touchend",u),t.removeEventListener("touchcancel",f)}}function Nt(e,t=52){let n=Math.max(1,t),r=Math.min(1,Math.max(0,e/n)),o=e<0?1+Math.min(0.1,-e/600):1;return{progress:Math.round(r*1000)/1000,stretch:Math.round(o*1000)/1000}}function pr(e,t={}){let n="",r=()=>t.title?.offsetHeight||t.height||52;return Ot((o)=>{let i=Nt(o,r()),a=`${i.progress}|${i.stretch}`;if(a===n)return;n=a,e.style.setProperty("--native-nav-progress",String(i.progress)),e.style.setProperty("--native-nav-stretch",String(i.stretch)),t.onChange?.(i)},t.host)}function fr(e){if(!e||typeof window>"u")return;let t=window.document?.querySelector(e);return t?t:void 0}function Xe(){if(typeof window>"u")return;return window}var Ge="__stxPushed",Ht="__stxScroll";function _t(e=Xe()){let t=e?.history?.state;if(t===null||t===void 0)return!1;if(typeof t!=="object")return!0;let n=t;if(Ge in n)return n[Ge]===!0;return!(Ht in n)}function gr(e=Xe()){if(!_t(e))return!1;return e.history.back(),!0}function hr(e,t,n=50){let r=e[e.length-1];if(e.length>=2&&e[e.length-2].path===t)e.pop();else if(!r||r.path!==t)e.push({path:t,title:""});if(e.length>n)e.splice(0,e.length-n);return{current:e[e.length-1],previous:e[e.length-2]??null}}function br(e,t,n=12){let r=e?.title.trim()??"";return r&&r.length<=n?r:t}function vr(){if(typeof window>"u")return[];let e=window;return e.__stacksNavTrail??=[]}function Dt(e){try{let t=new URL(e,"http://local");return`${t.pathname}${t.search}`}catch{return e}}function yr(){if(typeof window>"u")return;let e=window.stxRouter;if(typeof e?.screens!=="function")return;let t=e.screens(),n=t.find((o)=>o.active);if(!n)return;let r=t.filter((o)=>o.tab===n.tab&&o.depth<n.depth);if(!r.length)return null;return Dt(r.reduce((o,i)=>i.depth>o.depth?i:o).url)}function xr(e,t){for(let n=e.length-1;n>=0;n--)if(e[n].path===t)return e[n];return null}function Bt(e,t=Ft()){let n;try{n=new URL(e)}catch{return null}let r=`${n.search}${n.hash}`;if(n.protocol==="http:"||n.protocol==="https:"){if(!t||n.origin!==t)return null;return`${n.pathname||"/"}${r}`}return`${`/${[n.host,n.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${r}`}function Ft(){if(typeof window>"u")return;return window.location?.origin}var Ve="stacks-mobile-deep-link";function Sr(e,t){let n=(r)=>{let o=Bt(r);if(o)e(o)};return t.getInitialURL().then((r)=>{if(!r)return;try{if(sessionStorage.getItem(Ve)===r)return;sessionStorage.setItem(Ve,r)}catch{}n(r)}).catch(()=>{}),t.onLink((r,o)=>{if(o?.initial)return;n(r)})}var kr=30;function Kt(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function $t(e,t=25){let n=new Set;return e.filter((r)=>Number.isFinite(r.latitude)&&Number.isFinite(r.longitude)&&Number.isFinite(r.timestamp)&&r.accuracy>=0&&r.accuracy<=t).sort((r,o)=>r.timestamp-o.timestamp).filter((r)=>{if(n.has(r.timestamp))return!1;return n.add(r.timestamp),!0})}function Je(e,t={}){let n=$t(e,t.maxAccuracyM??25),r=t.paceWindowS??30,o=[],i=0,a=0,s=null;for(let c of n){let m=o[o.length-1],u=s?(c.timestamp-s.timestamp)/1000:0;if(s=c,!m){o.push({fix:c,cumM:0});continue}if(u>30){o.push({fix:c,cumM:i});continue}let f=(c.timestamp-m.fix.timestamp)/1000,h=Kt(m.fix,c),A=Math.min(10,Math.max(3,m.fix.accuracy,c.accuracy));if(h<A)continue;if(i+=h,f>0&&h/f>=0.5)a+=f;o.push({fix:c,cumM:i})}let l=o[o.length-1],d=null,p=null;if(l){let c=l.fix.timestamp-r*1000,m=o.find((h)=>h.fix.timestamp>=c)??l,u=l.cumM-m.cumM,f=(l.fix.timestamp-m.fix.timestamp)/1000;if(u>=20&&f>0)p=u/f,d=f/(u/1000)}return{distanceM:i,movingS:a,paceSPerKm:d,averagePaceSPerKm:i>=50&&a>0?a/(i/1000):null,speedMps:p,accuracyM:n.length?n[n.length-1].accuracy:e.length?e[e.length-1].accuracy??null:null,fixes:n.length}}function Ar(e){if(!e||!Number.isFinite(e)||e>3600)return"–";let t=Math.round(e);return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function Er(e){return e&&Number.isFinite(e)?(e*3.6).toFixed(1):"–"}var Qe={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function Tr(e){let t=e.location,n=e.intervalMs??3000,r=Qe,o=null,i=()=>typeof document<"u"&&document.visibilityState==="hidden";async function a(){let d=await t.readRecording();return r=Je(d,e),e.onUpdate?.(r),r}function s(){l(),o=setInterval(()=>{if(!i())a().catch(()=>{})},n)}function l(){if(o)clearInterval(o);o=null}return{get stats(){return r},async start(){return await t.startRecording({enableHighAccuracy:!0,...e.locationOptions}),r=Qe,e.onUpdate?.(r),s(),r},async attach(){let d=await t.getRecordingState().catch(()=>null);if(!d?.active)return null;if(await a().catch(()=>{}),!d.paused)s();return d},async pause(){l(),await t.pauseRecording(),await a().catch(()=>{})},async resume(){await t.resumeRecording(),s()},async stop(){l();let p=(await t.stopRecording())?.locations??[];return r=Je(p,e),e.onUpdate?.(r),p},refresh:a}}var Rr=150;function qt(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function G(e,t){let n=[...e].sort((r,o)=>r-o);return n[Math.min(n.length-1,Math.floor(t*n.length))]}function Pr(e,t){let n=(e||[]).filter((a)=>Number.isFinite(a?.latitude)&&Number.isFinite(a?.longitude)),r=n.map((a)=>Number(a.accuracy)).filter((a)=>Number.isFinite(a)&&a>=0),o=r.length?G(r,0.5):Number.POSITIVE_INFINITY,i=0;if(n.length){let a={latitude:G(n.map((s)=>s.latitude),0.5),longitude:G(n.map((s)=>s.longitude),0.5)};i=G(n.map((s)=>qt(a,s)),0.8)}if(n.length>=10&&i>150&&o<=15)return"outside";if(t<150)return"unsure";if(n.length<3||o>30||i<25)return"indoors";if(i<50&&o>10)return"indoors";return"unsure"}function Mr(e){let n=String(e||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d+)?)\s*(km|k|m|mi)?$/);if(!n)return null;let r=Number(n[1]),o=n[2]||(r>100?"m":"km"),i=o==="m"?r/1000:o==="mi"?r*1.609344:r;return i>0&&i<1000?Math.round(i*1000)/1000:null}var J=new Set,Ze=!1,V=null;function Ut(e){return e.isConnected&&e.getClientRects().length>0}function et(){return[...J].find((e)=>Ut(e.element))}function X(){let e=et(),t=Boolean(e);if(t===Ze)return;if(Ze=t,t)M.enable(e?.tintColor?{tintColor:e.tintColor}:{});else M.disable()}function Wt(){let e=et();if(!e){M.end();return}Promise.resolve().then(()=>e.run()).catch(()=>{}).finally(()=>M.end())}function Ir(e,t){let n={element:e,tintColor:t.tintColor,run:t.onRefresh};J.add(n);let r=e.ownerDocument?.defaultView;if(!V){let o=M.onRefresh(Wt),i=()=>X();r?.addEventListener("stx:load",i),V=()=>{o(),r?.removeEventListener("stx:load",i)}}return X(),r?.requestAnimationFrame?.(()=>X()),()=>{if(J.delete(n),J.size===0)V?.(),V=null;X()}}var Hr=0.5;function Yt(e,t,n){let r=[];if(n.includes("large")||n.length===0)r.push({name:"large",y:0});if(n.includes("medium"))r.push({name:"medium",y:Math.max(0,Math.round(e-t*0.5))});return r.push({name:"dismiss",y:Math.max(1,e)}),r.sort((o,i)=>o.y-i.y)}function jt(e){let{y:t,velocity:n,stops:r}=e,o=r.filter((s)=>s.name!=="dismiss"),i=r.find((s)=>s.name==="dismiss");if(o.length===0)return"dismiss";if(n>0.5)return(r.filter((l)=>l.y>t+1)[0]??i).name;if(n<-0.5){let s=o.filter((l)=>l.y<t-1);return(s[s.length-1]??o[0]).name}let a=o[o.length-1];if(t>a.y+(i.y-a.y)*0.5)return"dismiss";return o.reduce((s,l)=>Math.abs(l.y-t)<Math.abs(s.y-t)?l:s).name}function zt(e,t=400){if(e<=0)return 0;return e*t*0.55/(t+e*0.55)}function _r(e){let{panel:t}=e,n=null,r=[],o=0,i=()=>e.viewport?.()??t.ownerDocument?.defaultView?.innerHeight??800,a=()=>Yt(t.offsetHeight||t.getBoundingClientRect().height,i(),e.detents()),s=(p)=>{let c=p;if(c.button!==void 0&&c.button!==0)return;if(c.target?.closest?.("button, a, input, select, textarea, [role=button]"))return;let m=a().find((u)=>u.name===e.detent())?.y??0;n={y:c.clientY,base:m,pointerId:c.pointerId},o=m,r=[{y:m,t:c.timeStamp}],t.classList.add("is-dragging");try{p.currentTarget?.setPointerCapture?.(c.pointerId)}catch{}},l=(p)=>{if(!n)return;let c=p,m=n.base+c.clientY-n.y;o=m<0?-zt(-m):m,r.push({y:o,t:c.timeStamp});while(r.length>2&&c.timeStamp-r[0].t>100)r.shift();t.style.transform=`translateY(${o}px)`;let u=t.offsetHeight||1;t.parentElement?.style.setProperty("--native-sheet-presence",String(Math.max(0,Math.min(1,1-o/u))))},d=(p)=>{if(!n)return;let c=p;n=null;let m=r[0],u=Math.max(1,c.timeStamp-m.t),f=(o-m.y)/u;t.classList.remove("is-dragging"),t.style.transform="",t.parentElement?.style.removeProperty("--native-sheet-presence"),e.onSettle(jt({y:o,velocity:f,stops:a()}))};for(let p of e.handles)p.addEventListener("pointerdown",s),p.addEventListener("pointermove",l),p.addEventListener("pointerup",d),p.addEventListener("pointercancel",d);return()=>{for(let p of e.handles)p.removeEventListener("pointerdown",s),p.removeEventListener("pointermove",l),p.removeEventListener("pointerup",d),p.removeEventListener("pointercancel",d)}}var tt=0,ge="";function Dr(e){let t=e.ownerDocument,n=[],r=e;while(r.parentElement&&r!==t.body){for(let a of Array.from(r.parentElement.children)){if(a===r||a.hasAttribute("inert")||a.hasAttribute("data-native-dialog"))continue;if(["SCRIPT","STYLE","TEMPLATE","LINK"].includes(a.tagName))continue;a.setAttribute("inert",""),n.push(a)}r=r.parentElement}let o=t.documentElement;if(tt++===0)ge=o.style.overflow||"",o.style.overflow="hidden";let i=!1;return()=>{if(i)return;i=!0;for(let a of n)a.removeAttribute("inert");if(--tt===0)if(ge)o.style.overflow=ge;else o.style.removeProperty("overflow")}}function Br(e){let t=e.ownerDocument;if(e.parentElement===t.body)return()=>{};let n=t.createComment("native-sheet");return e.parentNode?.insertBefore(n,e),t.body.appendChild(e),()=>{if(n.parentNode)n.parentNode.insertBefore(e,n);else e.remove();n.remove()}}function Fr(e,t){let n=e.documentElement;if(!t){n.removeAttribute("data-native-sheet-card");return}let r=e.defaultView,o=(r?.scrollY??0)+(r?.innerHeight??800)/2;n.style.setProperty("--native-sheet-card-origin",`${Math.round(o)}px`),n.setAttribute("data-native-sheet-card","")}function Gt(e,t){e.style.setProperty("--native-font-scale",String(t.fontScale)),e.toggleAttribute("data-native-reduce-motion",t.reduceMotion),e.toggleAttribute("data-native-reduce-transparency",t.reduceTransparency)}function Vt(e){let t=e.replace(/\s+/g,"").toLowerCase();return!t||t==="transparent"||/^rgba\(\d+,\d+,\d+,0(\.0+)?\)$/.test(t)||/\/0(\.0+)?\)$/.test(t)}function Xt(e){let t=e.defaultView;if(!t?.getComputedStyle)return null;for(let n of[e.body,e.documentElement]){if(!n)continue;let r=t.getComputedStyle(n).backgroundColor;if(r&&!Vt(r))return r}return null}function Jt(e){if(e.documentElement.classList.contains("dark"))return!0;if(e.documentElement.classList.contains("light"))return!1;return Boolean(e.defaultView?.matchMedia?.("(prefers-color-scheme: dark)").matches)}function Ur(e,t={}){let n=t.root??e.documentElement;D.setKeyboardAccessory(t.keyboardAccessory===!0);let r="",o="",i=()=>{let p=Xt(e);if(p&&p!==r)r=p,D.setUnderPageColor(p);let c=Jt(e)?"light":"dark";if(c!==o)o=c,z.setStyle(c)},a=je((p)=>{Gt(n,p),i()}),s=e.defaultView,l=typeof s?.MutationObserver==="function"?new s.MutationObserver(i):null;l?.observe(e.documentElement,{attributes:!0,attributeFilter:["class","style","data-theme"]});let d=s?.matchMedia?.("(prefers-color-scheme: dark)");return d?.addEventListener?.("change",i),s?.addEventListener("stx:load",i),i(),()=>{a(),l?.disconnect(),d?.removeEventListener?.("change",i),s?.removeEventListener("stx:load",i)}}var Yr=64;var Qt=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,Zt=/^(?:0|[1-9]\d*)$/;function rt(e){let t=[],n=[],r=e&&typeof e==="object"&&!Array.isArray(e)?e:{};for(let[o,i]of Object.entries(r)){let a=i&&typeof i==="object"?i:null;if(!a){n.push(`spotlight kind "${o}" is not an object`);continue}let{slots:s,route:l}=a,d=typeof a.noun==="string"&&a.noun.trim()?a.noun.trim():"Item";if(!Qt.test(o)||o.includes("-slot-")){n.push(`spotlight kind "${o}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof s!=="number"||!Number.isInteger(s)||s<=0||s>64){n.push(`spotlight kind "${o}" needs slots between 1 and 64, not ${String(s)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){n.push(`spotlight kind "${o}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}t.push({name:o,slots:s,route:l,noun:d})}return{kinds:t,problems:n}}function q(e,t){return e.find((n)=>n.name===t)??null}function K(e,t,n){let r=q(e,t);if(!r||!Number.isInteger(n)||n<0||n>=r.slots)return null;return`${t}-slot-${n}`}function en(e,t){if(typeof t!=="string")return null;let n=t.lastIndexOf("-slot-");if(n<=0)return null;let r=t.slice(0,n),o=t.slice(n+6);if(!Zt.test(o))return null;let i=Number(o);return K(e,r,i)===t?{kind:r,slot:i}:null}function ot(e){return e.flatMap((t)=>Array.from({length:t.slots},(n,r)=>`${t.name}-slot-${r}`))}function jr(e,t){let n=e&&typeof e==="object"?e:{};if(n.enabled===!1)return[];let o=[...(Array.isArray(n.activityTypes)?n.activityTypes.filter((i)=>typeof i==="string"&&i.trim().length>0):[]).map((i)=>i.trim()),...ot(rt(n.kinds).kinds)];return[...new Set(o)].map((i)=>`${t}.${i}`)}function it(e,t,n){let r=typeof n.name==="string"?n.name.replace(/\s+/g," ").trim():"";if(!r)return`${q(e,t)?.noun??"Item"} #${n.id}`;return r.length>120?`${r.slice(0,119).trimEnd()}…`:r}function tn(e,t,n,r,o=Date.now()){let i=q(e,n);if(!i||!Number.isInteger(r.id)||r.id<=0)return null;let a=t.filter((f)=>f.kind===n),s=it(e,n,r),l=a.find((f)=>f.itemId===r.id)??null,d=l?null:an(a,i.slots),p=l||d!==null?null:sn(a),c=l?.slot??d??p?.slot;if(c===void 0||c===null)return null;let m={kind:n,slot:c,itemId:r.id,title:s,donatedAt:o},u=t.filter((f)=>f.kind!==n||f.slot!==c&&f.itemId!==r.id);return{entries:at(e,[...u,m]),entry:m,evicted:p,changed:!l||l.title!==s}}function nn(e,t,n){let r=e.find((o)=>o.kind===t&&o.itemId===n)??null;return{entries:r?e.filter((o)=>o!==r):[...e],removed:r}}function rn(e,t,n){let r=en(e,n);if(!r)return null;let o=t.find((a)=>a.kind===r.kind&&a.slot===r.slot),i=q(e,r.kind)?.route;return o&&i?i.replace(":id",String(o.itemId)):null}function on(e,t){if(!Array.isArray(t))return[];let n=new Map,r=new Set;for(let o of t){if(!o||typeof o!=="object")continue;let i=o,{kind:a,slot:s,itemId:l,title:d,donatedAt:p}=i;if(typeof a!=="string"||typeof s!=="number"||K(e,a,s)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let c=`${a}-slot-${s}`,m=`${a}#${l}`;if(n.has(c)||r.has(m))continue;n.set(c,{kind:a,slot:s,itemId:l,title:typeof d==="string"&&d.trim()?d:it(e,a,{id:l}),donatedAt:typeof p==="number"&&Number.isFinite(p)&&p>0?p:0}),r.add(m)}return at(e,[...n.values()])}function at(e,t){let n=new Map(e.map((r,o)=>[r.name,o]));return[...t].sort((r,o)=>(n.get(r.kind)??0)-(n.get(o.kind)??0)||r.slot-o.slot)}function an(e,t){let n=new Set(e.map((r)=>r.slot));for(let r=0;r<t;r++)if(!n.has(r))return r;return null}function sn(e){return e.reduce((t,n)=>!t||n.donatedAt<t.donatedAt?n:t,null)}function ln(){let e=globalThis.craft;return e&&typeof e==="object"?e.siri:void 0}var cn="stacks_spotlight_index",un=3000;function zr(e){let t=e.onProblem??((v)=>console.warn(`[spotlight] ${v}`)),n=Array.isArray(e.kinds)?{kinds:[...e.kinds],problems:[]}:rt(e.kinds);for(let v of n.problems)t(v);let r=e.enabled===!1?[]:n.kinds,o=e.storageKey??cn,i=e.legacyStorageKeys??[],a=e.timeoutMs??un,s=e.now??(()=>Date.now()),l=e.bridge??ln,d=null;function p(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function c(){if(d)return d;d=[];let v=p();if(!v)return d;try{let y=[o,...i].map((S)=>v.getItem(S)).find((S)=>S);d=y?on(r,JSON.parse(y)):[]}catch{d=[]}return d}function m(v){d=v;let y=p();if(!y)return;try{y.setItem(o,JSON.stringify(v));for(let S of i)y.removeItem(S)}catch{}}async function u(v){if(!v)return null;let y;try{return await Promise.race([v,new Promise((S)=>{y=setTimeout(()=>S(null),a)})])}catch{return null}finally{if(y!==void 0)clearTimeout(y)}}let f=Promise.resolve();function h(v){let y=f.then(v,v);return f=y.catch(()=>{return}),y}async function A(v,y){let S=l()?.register;if(!S||r.length===0)return!1;return h(async()=>{let k=tn(r,c(),v,y,s()),C=k&&K(r,v,k.entry.slot);if(!k||!C)return!1;if(!k.changed)return m(k.entries),!0;let H=await u(S(k.entry.title,C))!==null;if(H)m(k.entries);return H})}async function N(v,y){let S=l()?.remove;if(!S)return!1;return h(async()=>{let{entries:k,removed:C}=nn(c(),v,y);if(!C)return!1;let H=K(r,v,C.slot),ht=H?await u(S(H))!==null:!1;return m(k),ht})}async function mt(v,y){let S=q(r,v)?.slots;if(!S||!l()?.register)return 0;let k=0;for(let C of[...y].slice(0,S).reverse())if(await A(v,C))k++;return k}async function gt(){let v=l()?.remove;if(!v)return m([]),0;return h(async()=>{let y=0;for(let S of c()){let k=K(r,S.kind,S.slot);if(k&&await u(v(k))!==null)y++}return m([]),y})}return{kinds:r,index:A,sync:mt,remove:N,clear:gt,routeFor:(v)=>rn(r,c(),v),entries:()=>c(),activityTypes:(v)=>ot(r).map((y)=>`${v}.${y}`),reset:()=>{d=null}}}var nt=["craftShortcut","craftSiriShortcut"];function Gr(e,t){let n=(r)=>{let o=r.detail,i=typeof o==="string"?o:o&&typeof o==="object"?o.action??o.type:null,a=typeof i==="string"?e.routeFor(i):null;if(a)t(a)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let r of nt)globalThis.addEventListener(r,n);return()=>{for(let r of nt)globalThis.removeEventListener(r,n)}}import{tabBar as dn}from"craft-native/mobile";var pn=dn;function fn(e){return Array.from(e.querySelectorAll("a[data-native-tab]")).map((t)=>({id:t.getAttribute("href")||"",title:t.getAttribute("data-native-tab")||t.getAttribute("aria-label")||"",symbol:t.getAttribute("data-native-tab-symbol")||"circle",badge:(t.querySelector(".native-tab-badge")?.textContent||"").trim(),current:t.hasAttribute("data-stx-nav-current")||t.classList.contains("is-active")})).filter((t)=>t.id&&t.title)}function mn(e){return{tabs:e.map(({id:n,title:r,symbol:o,badge:i})=>i?{id:n,title:r,symbol:o,badge:i}:{id:n,title:r,symbol:o}),selected:e.find((n)=>n.current)?.id}}function lt(){if(typeof window>"u")return;let e=window.stxRouter;return e&&typeof e==="object"?e:void 0}function gn(){return typeof lt()?.selectTab==="function"}function Jr(e,t={}){let n=(r)=>{if(gn()||r.defaultPrevented)return;let o=r.target?.closest?.("a[data-native-tab]");if(!o||!e.contains(o))return;if(!o.hasAttribute("data-stx-nav-current")&&!o.classList.contains("is-active")&&o.getAttribute("aria-current")!=="page")return;r.preventDefault();let i=e.ownerDocument.defaultView;if(t.scrollToTop)t.scrollToTop();else i?.scrollTo?.({top:0,behavior:i.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"});i?.dispatchEvent(new CustomEvent("stx:tabreselect",{detail:{href:o.getAttribute("href")||""}}))};return e.addEventListener("click",n),()=>e.removeEventListener("click",n)}function st(e){let t=e.trim();return/^#[0-9a-f]{6}$/i.test(t)?t:void 0}var he="stacks:tab-bar-cover";function Qr(e,t){if(t)e.setAttribute("data-native-covers-tab-bar","");else e.removeAttribute("data-native-covers-tab-bar");e.ownerDocument?.defaultView?.dispatchEvent(new Event(he))}function Zr(e,t={}){let n=t.api??pn;if(!n.isAvailable())return null;let r=t.hidden??(()=>Boolean(e.ownerDocument?.querySelector("[data-native-hide-tab-bar], [data-native-covers-tab-bar]"))),o=typeof getComputedStyle==="function"?getComputedStyle(e):null,i=st(o?.getPropertyValue("--native-tab-active")||""),a=st(o?.getPropertyValue("--native-tab-active-dark")||""),s="",l=()=>{if(r()){if(s!=="hidden")n.hide();s="hidden";return}let{tabs:m,selected:u}=mn(fn(e)),f=JSON.stringify({tabs:m,selected:u});if(f===s)return;let h=s&&s!=="hidden"?JSON.parse(s):null;if(h&&u&&JSON.stringify(h.tabs)===JSON.stringify(m))n.select(u);else n.set(m,{selected:u,tint:i,tintDark:a});s=f},d=typeof MutationObserver==="function"?new MutationObserver(l):null;d?.observe(e,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let p=n.onSelect((m)=>{let u=lt();if(u?.selectTab){u.selectTab(m);return}Array.from(e.querySelectorAll("a[data-native-tab]")).find((h)=>h.getAttribute("href")===m)?.click()}),c=()=>l();if(typeof window<"u")window.addEventListener("stx:load",c),window.addEventListener("stx:screen-shown",c),window.addEventListener(he,c);return l(),()=>{if(d?.disconnect(),p(),typeof window<"u")window.removeEventListener("stx:load",c),window.removeEventListener("stx:screen-shown",c),window.removeEventListener(he,c);n.hide()}}var yn={isAvailable:()=>g(()=>be.isAvailable()),getBiometricType:()=>g(()=>be.getBiometricType()),authenticate:(e)=>g(()=>be.authenticate(e))},xn={takePicture:(e)=>g(()=>Q.takePicture(e)),pickImage:()=>g(()=>Q.pickImage()),pickMultiple:(e)=>g(()=>Q.pickMultiple(e)),isAvailable:()=>g(()=>Q.isAvailable())},Sn={getInfo:()=>g(()=>O.getInfo()),getCapabilities:()=>g(()=>O.getCapabilities()),isMobile:()=>O.isMobile(),isIOS:()=>O.isIOS(),isAndroid:()=>O.isAndroid(),getLocale:()=>O.getLocale(),getTimezone:()=>O.getTimezone()},wn=bn,kn={getCurrentPosition:(e)=>g(()=>P.getCurrentPosition(e)),watchPosition:(e,t)=>P.watchPosition(e,t),clearWatch:(e)=>P.clearWatch(e),startRecording:(e)=>g(()=>P.startRecording(e)),pauseRecording:()=>g(()=>P.pauseRecording()),resumeRecording:()=>g(()=>P.resumeRecording()),stopRecording:()=>g(()=>P.stopRecording()),getRecordingState:()=>g(()=>P.getRecordingState()),readRecording:()=>g(()=>P.readRecording())},An={show:(e)=>g(()=>ee.show(e)),schedule:(e)=>g(()=>ee.schedule(e)),cancelAll:()=>g(()=>ee.cancelAll()),setBadge:(e)=>g(()=>ee.setBadge(e))},En={check:(e)=>g(()=>W.check(e)),request:(e)=>g(()=>W.request(e)),checkMultiple:(e)=>g(()=>W.checkMultiple(e)),requestMultiple:(e)=>g(()=>W.requestMultiple(e)),openSettings:()=>g(()=>W.openSettings())},Tn={set:(e,t)=>g(()=>te.set(e,t)),get:(e)=>g(()=>te.get(e)),delete:(e)=>g(()=>te.delete(e)),clear:()=>g(()=>te.clear())},Ln={share:(e)=>g(()=>pt.share(e)),isAvailable:()=>pt.isAvailable()},Rn={request:()=>g(()=>hn.request())},ne={impact:(e)=>Promise.resolve().then(()=>Z.impact(e)).catch(()=>{}),notification:(e)=>Promise.resolve().then(()=>Z.notification(e)).catch(()=>{}),selection:()=>Promise.resolve().then(()=>Z.selection()).catch(()=>{}),vibrate:(e)=>Promise.resolve().then(()=>Z.vibrate(e)).catch(()=>{}),prepare:(e)=>{let t=T("haptics.prepare");return t?Promise.resolve().then(()=>t(e)).then(()=>{},()=>{}):Promise.resolve()}};function ft(e){if(typeof e==="string")return e.trim()||null;if(!e||typeof e!=="object")return null;let t=e.url;return typeof t==="string"&&t.trim()?t:null}var Pn={async getInitialURL(){if(!await I())return null;return ft(await ct.getInitialURL?.())},onLink(e){let t=null,n=!1,r=()=>{if(n)return;t=ct.onLink?.((o,i)=>{let a=ft(o);if(a)e(a,{initial:i?.initial===!0})})??null};if(oe()?.craft)r();else I().then(r);return()=>{n=!0,t?.()}}},Mn={enable:()=>g(()=>ut.enable()),disable:()=>g(()=>ut.disable())},Cn={isAvailable:()=>xe.isAvailable(),speak:(e,t)=>g(()=>xe.speak(e,t)),stop:()=>g(()=>xe.stop())},On={getStatus:()=>g(()=>dt.getStatus()),onChange:(e)=>ae(()=>dt.onChange(e))},In={register:()=>g(()=>ye.register()),onToken:(e)=>ye.onToken(e),onNotification:(e)=>ae(()=>ye.onNotification(e))},Nn={requestAuthorization:(e,t)=>g(()=>U.requestAuthorization(e,t)),getData:(e,t)=>g(()=>U.getData(e,t)),saveWorkout:(e)=>g(()=>U.saveWorkout(e)),getWorkouts:(e)=>g(()=>U.getWorkouts(e)),getDailyStatistics:(e,t)=>g(()=>U.getDailyStatistics(e,t))},Hn={start:(e)=>g(()=>ve.start(e)),update:(e)=>g(()=>ve.update(e)),end:()=>g(()=>ve.end())},_n={send:(e)=>g(()=>Y.send(e)),updateContext:(e)=>g(()=>Y.updateContext(e)),isReachable:()=>g(()=>Y.isReachable()),onMessage:(e)=>Y.onMessage(e),onReachabilityChange:(e)=>Y.onReachabilityChange(e)},oo=vn;function oe(){return x()}function re(){let e=oe()?.craft;if(!e||typeof e!=="object")return null;if(!("platform"in e)||e.platform!=="ios"&&e.platform!=="android")return null;let t="capabilities"in e?e.capabilities:void 0,n=t&&typeof t==="object"&&!Array.isArray(t)?Object.fromEntries(Object.entries(t).filter(([,r])=>typeof r==="boolean")):{};return{platform:e.platform,capabilities:n}}function Se(){return re()!==null}function Dn(e=2000){if(Se()||ie())return Promise.resolve(!0);let t=oe();if(!t||!(t.craft||t.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(Se())},o=setTimeout(r,e);t.addEventListener("craftReady",r,{once:!0})})}function Bn(e){let t=oe();if(!t)return()=>{};if(re()){let r=!1;return queueMicrotask(()=>{if(!r)e(new Event("craftReady"))}),()=>{r=!0}}let n=(r)=>{if(!re())return;t.removeEventListener("craftReady",n),e(r)};return t.addEventListener("craftReady",n),()=>t.removeEventListener("craftReady",n)}async function Fn(e){await ne.impact("light");try{let t=await e();return await ne.notification("success"),t}catch(t){throw await ne.notification("error"),t}}var io={get nativeBridge(){return re()},biometrics:yn,camera:xn,device:Sn,haptics:ne,lifecycle:wn,location:kn,notifications:An,permissions:En,secureStorage:Tn,share:Ln,appReview:Rn,deepLinks:Pn,keepAwake:Mn,speech:Cn,network:On,pushNotifications:In,health:Nn,liveActivities:Hn,watchConnectivity:_n,dialog:_,contextMenu:pe,browser:Ne,symbols:He,statusBar:z,chrome:D,refresh:M,background:B,clipboard:_e,db:De,files:Be,shortcuts:Fe,widgets:Ke,orientation:$e,auth:qe,storeKit:Ue,isNativeMobile:Se,whenNative:Dn,onReady:Bn,withFeedback:Fn};export{Kn as BRIDGE_WAIT_MS,Rr as INDOOR_CHECK_AFTER_S,Yr as MAX_SPOTLIGHT_SLOTS_PER_KIND,kr as ROUTE_GAP_S,Hr as SHEET_FLICK_VELOCITY,he as TAB_BAR_COVER_EVENT,g as afterBridge,Rn as appReview,Gt as applyAppearance,qe as auth,br as backLabelFor,B as background,yn as biometrics,j as bridgePending,Ne as browser,b as callNative,xn as camera,_t as canGoBack,D as chrome,_e as clipboard,zn as confirmAction,pe as contextMenu,Qr as coverTabBar,x as craftHost,bt as craftRoot,Tr as createRouteRecorder,zr as createSpotlightIndex,Ye as currentAppearance,De as db,Bt as deepLinkPath,Pn as deepLinks,Sn as device,_ as dialog,hr as enterNavTrail,Be as files,Kt as fixDistance,er as focusSegment,Sr as followDeepLinks,re as getNativeMobileBridge,gr as goBack,Jr as handleTabReselect,ne as haptics,ie as hasNativeMobileHost,Nn as health,Pr as indoorVerdict,Ur as installNativeChrome,tr as installPressables,Se as isNativeMobile,Ut as isShown,Mn as keepAwake,Nt as largeTitleMetrics,wn as lifecycle,Br as liftToBody,Hn as liveActivities,kn as location,Dr as lockBackground,Zr as mirrorTabBar,io as mobile,xt as nativeFunction,T as nativeFunctionNow,mn as nativeTabs,vr as navTrail,On as network,Mt as normalizeAppearance,ft as normalizeDeepLinkURL,An as notifications,pr as observeLargeTitle,Jn as observeLongPress,Ir as observeNativeRefresh,Ot as observePageScroll,dr as observePullToRefresh,Qn as observeSegmentScrub,_r as observeSheetDrag,je as onAppearance,lr as onBackgroundRefresh,R as onCraftEvent,ar as onMemoryWarning,Bn as onMobileReady,ir as onResume,sr as onSilentPush,Gr as onSpotlightTap,$e as orientation,Ar as paceLabel,Xt as pageBackground,Jt as pageIsDark,F as pageScrollTop,En as permissions,Et as placeMenu,tn as placeSpotlightItem,Re as presentActionSheet,Te as presentAlert,se as presentChoice,Le as presentConfirm,Pe as presentContextMenu,Fr as presentPageAsCard,yr as previousScreenPath,It as pullDistance,In as pushNotifications,on as readSpotlightEntries,rt as readSpotlightKinds,fn as readTabLinks,M as refresh,nn as removeSpotlightItem,fr as resolveScrollHost,Je as routeStats,gn as routerHandlesTabs,zt as rubberBand,Tn as secureStorage,Pt as segmentAt,Zn as segmentForKey,jt as settleSheet,Ln as share,Yt as sheetStops,Fe as shortcuts,Gn as showContextMenuFor,Cn as speech,Er as speedLabel,oo as splash,K as spotlightAction,ot as spotlightActions,jr as spotlightActivityTypes,ln as spotlightBridge,q as spotlightKind,rn as spotlightRoute,en as spotlightSlot,it as spotlightTitle,z as statusBar,Ue as storeKit,ae as subscribeWhenReady,He as symbols,pn as tabBar,de as toNativeRect,xr as trailEntryFor,At as trapFocus,Mr as typedDistanceKm,$t as usableFixes,jn as useActionSheet,_n as watchConnectivity,I as whenBridgeReady,Dn as whenNativeMobile,Ke as widgets,Fn as withNativeFeedback};
|
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type { ActionSheetOptions, AlertOptions, ConfirmOptions, ContextMenuOptions, NativeRect } from './sheets';
|
|
2
|
+
export type { ActionSheetOptions, AlertOptions, ChoiceOptions, ConfirmOptions, ContextMenuItem, ContextMenuOptions, DialogAction, DialogActionStyle, NativeRect } from './sheets';
|
|
3
|
+
declare function hostNavigator(): Navigator | undefined;
|
|
4
|
+
/** A rectangle the bridge can serialise: getBoundingClientRect() returns a DOMRect, which it cannot. */
|
|
5
|
+
export declare function toNativeRect(rect: { x?: number, y?: number, left?: number, top?: number, width: number, height: number }): NativeRect;
|
|
6
|
+
/** Shows an action sheet: `useActionSheet()(options)`, for a page that keeps the function. */
|
|
7
|
+
export declare function useActionSheet(): (options: ActionSheetOptions) => Promise<string | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Asks before doing something. `await confirmAction({ title: 'Delete this
|
|
10
|
+
* workout?', confirmLabel: 'Delete', destructive: true })` raises the iOS
|
|
11
|
+
* destructive-action sheet and resolves `true` when the action was chosen.
|
|
12
|
+
*/
|
|
13
|
+
export declare function confirmAction(options: ConfirmActionOptions): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Shows a context menu beside `element`, the one that was long-pressed.
|
|
16
|
+
* Resolves with the chosen item's id, or null.
|
|
17
|
+
*/
|
|
18
|
+
export declare function showContextMenuFor(element: Element, options: Omit<ContextMenuOptions, 'anchor'>): Promise<string | null>;
|
|
19
|
+
declare function openOnTheWeb(url: string, options: BrowserOpenOptions): BrowserResult;
|
|
20
|
+
declare function symbolKey(name: string, options: SymbolOptions): string;
|
|
21
|
+
declare function downloadOnTheWeb(href: string, filename: string): string | null;
|
|
22
|
+
declare function pickOnTheWeb(types: string[]): Promise<PickedFile | null>;
|
|
23
|
+
declare function screenOrientation(): LockableOrientation | undefined;
|
|
24
|
+
declare const done: () => true;
|
|
25
|
+
declare const no: () => false;
|
|
26
|
+
declare const nothing: () => null;
|
|
27
|
+
export declare const dialog: DialogApi;
|
|
28
|
+
export declare const contextMenu: ContextMenuApi;
|
|
29
|
+
export declare const browser: BrowserApi;
|
|
30
|
+
declare const symbolRequests: Map<string, Promise<string | null>>;
|
|
31
|
+
declare const symbolImages: Map<string, string | null>;
|
|
32
|
+
export declare const symbols: SymbolsApi;
|
|
33
|
+
export declare const statusBar: StatusBarApi;
|
|
34
|
+
export declare const chrome: ChromeApi;
|
|
35
|
+
export declare const refresh: RefreshApi;
|
|
36
|
+
export declare const background: BackgroundApi;
|
|
37
|
+
export declare const clipboard: ClipboardApi;
|
|
38
|
+
export declare const db: DatabaseApi;
|
|
39
|
+
export declare const files: FilesApi;
|
|
40
|
+
export declare const shortcuts: ShortcutsApi;
|
|
41
|
+
export declare const widgets: WidgetsApi;
|
|
42
|
+
/**
|
|
43
|
+
* @defaultValue
|
|
44
|
+
* ```ts
|
|
45
|
+
* {
|
|
46
|
+
* portrait: 'portrait-primary',
|
|
47
|
+
* portraitUpsideDown: 'portrait-secondary',
|
|
48
|
+
* landscape: 'landscape',
|
|
49
|
+
* landscapeLeft: 'landscape-primary',
|
|
50
|
+
* landscapeRight: 'landscape-secondary'
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
declare const WEB_ORIENTATIONS: Record<OrientationLock, string>;
|
|
55
|
+
export declare const orientation: OrientationApi;
|
|
56
|
+
export declare const auth: AuthApi;
|
|
57
|
+
export declare const storeKit: StoreKitApi;
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Dialogs
|
|
60
|
+
export declare interface DialogApi {
|
|
61
|
+
alert: (options: AlertOptions) => Promise<void>
|
|
62
|
+
confirm: (options: ConfirmOptions) => Promise<boolean>
|
|
63
|
+
actionSheet: (options: ActionSheetOptions) => Promise<string | null>
|
|
64
|
+
}
|
|
65
|
+
export declare interface ConfirmActionOptions extends ConfirmOptions {
|
|
66
|
+
style?: 'sheet' | 'alert'
|
|
67
|
+
anchor?: NativeRect
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Context menus
|
|
71
|
+
export declare interface ContextMenuApi {
|
|
72
|
+
show: (options: ContextMenuOptions) => Promise<string | null>
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// In-app browser
|
|
76
|
+
export declare interface BrowserOpenOptions {
|
|
77
|
+
mode?: 'safari' | 'auth'
|
|
78
|
+
callbackScheme?: string
|
|
79
|
+
}
|
|
80
|
+
export declare interface BrowserResult {
|
|
81
|
+
url?: string
|
|
82
|
+
cancelled: boolean
|
|
83
|
+
}
|
|
84
|
+
export declare interface BrowserApi {
|
|
85
|
+
open: (url: string, options?: BrowserOpenOptions) => Promise<BrowserResult>
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// SF Symbols
|
|
89
|
+
export declare interface SymbolOptions {
|
|
90
|
+
pointSize?: number
|
|
91
|
+
weight?: 'ultralight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black'
|
|
92
|
+
color?: string
|
|
93
|
+
scale?: 'small' | 'medium' | 'large'
|
|
94
|
+
}
|
|
95
|
+
export declare interface SymbolsApi {
|
|
96
|
+
isAvailable: () => boolean
|
|
97
|
+
image: (name: string, options?: SymbolOptions) => Promise<string | null>
|
|
98
|
+
cached: (name: string, options?: SymbolOptions) => string | null | undefined
|
|
99
|
+
clearCache: () => void
|
|
100
|
+
}
|
|
101
|
+
export declare interface StatusBarApi {
|
|
102
|
+
setStyle: (style: StatusBarStyle) => Promise<boolean>
|
|
103
|
+
}
|
|
104
|
+
export declare interface ChromeApi {
|
|
105
|
+
setUnderPageColor: (color: string) => Promise<boolean>
|
|
106
|
+
setKeyboardAccessory: (visible: boolean) => Promise<boolean>
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Native pull-to-refresh
|
|
110
|
+
export declare interface RefreshApi {
|
|
111
|
+
isAvailable: () => boolean
|
|
112
|
+
enable: (options?: { tintColor?: string }) => Promise<boolean>
|
|
113
|
+
disable: () => Promise<boolean>
|
|
114
|
+
end: () => Promise<boolean>
|
|
115
|
+
onRefresh: (callback: () => void) => () => void
|
|
116
|
+
}
|
|
117
|
+
export declare interface BackgroundApi {
|
|
118
|
+
complete: (ok: boolean) => Promise<boolean>
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Clipboard
|
|
122
|
+
export declare interface ClipboardApi {
|
|
123
|
+
write: (text: string) => Promise<boolean>
|
|
124
|
+
read: () => Promise<string | null>
|
|
125
|
+
}
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// The app's own SQLite database (Documents/craft.db)
|
|
128
|
+
export declare interface DatabaseExecuteResult {
|
|
129
|
+
rowsAffected: number
|
|
130
|
+
lastInsertId: number
|
|
131
|
+
}
|
|
132
|
+
export declare interface DatabaseApi {
|
|
133
|
+
isAvailable: () => boolean
|
|
134
|
+
query: <T = Record<string, unknown>>(sql: string, params?: unknown[]) => Promise<T[] | null>
|
|
135
|
+
execute: (sql: string, params?: unknown[]) => Promise<DatabaseExecuteResult | null>
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Files, documents and the camera's scanner
|
|
139
|
+
export declare interface PickedFile {
|
|
140
|
+
name: string
|
|
141
|
+
path?: string
|
|
142
|
+
data?: string
|
|
143
|
+
mimeType?: string
|
|
144
|
+
}
|
|
145
|
+
export declare interface ScannedCode {
|
|
146
|
+
type: string
|
|
147
|
+
data: string
|
|
148
|
+
}
|
|
149
|
+
export declare interface FilesApi {
|
|
150
|
+
openPDF: (source: string, page?: number) => Promise<boolean>
|
|
151
|
+
takeScreenshot: () => Promise<string | null>
|
|
152
|
+
scanQRCode: () => Promise<ScannedCode | null>
|
|
153
|
+
pickFile: (types?: string[]) => Promise<PickedFile | null>
|
|
154
|
+
saveFile: (data: string, filename: string, mimeType?: string) => Promise<string | null>
|
|
155
|
+
downloadFile: (url: string, filename: string) => Promise<string | null>
|
|
156
|
+
}
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Home screen quick actions
|
|
159
|
+
export declare interface HomeScreenShortcut {
|
|
160
|
+
type: string
|
|
161
|
+
title: string
|
|
162
|
+
subtitle?: string
|
|
163
|
+
symbol?: string
|
|
164
|
+
userInfo?: Record<string, string>
|
|
165
|
+
}
|
|
166
|
+
export declare interface ShortcutsApi {
|
|
167
|
+
set: (shortcuts: HomeScreenShortcut[]) => Promise<boolean>
|
|
168
|
+
clear: () => Promise<boolean>
|
|
169
|
+
onShortcut: (callback: (type: string) => void) => () => void
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Home screen widgets (WidgetKit)
|
|
173
|
+
export declare interface WidgetsApi {
|
|
174
|
+
update: (data: Record<string, unknown>) => Promise<boolean>
|
|
175
|
+
reload: () => Promise<boolean>
|
|
176
|
+
}
|
|
177
|
+
export declare interface OrientationApi {
|
|
178
|
+
lock: (orientation: OrientationLock) => Promise<boolean>
|
|
179
|
+
unlock: () => Promise<boolean>
|
|
180
|
+
}
|
|
181
|
+
declare interface LockableOrientation { lock?: (orientation: string) => Promise<void>, unlock?: () => void }
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Sign in with Apple
|
|
184
|
+
export declare interface AppleSignInResult {
|
|
185
|
+
userId: string
|
|
186
|
+
email?: string
|
|
187
|
+
name?: string
|
|
188
|
+
identityToken?: string
|
|
189
|
+
authorizationCode?: string
|
|
190
|
+
}
|
|
191
|
+
export declare interface AuthApi {
|
|
192
|
+
signInWithApple: () => Promise<AppleSignInResult | null>
|
|
193
|
+
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// In-app purchase (StoreKit 2)
|
|
196
|
+
export declare interface StoreProduct {
|
|
197
|
+
id: string
|
|
198
|
+
displayName: string
|
|
199
|
+
description: string
|
|
200
|
+
price: string
|
|
201
|
+
displayPrice: string
|
|
202
|
+
}
|
|
203
|
+
export declare interface StoreTransaction {
|
|
204
|
+
transactionId: string
|
|
205
|
+
productId: string
|
|
206
|
+
}
|
|
207
|
+
export declare interface StoreKitApi {
|
|
208
|
+
isAvailable: () => boolean
|
|
209
|
+
products: (ids: string[]) => Promise<StoreProduct[]>
|
|
210
|
+
purchase: (id: string) => Promise<StoreTransaction | null>
|
|
211
|
+
restore: () => Promise<StoreTransaction[]>
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// System chrome
|
|
215
|
+
export type StatusBarStyle = 'default' | 'light' | 'dark';
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
// Orientation
|
|
218
|
+
export type OrientationLock = 'portrait' | 'portraitUpsideDown' | 'landscape' | 'landscapeLeft' | 'landscapeRight';
|
package/dist/navigation.d.ts
CHANGED
|
@@ -24,6 +24,17 @@ export declare function enterNavTrail(trail: NavTrailEntry[], path: string, limi
|
|
|
24
24
|
export declare function backLabelFor(previous: NavTrailEntry | null, fallback: string, max?: number): string;
|
|
25
25
|
/** The trail for this window: it outlives each screen, not a full reload. */
|
|
26
26
|
export declare function navTrail(): NavTrailEntry[];
|
|
27
|
+
/**
|
|
28
|
+
* The path a back from the screen on show returns to, in its own tab's stack.
|
|
29
|
+
*
|
|
30
|
+
* The trail is one list for the window, but the stx router keeps a stack per
|
|
31
|
+
* tab, so a screen opened in Calendar after a visit to Today goes back to
|
|
32
|
+
* Calendar, not to whatever was entered last. Answers null at a tab's root,
|
|
33
|
+
* and undefined when there is no router that keeps tabs to ask.
|
|
34
|
+
*/
|
|
35
|
+
export declare function previousScreenPath(): string | null | undefined;
|
|
36
|
+
/** The latest trail entry for `path`, which carries that screen's name. */
|
|
37
|
+
export declare function trailEntryFor(trail: NavTrailEntry[], path: string): NavTrailEntry | null;
|
|
27
38
|
/**
|
|
28
39
|
* The in-app path a deep link opens, or null when it is not this app's.
|
|
29
40
|
*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Whether an element is laid out in view: connected, and not inside something hidden. */
|
|
2
|
+
export declare function isShown(element: HTMLElement): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Refreshes the screen `element` belongs to with the native control, for as
|
|
5
|
+
* long as the returned function is not called. Check `refresh.isAvailable()`
|
|
6
|
+
* first: a shell without the control needs the web gesture instead.
|
|
7
|
+
*/
|
|
8
|
+
export declare function observeNativeRefresh(element: HTMLElement, options: NativeRefreshOptions): () => void;
|
|
9
|
+
export declare interface NativeRefreshOptions {
|
|
10
|
+
tintColor?: string
|
|
11
|
+
onRefresh: () => unknown
|
|
12
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where each detent leaves a panel `height` tall on a `viewport` tall screen:
|
|
3
|
+
* large shows all of it, medium the bottom half of the screen, and dismissed
|
|
4
|
+
* none.
|
|
5
|
+
*/
|
|
6
|
+
export declare function sheetStops(height: number, viewport: number, detents: readonly SheetDetent[]): SheetStop[];
|
|
7
|
+
/**
|
|
8
|
+
* Where a released sheet goes.
|
|
9
|
+
*
|
|
10
|
+
* A flick (faster than 0.5px/ms) goes on to the next stop in its direction,
|
|
11
|
+
* past the lowest detent meaning dismissed. A slow release dismisses once the
|
|
12
|
+
* sheet is more than half way down from its lowest detent, and otherwise
|
|
13
|
+
* springs back to the nearest detent.
|
|
14
|
+
*/
|
|
15
|
+
export declare function settleSheet(state: { y: number, velocity: number, stops: SheetStop[] }): SheetSettle;
|
|
16
|
+
/** iOS's resistance past the top: the further it is pulled, the less it gives. */
|
|
17
|
+
export declare function rubberBand(overshoot: number, dimension?: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* Lets a sheet be dragged by its handles. While dragging, the panel follows
|
|
20
|
+
* the finger with `is-dragging` set (the stylesheet turns its transition off)
|
|
21
|
+
* and its parent's `--native-sheet-presence` (1 open, 0 gone) dims the
|
|
22
|
+
* backdrop to match; on release both are handed back to the stylesheet, which
|
|
23
|
+
* animates to wherever `onSettle` puts it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function observeSheetDrag(options: SheetDragOptions): () => void;
|
|
26
|
+
/**
|
|
27
|
+
* Holds the page still and out of reach behind `keep`: everything outside it
|
|
28
|
+
* becomes inert (no taps, no focus, hidden from VoiceOver) and the document
|
|
29
|
+
* stops scrolling. Returns the release. Nested sheets count, so the page
|
|
30
|
+
* scrolls again only once the last has closed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function lockBackground(keep: HTMLElement): () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Moves `element` to the end of the body, out of every stacking context and
|
|
35
|
+
* transform on the way, and returns the way back: to where it was, or out of
|
|
36
|
+
* the document when that place has gone (the page navigated away).
|
|
37
|
+
*/
|
|
38
|
+
export declare function liftToBody(element: HTMLElement): () => void;
|
|
39
|
+
/**
|
|
40
|
+
* The iOS card presentation: while a large sheet is up, the page behind it
|
|
41
|
+
* shrinks back from the screen's edges, centred on what was in view. Undone by
|
|
42
|
+
* calling it with `false`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function presentPageAsCard(doc: Document, on: boolean): void;
|
|
45
|
+
/** A flick faster than this (CSS pixels a millisecond) moves on to the next stop. */
|
|
46
|
+
export declare const SHEET_FLICK_VELOCITY: 0.5;
|
|
47
|
+
/** A resting place, as the panel's downward offset from its fully open position. */
|
|
48
|
+
export declare interface SheetStop {
|
|
49
|
+
name: SheetSettle
|
|
50
|
+
y: number
|
|
51
|
+
}
|
|
52
|
+
export declare interface SheetDragOptions {
|
|
53
|
+
panel: HTMLElement
|
|
54
|
+
handles: HTMLElement[]
|
|
55
|
+
detents: () => SheetDetent[]
|
|
56
|
+
detent: () => SheetDetent
|
|
57
|
+
viewport?: () => number
|
|
58
|
+
onSettle: (to: SheetSettle) => void
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* What makes a bottom sheet behave like a UISheetPresentationController:
|
|
62
|
+
* dragged by its grabber or header, flicked away, resting at a medium or a
|
|
63
|
+
* large detent, and holding the page behind it still and out of reach.
|
|
64
|
+
*/
|
|
65
|
+
export type SheetDetent = 'medium' | 'large';
|
|
66
|
+
export type SheetSettle = SheetDetent | 'dismiss';
|
package/dist/sheets.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps Tab and Shift+Tab inside `container`: called from a keydown listener,
|
|
3
|
+
* it moves focus from one end to the other instead of out of it.
|
|
4
|
+
*/
|
|
5
|
+
export declare function trapFocus(container: HTMLElement, event: KeyboardEvent): void;
|
|
6
|
+
/**
|
|
7
|
+
* An alert or action sheet drawn in HTML. Resolves with the chosen action's
|
|
8
|
+
* id, or null when it is dismissed or Cancel is chosen.
|
|
9
|
+
*/
|
|
10
|
+
export declare function presentChoice(options: ChoiceOptions): Promise<string | null>;
|
|
11
|
+
export declare function presentAlert(options: AlertOptions): Promise<void>;
|
|
12
|
+
export declare function presentConfirm(options: ConfirmOptions): Promise<boolean>;
|
|
13
|
+
export declare function presentActionSheet(options: ActionSheetOptions): Promise<string | null>;
|
|
14
|
+
/** Where a menu of `size` opens beside `anchor` within a `viewport`, 12px clear of its edges. */
|
|
15
|
+
export declare function placeMenu(anchor: NativeRect, size: { width: number, height: number }, viewport: { width: number, height: number }): { top: number, left: number, origin: string };
|
|
16
|
+
/**
|
|
17
|
+
* A context menu drawn in HTML over a blurred page, beside the element that
|
|
18
|
+
* was pressed. Resolves with the chosen item's id, or null when dismissed.
|
|
19
|
+
*/
|
|
20
|
+
export declare function presentContextMenu(options: ContextMenuOptions): Promise<string | null>;
|
|
21
|
+
export declare interface DialogAction {
|
|
22
|
+
id: string
|
|
23
|
+
title: string
|
|
24
|
+
style?: DialogActionStyle
|
|
25
|
+
}
|
|
26
|
+
/** A rectangle in CSS pixels relative to the viewport, as getBoundingClientRect() reports. */
|
|
27
|
+
export declare interface NativeRect {
|
|
28
|
+
x: number
|
|
29
|
+
y: number
|
|
30
|
+
width: number
|
|
31
|
+
height: number
|
|
32
|
+
}
|
|
33
|
+
export declare interface ChoiceOptions {
|
|
34
|
+
variant: 'alert' | 'sheet'
|
|
35
|
+
title?: string
|
|
36
|
+
message?: string
|
|
37
|
+
actions: DialogAction[]
|
|
38
|
+
cancelLabel?: string
|
|
39
|
+
}
|
|
40
|
+
export declare interface ContextMenuItem {
|
|
41
|
+
id: string
|
|
42
|
+
title: string
|
|
43
|
+
symbol?: string
|
|
44
|
+
icon?: string
|
|
45
|
+
destructive?: boolean
|
|
46
|
+
disabled?: boolean
|
|
47
|
+
}
|
|
48
|
+
export declare interface ContextMenuOptions {
|
|
49
|
+
items: ContextMenuItem[]
|
|
50
|
+
anchor: NativeRect
|
|
51
|
+
title?: string
|
|
52
|
+
}
|
|
53
|
+
export declare interface AlertOptions {
|
|
54
|
+
title: string
|
|
55
|
+
message?: string
|
|
56
|
+
okLabel?: string
|
|
57
|
+
}
|
|
58
|
+
export declare interface ConfirmOptions {
|
|
59
|
+
title: string
|
|
60
|
+
message?: string
|
|
61
|
+
confirmLabel?: string
|
|
62
|
+
cancelLabel?: string
|
|
63
|
+
destructive?: boolean
|
|
64
|
+
}
|
|
65
|
+
export declare interface ActionSheetOptions {
|
|
66
|
+
title?: string
|
|
67
|
+
message?: string
|
|
68
|
+
actions: DialogAction[]
|
|
69
|
+
anchor?: NativeRect
|
|
70
|
+
cancelLabel?: string
|
|
71
|
+
}
|
|
72
|
+
export type DialogActionStyle = 'default' | 'destructive' | 'cancel';
|
package/dist/shell.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NativeAppearance } from './events';
|
|
2
|
+
/** Writes an appearance where CSS can read it: `--native-font-scale` and `data-native-reduce-*`. */
|
|
3
|
+
export declare function applyAppearance(root: HTMLElement, appearance: NativeAppearance): void;
|
|
4
|
+
/**
|
|
5
|
+
* The colour behind the page: the first opaque background of the body or the
|
|
6
|
+
* root element. The under-page area should read as more of the page when it
|
|
7
|
+
* is pulled past its top or bottom, not as a white or black band.
|
|
8
|
+
*/
|
|
9
|
+
export declare function pageBackground(doc: Document): string | null;
|
|
10
|
+
/** Whether the page draws dark: the `.dark` class, or the system's preference where the app follows it. */
|
|
11
|
+
export declare function pageIsDark(doc: Document): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Keeps the native chrome in step with the page until the returned function
|
|
14
|
+
* is called: on install, whenever the colour scheme flips (the `.dark` class
|
|
15
|
+
* or the system's), after each navigation, and on every appearance change.
|
|
16
|
+
*/
|
|
17
|
+
export declare function installNativeChrome(doc: Document, options?: NativeChromeOptions): () => void;
|
|
18
|
+
export declare interface NativeChromeOptions {
|
|
19
|
+
root?: HTMLElement
|
|
20
|
+
keyboardAccessory?: boolean
|
|
21
|
+
}
|