@stacksjs/mobile 0.75.165 → 0.75.167

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 CHANGED
@@ -173,6 +173,51 @@ with fixes recorded separately. In a browser and on Android `isAvailable()` is
173
173
  false, the state says `available: false` and nothing fires. Word iOS's prompt
174
174
  with `ios.usageDescriptions.NSBluetoothAlwaysUsageDescription`.
175
175
 
176
+ ## Apple Watch scheduled workouts
177
+
178
+ `scheduledWorkouts` puts structured workouts on the paired Apple Watch through
179
+ WorkoutKit's scheduler (iOS 17+): each appears in the watch's Workout app on
180
+ its day, with its warmup, repeated blocks, cooldown, goals and alerts. iOS
181
+ only, behind `capabilities.scheduledWorkouts`; only an app with it compiles in
182
+ and links WorkoutKit. The calls work on the page and on native stx screens.
183
+ A plan is plain JSON in SI units, its `id` a UUID the app keeps for it.
184
+
185
+ ```ts
186
+ import { scheduledWorkouts } from '@stacksjs/mobile'
187
+
188
+ if (await scheduledWorkouts.isSupported()) { // false off an iPhone, never rejects
189
+ await scheduledWorkouts.requestAuthorization() // iOS's prompt, once; call it from a tap
190
+ const kept = await scheduledWorkouts.list() // [{ id, date, hour, minute, complete }]
191
+ await scheduledWorkouts.schedule({
192
+ id: '6f1c2b8e-5a7d-4c3e-9b1a-2d4e6f8a0b1c',
193
+ date: '2026-10-20', hour: 6, minute: 30, // local; 07:00 without a time
194
+ workout: {
195
+ activity: 'running', location: 'outdoor', displayName: '4 x 1 km',
196
+ warmup: { goal: { type: 'time', seconds: 600 } },
197
+ blocks: [{ iterations: 4, steps: [
198
+ { purpose: 'work', step: { goal: { type: 'distance', meters: 1000 }, alert: { type: 'speed', min: 4.1, max: 4.4 } } },
199
+ { purpose: 'recovery', step: { goal: { type: 'time', seconds: 120 } } },
200
+ ] }],
201
+ },
202
+ })
203
+ await scheduledWorkouts.remove(kept[0].id) // every day it is on
204
+ }
205
+ ```
206
+
207
+ Goals are `open`, `time` (seconds), `distance` (meters) and `energy`
208
+ (kilocalories); alerts `heartRate`, `power`, `speed` (m/s), `cadence` ranges and
209
+ `heartRateZone` / `powerZone`. An activity or goal WorkoutKit refuses rejects
210
+ the call with a message naming it; an alert it refuses is left out and named
211
+ in the result's `droppedAlerts`. `schedule` also rejects LIMIT_REACHED (the
212
+ watch holds 15) and NOT_SCHEDULED when nothing kept the plan, as without a
213
+ paired watch. In a browser and on Android `isSupported()` is false and every
214
+ other call rejects `unsupported`.
215
+
216
+ For tests, `createScheduledWorkoutsFake()` from `@stacksjs/mobile/testing` is a
217
+ `craft.scheduledWorkouts` that answers like the shell. On the iOS simulator,
218
+ which never has a watch, the app's `CraftFakeWorkoutScheduler` default makes
219
+ the shell keep plans itself (`xcrun simctl spawn <device> defaults write <bundle id> CraftFakeWorkoutScheduler -bool YES`).
220
+
176
221
  ## Apple Music
177
222
 
178
223
  `music` shows what the Music app is playing (title, artist, album, a small
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Bundled TypeScript declarations
3
- * Generated from 17 source files
3
+ * Generated from 18 source files
4
4
  */
5
5
 
6
6
  import { NativeTab } from 'craft-native/mobile';
@@ -522,6 +522,80 @@ declare interface RouteRecorder {
522
522
  readonly heartRate: HeartRateSample[]
523
523
  }
524
524
 
525
+ // From: src/scheduled-workouts.ts
526
+ declare function native(): Record<string, any> | undefined;
527
+ /** The rejection every call but `isSupported()` gets where nothing can schedule. */
528
+ declare function scheduledWorkoutsUnsupported(): Error;
529
+ declare function authorizationOf(value: unknown): ScheduledWorkoutsAuthorization;
530
+ /** A row of `list()`, or null for one that is not a scheduled plan. */
531
+ declare function normalizeScheduledWorkout(value: unknown): ScheduledWorkout | null;
532
+ declare function call<T>(method: ScheduledWorkoutsMethod, normalize: (value: unknown) => T, ...args: unknown[]): Promise<T>;
533
+ declare const scheduledWorkouts: ScheduledWorkoutsApi;
534
+ declare interface AppleWorkoutStep {
535
+ goal: AppleWorkoutGoal
536
+ alert?: AppleWorkoutAlert
537
+ displayName?: string
538
+ }
539
+ declare interface AppleIntervalBlock {
540
+ iterations: number
541
+ steps: Array<{ purpose: 'work' | 'recovery', step: AppleWorkoutStep }>
542
+ }
543
+ declare interface AppleCustomWorkout {
544
+ activity: string
545
+ location: 'indoor' | 'outdoor' | 'unknown'
546
+ swimmingLocation?: 'pool' | 'openWater'
547
+ poolLengthMeters?: number
548
+ displayName: string
549
+ warmup?: AppleWorkoutStep
550
+ cooldown?: AppleWorkoutStep
551
+ blocks: AppleIntervalBlock[]
552
+ }
553
+ declare interface AppleWorkoutPlan {
554
+ id: string
555
+ date: string
556
+ hour?: number
557
+ minute?: number
558
+ workout: AppleCustomWorkout
559
+ }
560
+ /** A plan on the watch's schedule. */
561
+ declare interface ScheduledWorkout {
562
+ id: string
563
+ date: string
564
+ hour?: number
565
+ minute?: number
566
+ complete: boolean
567
+ }
568
+ declare interface ScheduleWorkoutResult {
569
+ id: string
570
+ droppedAlerts?: string[]
571
+ }
572
+ declare interface ScheduledWorkoutsApi {
573
+ isAvailable: () => boolean
574
+ supports: (method: ScheduledWorkoutsMethod) => boolean
575
+ isSupported: () => Promise<boolean>
576
+ authorization: () => Promise<ScheduledWorkoutsAuthorization>
577
+ requestAuthorization: () => Promise<ScheduledWorkoutsAuthorization>
578
+ list: () => Promise<ScheduledWorkout[]>
579
+ schedule: (plan: AppleWorkoutPlan) => Promise<ScheduleWorkoutResult>
580
+ remove: (id: string) => Promise<boolean>
581
+ removeAll: () => Promise<number>
582
+ }
583
+ type ScheduledWorkoutsAuthorization = 'authorized' | 'denied' | 'notDetermined' | 'restricted' | 'unsupported';
584
+ type AppleWorkoutGoal = | { type: 'open' }
585
+ | { type: 'time', seconds: number }
586
+ | { type: 'distance', meters: number }
587
+ | { type: 'energy', kilocalories: number }
588
+ type AppleWorkoutAlert = | { type: 'heartRate', min: number, max: number }
589
+ | { type: 'heartRateZone', zone: number }
590
+ /** Watts (PowerRangeAlert). */
591
+ | { type: 'power', min: number, max: number }
592
+ | { type: 'powerZone', zone: number }
593
+ /** Metres per second, the current speed (SpeedRangeAlert); a pace range is sent as speed. */
594
+ | { type: 'speed', min: number, max: number }
595
+ /** Per minute (CadenceRangeAlert). */
596
+ | { type: 'cadence', min: number, max: number }
597
+ type ScheduledWorkoutsMethod = 'isSupported' | 'authorization' | 'requestAuthorization' | 'list' | 'schedule' | 'remove' | 'removeAll';
598
+
525
599
  // From: src/session-clock.ts
526
600
  declare function startSessionClock(now: number): SessionClock;
527
601
  declare function pauseSessionClock(clock: SessionClock, now: number): SessionClock;
@@ -1251,6 +1325,7 @@ declare interface CraftMobileCapabilities {
1251
1325
  deepLinks?: boolean
1252
1326
  flashlight?: boolean
1253
1327
  music?: boolean
1328
+ scheduledWorkouts?: boolean
1254
1329
  network?: boolean
1255
1330
  deviceInfo?: boolean
1256
1331
  badge?: boolean
@@ -1299,6 +1374,7 @@ declare interface MobileApi {
1299
1374
  brightness: BrightnessApi
1300
1375
  music: MusicApi
1301
1376
  heartRate: HeartRateApi
1377
+ scheduledWorkouts: import('./scheduled-workouts').ScheduledWorkoutsApi
1302
1378
  speech: SpeechApi
1303
1379
  network: NetworkApi
1304
1380
  pushNotifications: PushNotificationsApi
@@ -1827,6 +1903,6 @@ type HealthSleepStage = 'inBed' | 'awake' | 'asleep' | 'core' | 'deep' | 'rem';
1827
1903
  /** The health reads and writes an installed app build may or may not answer. */
1828
1904
  type HealthReadMethod = 'getWorkouts' | 'getDailyStatistics' | 'getHeartRateSamples' | 'getSleepIntervals' | 'saveMindfulSession' | 'getMindfulSessions';
1829
1905
 
1830
- export { normalizeDeepLinkURL, getNativeMobileBridge, isNativeMobile, whenNativeMobile, onMobileReady, withNativeFeedback, biometrics, camera, device, lifecycle, location, notifications, permissions, secureStorage, share, appReview, haptics, deepLinks, snapshots, keepAwake, brightness, music, heartRate, speech, network, pushNotifications, health, liveActivities, watchConnectivity, splash, mobile, craftHost, craftRoot, hasNativeMobileHost, bridgePending, whenBridgeReady, nativeFunctionNow, nativeFunction, callNative, afterBridge, subscribeWhenReady, onCraftEvent, BRIDGE_WAIT_MS, CraftHost, CallNativeOptions, observeLongPress, segmentAt, observeSegmentScrub, segmentForKey, focusSegment, installPressables, LongPressOptions, SegmentScrubOptions, currentAppearance, normalizeAppearance, onAppearance, onResume, onMemoryWarning, onSilentPush, onBackgroundRefresh, NativeAppearance, pageScrollTop, observePageScroll, pullDistance, observePullToRefresh, largeTitleMetrics, observeLargeTitle, resolveScrollHost, ScrollHost, PullToRefreshOptions, LargeTitleMetrics, LargeTitleOptions, canGoBack, goBack, enterNavTrail, backLabelFor, navTrail, previousScreenPath, goBackToTabRoot, trailEntryFor, deepLinkPath, followDeepLinks, HistoryHost, NavTrailEntry, TabRootHost, attachHeartRate, fixDistance, usableFixes, routeStats, paceLabel, speedLabel, createRouteRecorder, HEART_RATE_MATCH_MS, ROUTE_GAP_S, RouteFix, RouteStats, RouteStatsOptions, RouteRecorderOptions, RouteRecorder, startSessionClock, pauseSessionClock, resumeSessionClock, sessionClockElapsed, SessionClock, indoorVerdict, typedDistanceKm, INDOOR_CHECK_AFTER_S, IndoorFix, IndoorVerdict, toNativeRect, useActionSheet, confirmAction, showContextMenuFor, dialog, contextMenu, browser, symbols, statusBar, chrome, refresh, background, clipboard, db, files, shortcuts, widgets, orientation, auth, storeKit, DialogApi, ConfirmActionOptions, ContextMenuApi, BrowserOpenOptions, BrowserResult, BrowserApi, SymbolOptions, SymbolsApi, StatusBarApi, ChromeApi, RefreshApi, BackgroundApi, ClipboardApi, DatabaseExecuteResult, DatabaseApi, PickedFile, ScannedCode, FilesApi, HomeScreenShortcut, ShortcutsApi, WidgetsApi, OrientationApi, AppleSignInResult, AppleSignInOptions, AuthApi, StoreProduct, StoreTransaction, StoreKitApi, StatusBarStyle, OrientationLock, ActionSheetOptions, AlertOptions, ChoiceOptions, ConfirmOptions, ContextMenuItem, ContextMenuOptions, DialogAction, DialogActionStyle, NativeRect, isShown, observeNativeRefresh, NativeRefreshOptions, sheetStops, settleSheet, rubberBand, observeSheetDrag, lockBackground, liftToBody, presentPageAsCard, SHEET_FLICK_VELOCITY, SheetStop, SheetDragOptions, SheetDetent, SheetSettle, trapFocus, presentChoice, presentAlert, presentConfirm, presentActionSheet, placeMenu, presentContextMenu, applyAppearance, pageBackground, pageIsDark, installNativeChrome, NativeChromeOptions, readSpotlightKinds, spotlightKind, spotlightAction, spotlightSlot, spotlightActions, spotlightActivityTypes, spotlightTitle, placeSpotlightItem, removeSpotlightItem, spotlightRoute, readSpotlightEntries, spotlightBridge, createSpotlightIndex, onSpotlightTap, MAX_SPOTLIGHT_SLOTS_PER_KIND, SpotlightKind, SpotlightKindInput, SpotlightItem, SpotlightEntry, SpotlightKindsResult, SpotlightPlacement, SpotlightBridge, SpotlightIndexOptions, SpotlightIndex, readTabLinks, nativeTabs, routerHandlesTabs, handleTabReselect, coverTabBar, mirrorTabBar, tabBar, TAB_BAR_COVER_EVENT, TabBarApi, TabLink, TabReselectOptions, MirrorTabBarOptions, CraftMobileCapabilities, CraftMobileBridge, CraftReadyEvent, MobileApi, DeviceInfo, DeviceCapabilities, CameraOptions, PhotoResult, Location, LocationOptions, LocationRecordingState, LocationRecordingResult, ShareOptions, NotificationOptions, DeviceApi, HapticsApi, PermissionsApi, CameraApi, BiometricsApi, SecureStorageApi, LocationApi, ShareApi, LifecycleApi, NotificationsApi, KeepAwakeApi, BrightnessApi, SpeechOptions, SpeechApi, NowPlaying, MusicSkipOptions, HeartRateDevice, HeartRateRecordingState, HeartRateState, HeartRateReading, HeartRateSample, HeartRateRecordingApi, HeartRateApi, MusicApi, DeepLinksApi, SnapshotsApi, NetworkStatus, NetworkApi, AppReviewApi, PushNotificationsApi, HealthDataOptions, HealthDataResult, HealthWorkoutLocation, HealthWorkout, HealthWorkoutResult, HealthWorkoutQuery, HealthWorkoutSample, HealthDailyValue, HealthSampleQuery, HealthHeartRateQuery, HealthHeartRateSample, HealthSleepInterval, HealthMindfulSession, HealthMindfulSessionResult, HealthMindfulSessionQuery, HealthMindfulSample, HealthAuthorizationOptions, HealthApi, LiveActivityState, LiveActivityOptions, LiveActivitiesApi, WatchConnectivityApi, HapticStyle, HapticNotificationType, PermissionType, PermissionStatus, BiometricType, AppState, HapticKind, MusicAuthorization, MusicPlaybackState, MusicMethod, HeartRateAuthorization, BluetoothState, HeartRateConnection, HeartRateMethod, HealthDataType, HealthDailyType, HealthWorkoutType, HealthWorkoutActivity, HealthSleepStage, HealthReadMethod };
1906
+ export { normalizeDeepLinkURL, getNativeMobileBridge, isNativeMobile, whenNativeMobile, onMobileReady, withNativeFeedback, biometrics, camera, device, lifecycle, location, notifications, permissions, secureStorage, share, appReview, haptics, deepLinks, snapshots, keepAwake, brightness, music, heartRate, speech, network, pushNotifications, health, liveActivities, watchConnectivity, splash, mobile, craftHost, craftRoot, hasNativeMobileHost, bridgePending, whenBridgeReady, nativeFunctionNow, nativeFunction, callNative, afterBridge, subscribeWhenReady, onCraftEvent, BRIDGE_WAIT_MS, CraftHost, CallNativeOptions, observeLongPress, segmentAt, observeSegmentScrub, segmentForKey, focusSegment, installPressables, LongPressOptions, SegmentScrubOptions, currentAppearance, normalizeAppearance, onAppearance, onResume, onMemoryWarning, onSilentPush, onBackgroundRefresh, NativeAppearance, pageScrollTop, observePageScroll, pullDistance, observePullToRefresh, largeTitleMetrics, observeLargeTitle, resolveScrollHost, ScrollHost, PullToRefreshOptions, LargeTitleMetrics, LargeTitleOptions, canGoBack, goBack, enterNavTrail, backLabelFor, navTrail, previousScreenPath, goBackToTabRoot, trailEntryFor, deepLinkPath, followDeepLinks, HistoryHost, NavTrailEntry, TabRootHost, attachHeartRate, fixDistance, usableFixes, routeStats, paceLabel, speedLabel, createRouteRecorder, HEART_RATE_MATCH_MS, ROUTE_GAP_S, RouteFix, RouteStats, RouteStatsOptions, RouteRecorderOptions, RouteRecorder, scheduledWorkoutsUnsupported, normalizeScheduledWorkout, scheduledWorkouts, AppleWorkoutStep, AppleIntervalBlock, AppleCustomWorkout, AppleWorkoutPlan, ScheduledWorkout, ScheduleWorkoutResult, ScheduledWorkoutsApi, ScheduledWorkoutsAuthorization, AppleWorkoutGoal, AppleWorkoutAlert, ScheduledWorkoutsMethod, startSessionClock, pauseSessionClock, resumeSessionClock, sessionClockElapsed, SessionClock, indoorVerdict, typedDistanceKm, INDOOR_CHECK_AFTER_S, IndoorFix, IndoorVerdict, toNativeRect, useActionSheet, confirmAction, showContextMenuFor, dialog, contextMenu, browser, symbols, statusBar, chrome, refresh, background, clipboard, db, files, shortcuts, widgets, orientation, auth, storeKit, DialogApi, ConfirmActionOptions, ContextMenuApi, BrowserOpenOptions, BrowserResult, BrowserApi, SymbolOptions, SymbolsApi, StatusBarApi, ChromeApi, RefreshApi, BackgroundApi, ClipboardApi, DatabaseExecuteResult, DatabaseApi, PickedFile, ScannedCode, FilesApi, HomeScreenShortcut, ShortcutsApi, WidgetsApi, OrientationApi, AppleSignInResult, AppleSignInOptions, AuthApi, StoreProduct, StoreTransaction, StoreKitApi, StatusBarStyle, OrientationLock, ActionSheetOptions, AlertOptions, ChoiceOptions, ConfirmOptions, ContextMenuItem, ContextMenuOptions, DialogAction, DialogActionStyle, NativeRect, isShown, observeNativeRefresh, NativeRefreshOptions, sheetStops, settleSheet, rubberBand, observeSheetDrag, lockBackground, liftToBody, presentPageAsCard, SHEET_FLICK_VELOCITY, SheetStop, SheetDragOptions, SheetDetent, SheetSettle, trapFocus, presentChoice, presentAlert, presentConfirm, presentActionSheet, placeMenu, presentContextMenu, applyAppearance, pageBackground, pageIsDark, installNativeChrome, NativeChromeOptions, readSpotlightKinds, spotlightKind, spotlightAction, spotlightSlot, spotlightActions, spotlightActivityTypes, spotlightTitle, placeSpotlightItem, removeSpotlightItem, spotlightRoute, readSpotlightEntries, spotlightBridge, createSpotlightIndex, onSpotlightTap, MAX_SPOTLIGHT_SLOTS_PER_KIND, SpotlightKind, SpotlightKindInput, SpotlightItem, SpotlightEntry, SpotlightKindsResult, SpotlightPlacement, SpotlightBridge, SpotlightIndexOptions, SpotlightIndex, readTabLinks, nativeTabs, routerHandlesTabs, handleTabReselect, coverTabBar, mirrorTabBar, tabBar, TAB_BAR_COVER_EVENT, TabBarApi, TabLink, TabReselectOptions, MirrorTabBarOptions, CraftMobileCapabilities, CraftMobileBridge, CraftReadyEvent, MobileApi, DeviceInfo, DeviceCapabilities, CameraOptions, PhotoResult, Location, LocationOptions, LocationRecordingState, LocationRecordingResult, ShareOptions, NotificationOptions, DeviceApi, HapticsApi, PermissionsApi, CameraApi, BiometricsApi, SecureStorageApi, LocationApi, ShareApi, LifecycleApi, NotificationsApi, KeepAwakeApi, BrightnessApi, SpeechOptions, SpeechApi, NowPlaying, MusicSkipOptions, HeartRateDevice, HeartRateRecordingState, HeartRateState, HeartRateReading, HeartRateSample, HeartRateRecordingApi, HeartRateApi, MusicApi, DeepLinksApi, SnapshotsApi, NetworkStatus, NetworkApi, AppReviewApi, PushNotificationsApi, HealthDataOptions, HealthDataResult, HealthWorkoutLocation, HealthWorkout, HealthWorkoutResult, HealthWorkoutQuery, HealthWorkoutSample, HealthDailyValue, HealthSampleQuery, HealthHeartRateQuery, HealthHeartRateSample, HealthSleepInterval, HealthMindfulSession, HealthMindfulSessionResult, HealthMindfulSessionQuery, HealthMindfulSample, HealthAuthorizationOptions, HealthApi, LiveActivityState, LiveActivityOptions, LiveActivitiesApi, WatchConnectivityApi, HapticStyle, HapticNotificationType, PermissionType, PermissionStatus, BiometricType, AppState, HapticKind, MusicAuthorization, MusicPlaybackState, MusicMethod, HeartRateAuthorization, BluetoothState, HeartRateConnection, HeartRateMethod, HealthDataType, HealthDailyType, HealthWorkoutType, HealthWorkoutActivity, HealthSleepStage, HealthReadMethod };
1831
1907
  export { NativeTab } from 'craft-native/mobile';
1832
1908
  export { NativeTabBarOptions } from 'craft-native/mobile';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{appReview as kn,biometrics as Ae,brightness as re,camera as ie,deepLinks as gt,device as D,haptics as oe,health as V,heartRate as A,keepAwake as ht,lifecycle as En,liveActivities as ke,location as N,music as P,network as bt,notifications as ae,permissions as G,pushNotifications as Ee,secureStorage as se,share as vt,speech as Te,snapshots as le,splash as Tn,watchConnectivity as X}from"craft-native/mobile";var Jn=2500;function S(){if(typeof window>"u")return;return window}function xt(){let e=S()?.craft;return e&&typeof e==="object"?e:void 0}function wt(){return typeof navigator>"u"?"":navigator.userAgent||""}function pe(){let e=S();if(!e)return!1;if(e.CraftAndroid)return!0;return Boolean(e.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(wt())}function J(){let e=S();if(!e||e.craft)return!1;return pe()||Boolean(e.webkit?.messageHandlers?.craft)}function B(e=15000){let t=S();if(t?.craft)return Promise.resolve(!0);if(!t||!J())return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(i),t.removeEventListener("craftReady",r),n(Boolean(t.craft))},i=setTimeout(r,e);t.addEventListener("craftReady",r)})}function At(e,t){if(!e)return null;let n=t.split("."),r=e;for(let o of n.slice(0,-1))if(r=r?.[o],!r||typeof r!=="object"&&typeof r!=="function")return null;let i=r?.[n[n.length-1]];return typeof i==="function"?i.bind(r):null}function L(e){return At(xt(),e)}async function kt(e,t=2500){let n=L(e);if(n||!J())return n;return await B(t),L(e)}async function v(e,t,n,r={}){let i=await kt(e,r.timeoutMs);if(!i)return n();try{return await i(...t)}catch(o){if(r.fallbackOnError)return n();throw o}}async function c(e,t=2500){if(J())await B(t);return e()}function _(e,t=2500){let n,r=!1;if(!J())n=e();else B(t).then(()=>{if(!r)n=e()});return()=>{if(r=!0,typeof n==="function")n()}}function O(e,t){let n=S();if(!n)return()=>{};let r=(i)=>t(i.detail??{});return n.addEventListener(e,r),()=>n.removeEventListener(e,r)}var Le="native-dialog-styles",Et=`
1
+ import{appReview as Cn,biometrics as Re,brightness as ie,camera as ae,deepLinks as St,device as _,haptics as se,health as V,heartRate as w,keepAwake as xt,lifecycle as On,liveActivities as Te,location as N,music as P,network as At,notifications as le,permissions as X,pushNotifications as Le,secureStorage as ce,share as wt,speech as Me,snapshots as ue,splash as Nn,watchConnectivity as J}from"craft-native/mobile";var or=2500;function S(){if(typeof window>"u")return;return window}function me(){let e=S()?.craft;return e&&typeof e==="object"?e:void 0}function Rt(){return typeof navigator>"u"?"":navigator.userAgent||""}function ge(){let e=S();if(!e)return!1;if(e.CraftAndroid)return!0;return Boolean(e.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(Rt())}function Q(){let e=S();if(!e||e.craft)return!1;return ge()||Boolean(e.webkit?.messageHandlers?.craft)}function B(e=15000){let t=S();if(t?.craft)return Promise.resolve(!0);if(!t||!Q())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 Tt(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 L(e){return Tt(me(),e)}async function Lt(e,t=2500){let n=L(e);if(n||!Q())return n;return await B(t),L(e)}async function v(e,t,n,r={}){let o=await Lt(e,r.timeoutMs);if(!o)return n();try{return await o(...t)}catch(i){if(r.fallbackOnError)return n();throw i}}async function c(e,t=2500){if(Q())await B(t);return e()}function D(e,t=2500){let n,r=!1;if(!Q())n=e();else B(t).then(()=>{if(!r)n=e()});return()=>{if(r=!0,typeof n==="function")n()}}function O(e,t){let n=S();if(!n)return()=>{};let r=(o)=>t(o.detail??{});return n.addEventListener(e,r),()=>n.removeEventListener(e,r)}var Ce="native-dialog-styles",Mt=`
2
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
3
  .native-dialog-backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 0.3); opacity: 0; transition: opacity 220ms ease; }
4
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%); }
@@ -52,4 +52,4 @@ import{appReview as kn,biometrics as Ae,brightness as re,camera as ie,deepLinks
52
52
  .native-dialog-group, .native-menu { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--native-dialog-solid, rgb(242 242 247)); }
53
53
  .dark .native-dialog-group, .dark .native-menu { background: var(--native-dialog-solid-dark, rgb(44 44 46)); }
54
54
  }
55
- `;function Me(){return S()?.document}function Tt(e){if(e.getElementById(Le))return;let t=e.createElement("style");t.id=Le,t.textContent=Et,(e.head??e.documentElement).appendChild(t)}var Rt=0;function E(e,t,n,r){let i=e.createElement(t);if(i.className=n,r!==void 0)i.textContent=r;return i}var Pe='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Lt(e,t){if(t.key!=="Tab")return;let n=Array.from(e.querySelectorAll(Pe));if(n.length===0){t.preventDefault();return}let r=n[0],i=n[n.length-1],o=e.ownerDocument.activeElement;if(t.shiftKey&&(o===r||!e.contains(o)))t.preventDefault(),i.focus();else if(!t.shiftKey&&(o===i||!e.contains(o)))t.preventDefault(),r.focus()}function Ce(e,t,n,r){Tt(e);let i=S(),o=e.activeElement,a=E(e,"div",`native-dialog native-dialog--${t}`);return a.setAttribute("data-native-dialog",t),a.appendChild(E(e,"div","native-dialog-backdrop")),new Promise((s)=>{let l=!1,g=(h)=>{if(l)return;l=!0,a.classList.remove("is-open"),e.removeEventListener("keydown",p,!0),setTimeout(()=>{if(a.remove(),o&&typeof o.focus==="function")o.focus()},260),s(h)},p=(h)=>{if(h.key==="Escape"){h.preventDefault(),g(r());return}Lt(u,h)},u=n({root:a,settle:g});a.appendChild(u),e.body.appendChild(a),e.addEventListener("keydown",p,!0);let f=i;(typeof f?.requestAnimationFrame==="function"?(h)=>f.requestAnimationFrame(()=>f.requestAnimationFrame(h)):(h)=>setTimeout(h,16))(()=>{if(!l)a.classList.add("is-open")}),(u.querySelector("[data-native-autofocus]")??u.querySelector(Pe))?.focus()})}function fe(e){let t=Me();if(!t?.body)return Promise.resolve(null);let n=`native-dialog-${++Rt}`,r=e.actions.find((a)=>a.style==="cancel"),i=e.variant==="sheet"?e.actions.filter((a)=>a.style!=="cancel"):e.actions,o=e.variant==="sheet"?r??{id:"__cancel",title:e.cancelLabel||"Cancel",style:"cancel"}:void 0;return Ce(t,e.variant,({root:a,settle:s})=>{let l=(d)=>d.style==="cancel"?null:d.id,g=E(t,"div","native-dialog-panel");g.setAttribute("role","alertdialog"),g.setAttribute("aria-modal","true"),g.tabIndex=-1;let p=E(t,"div","native-dialog-group");if(e.title||e.message){let d=E(t,"div","native-dialog-header");if(e.title){let m=E(t,"p","native-dialog-title",e.title);m.id=`${n}-title`,d.appendChild(m),g.setAttribute("aria-labelledby",m.id)}if(e.message){let m=E(t,"p","native-dialog-message",e.message);m.id=`${n}-message`,d.appendChild(m),g.setAttribute("aria-describedby",m.id)}p.appendChild(d)}let u=E(t,"div","native-dialog-actions");if(e.variant==="alert"&&i.length===2)u.classList.add("is-row");for(let d of i){let m=E(t,"button",`native-dialog-action${d.style==="destructive"?" is-destructive":""}${d.style==="cancel"?" is-cancel":""}`,d.title);m.type="button",m.setAttribute("data-action-id",d.id),m.addEventListener("click",()=>s(l(d))),u.appendChild(m)}if(p.appendChild(u),g.appendChild(p),o){let d=E(t,"div","native-dialog-group"),m=E(t,"button","native-dialog-action is-cancel",o.title);m.type="button",m.setAttribute("data-action-id",o.id),m.addEventListener("click",()=>s(null)),d.appendChild(m),g.appendChild(d)}let f=a.querySelector(".native-dialog-backdrop");if(e.variant==="sheet")f?.addEventListener("click",()=>s(null));return g},()=>{if(e.variant==="sheet")return null;if(r)return null;return i.length===1?i[0].id:null})}async function Oe(e){await fe({variant:"alert",title:e.title,message:e.message,actions:[{id:"ok",title:e.okLabel||"OK"}]})}async function Ne(e){return await fe({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 Ie(e){return fe({variant:"sheet",title:e.title,message:e.message,actions:e.actions,cancelLabel:e.cancelLabel})}function Mt(e,t,n){let o=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,g=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:g,left:o,origin:`${s||l<12?"top":"bottom"} ${p}`}}function He(e){let t=Me();if(!t?.body)return Promise.resolve(null);let n=S();return Ce(t,"menu",({root:r,settle:i})=>{let o=E(t,"div","native-menu native-dialog-panel");if(o.setAttribute("role","menu"),e.title)o.appendChild(E(t,"p","native-menu-title",e.title)),o.setAttribute("aria-label",e.title);for(let a of e.items){let s=E(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(E(t,"span","native-menu-label",a.title)),a.icon){let l=E(t,"i",`native-menu-icon ${a.icon}`);l.setAttribute("aria-hidden","true"),s.appendChild(l)}s.addEventListener("click",()=>i(a.id)),o.appendChild(s)}return r.querySelector(".native-dialog-backdrop")?.addEventListener("click",()=>i(null)),queueMicrotask(()=>{let a=o.getBoundingClientRect?.(),s=Mt(e.anchor,{width:a?.width||248,height:a?.height||e.items.length*44},{width:n?.innerWidth||390,height:n?.innerHeight||844});o.style.top=`${s.top}px`,o.style.left=`${s.left}px`,o.style.setProperty("--native-menu-origin",s.origin)}),o},()=>null)}var Fe=()=>!0,R=()=>!1,M=()=>null;function _e(){return S()?.navigator??(typeof navigator>"u"?void 0:navigator)}function be(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 q={alert:(e)=>v("dialog.alert",[e],()=>Oe(e),{fallbackOnError:!0}).then(()=>{}),confirm:(e)=>v("dialog.confirm",[e],()=>Ne(e),{fallbackOnError:!0}).then(Boolean),actionSheet:async(e)=>{let t={...e,anchor:e.anchor?be(e.anchor):void 0},n=await v("dialog.actionSheet",[t],()=>Ie(e),{fallbackOnError:!0});if(typeof n!=="string")return null;return e.actions.find((r)=>r.id===n)?.style==="cancel"?null:n}};function rr(){return(e)=>q.actionSheet(e)}async function ir(e){if((e.style??(e.destructive?"sheet":"alert"))==="alert")return q.confirm(e);return await q.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 ve={show:async(e)=>{let t={title:e.title,anchor:be(e.anchor),items:e.items.map(({id:r,title:i,symbol:o,destructive:a,disabled:s})=>({id:r,title:i,symbol:o,destructive:a,disabled:s}))},n=await v("contextMenu.show",[t],()=>He(e),{fallbackOnError:!0});return typeof n==="string"?n:null}};function or(e,t){return ve.show({...t,anchor:be(e.getBoundingClientRect())})}function Pt(e,t){let n=S();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 Ke={open:async(e,t={})=>{let n=await v("browser.open",[e,t],()=>Pt(e,t),{fallbackOnError:!0});if(!n||typeof n!=="object")return{cancelled:!1};let{url:r,cancelled:i}=n;return typeof r==="string"?{url:r,cancelled:Boolean(i)}:{cancelled:Boolean(i)}}},me=new Map,ge=new Map;function De(e,t){return`${e}|${t.pointSize??""}|${t.weight??""}|${t.color??""}|${t.scale??""}`}var $e={isAvailable:()=>L("symbols.image")!==null,image:(e,t={})=>{let n=De(e,t),r=me.get(n);if(r)return r;let i=v("symbols.image",[e,t],M).then((o)=>typeof o==="string"&&o.startsWith("data:")?o:null,M).then((o)=>(ge.set(n,o),o));return me.set(n,i),i},cached:(e,t={})=>ge.get(De(e,t)),clearCache:()=>{me.clear(),ge.clear()}},Q={setStyle:(e)=>v("statusBar.setStyle",[e],R,{fallbackOnError:!0}).then((t)=>t!==!1)},U={setUnderPageColor:(e)=>v("chrome.setUnderPageColor",[e],R,{fallbackOnError:!0}).then((t)=>t!==!1),setKeyboardAccessory:(e)=>v("chrome.setKeyboardAccessory",[e],R,{fallbackOnError:!0}).then((t)=>t!==!1)},I={isAvailable:()=>L("refresh.enable")!==null,enable:(e)=>v("refresh.enable",[e??{}],R,{fallbackOnError:!0}).then((t)=>t!==!1),disable:()=>v("refresh.disable",[],R,{fallbackOnError:!0}).then((e)=>e!==!1),end:()=>v("refresh.end",[],R,{fallbackOnError:!0}).then((e)=>e!==!1),onRefresh:(e)=>O("craftRefresh",()=>e())},W={complete:(e)=>v("background.complete",[e],R,{fallbackOnError:!0}).then((t)=>t!==!1)},qe={write:(e)=>v("clipboard.write",[e],async()=>{let t=_e()?.clipboard;if(!t?.writeText)return!1;return t.writeText(e).then(Fe,R)},{fallbackOnError:!0}).then((t)=>t!==!1),read:()=>v("clipboard.read",[],async()=>{let e=_e()?.clipboard;if(!e?.readText)return null;return e.readText().catch(M)},{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null)},Ue={isAvailable:()=>L("db.query")!==null,query:(e,t=[])=>v("db.query",[e,t],M).then((n)=>Array.isArray(n)?n:null),execute:(e,t=[])=>v("db.execute",[e,t],M).then((n)=>{if(!n||typeof n!=="object")return null;let{rowsAffected:r,lastInsertId:i}=n;return{rowsAffected:Number(r)||0,lastInsertId:Number(i)||0}})};function he(e,t){let n=S()?.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 Ct(e){let t=S()?.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((o)=>o.includes("/")||o.startsWith(".")?o:`.${o}`).join(",");let i=(o)=>{r.remove(),n(o)};r.addEventListener("cancel",()=>i(null)),r.addEventListener("change",()=>{let o=r.files?.[0];if(!o)return i(null);let a=new FileReader;a.onload=()=>i({name:o.name,mimeType:o.type||void 0,data:typeof a.result==="string"?a.result:void 0}),a.onerror=()=>i({name:o.name,mimeType:o.type||void 0}),a.readAsDataURL(o)}),t.body.appendChild(r),r.click()})}var We={openPDF:(e,t=0)=>v("openPDF",[e,t],()=>{let n=S();return Boolean(n?.open?.(e,"_blank","noopener"))}).then((n)=>n!==!1),takeScreenshot:()=>v("takeScreenshot",[],M,{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null),scanQRCode:()=>v("scanQRCode",[],M).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},M),pickFile:(e=[])=>v("pickFile",[e],()=>Ct(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}},M),saveFile:(e,t,n)=>v("saveFile",[e,t,n],()=>{if(e.startsWith("data:"))return he(e,t);let r=new Blob([e],{type:n||"text/plain"}),i=URL.createObjectURL(r),o=he(i,t);return setTimeout(()=>URL.revokeObjectURL(i),1000),o}).then((r)=>typeof r==="string"?r:null),downloadFile:(e,t)=>v("downloadFile",[e,t],()=>he(e,t)).then((n)=>typeof n==="string"?n:null)},ze={set:(e)=>v("shortcuts.set",[e.map(({symbol:t,...n})=>t?{...n,iconName:t}:n)],R).then((t)=>t!==!1),clear:()=>v("shortcuts.clear",[],R).then((e)=>e!==!1),onShortcut:(e)=>O("craftShortcut",(t)=>{if(typeof t.type==="string")e(t.type)})},Ye={update:(e)=>v("widget.update",[e],R).then((t)=>t!==!1),reload:()=>v("widget.reload",[],R).then((e)=>e!==!1)},Ot={portrait:"portrait-primary",portraitUpsideDown:"portrait-secondary",landscape:"landscape",landscapeLeft:"landscape-primary",landscapeRight:"landscape-secondary"};function Be(){return S()?.screen?.orientation}var je={lock:(e)=>v("lockOrientation",[e],()=>{let t=Be();return t?.lock?t.lock(Ot[e]).then(Fe,R):!1}).then((t)=>t!==!1),unlock:()=>v("unlockOrientation",[],()=>(Be()?.unlock?.(),!0)).then((e)=>e!==!1)},Ve={signInWithApple:(e={})=>v("signInWithApple",e.nonce?[{nonce:e.nonce}]:[],M).then((t)=>{if(!t||typeof t!=="object"||typeof t.userId!=="string")return null;return t})},Ge={isAvailable:()=>L("iap.purchase")!==null,products:(e)=>v("iap.getProducts",[e],()=>[]).then((t)=>Array.isArray(t)?t:[]),purchase:(e)=>v("iap.purchase",[e],M).then((t)=>t&&typeof t==="object"?t:null,(t)=>{if(/cancel/i.test(String(t?.message??t)))return null;throw t}),restore:()=>v("iap.restore",[],()=>[]).then((e)=>Array.isArray(e)?e:[])};function lr(e,t){let n=t.delay??500,r=t.tolerance??10,i=null,o=null,a=!1,s=()=>{if(i)clearTimeout(i);if(i=null,o&&!a)t.onPressEnd?.();o=null},l=(f)=>{let d=f;if(d.button!==void 0&&d.button!==0)return;a=!1,o={x:d.clientX,y:d.clientY},t.onPressStart?.(),i=setTimeout(()=>{if(i=null,!o)return;a=!0,t.onLongPress({...o}),o=null},n)},g=(f)=>{if(!o)return;let d=f;if(Math.hypot(d.clientX-o.x,d.clientY-o.y)>r)s()},p=(f)=>{if(!a)return;a=!1,f.preventDefault(),f.stopPropagation()},u=(f)=>f.preventDefault();return e.addEventListener("pointerdown",l),e.addEventListener("pointermove",g),e.addEventListener("pointerup",s),e.addEventListener("pointercancel",s),e.addEventListener("pointerleave",s),e.addEventListener("click",p,!0),e.addEventListener("contextmenu",u),()=>{s(),e.removeEventListener("pointerdown",l),e.removeEventListener("pointermove",g),e.removeEventListener("pointerup",s),e.removeEventListener("pointercancel",s),e.removeEventListener("pointerleave",s),e.removeEventListener("click",p,!0),e.removeEventListener("contextmenu",u)}}function Nt(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 cr(e,t){let n=null,r=null,i=!1,o=0,a=(d)=>{let m=e.getBoundingClientRect();return Nt(d,{left:m.left+2,width:m.width-4},t.count())},s=(d)=>{let m=d;if(m.button!==void 0&&m.button!==0)return;let h=a(m.clientX);if(h!==t.selected())return;n=h,o=h,i=!1,r=m.pointerId;try{e.setPointerCapture?.(m.pointerId)}catch{}t.onPress?.(!0)},l=(d)=>{if(n===null)return;let m=a(d.clientX);if(m===o)return;i=!0,o=m,t.onScrub(m)},g=(d)=>{if(n===null)return;if(r!==null)try{e.releasePointerCapture?.(r)}catch{}if(t.onPress?.(!1),d&&i)t.onCommit(o);else if(i)t.onScrub(n);n=null,r=null},p=(d)=>{if(!i)return;i=!1,d.preventDefault(),d.stopPropagation()},u=()=>g(!0),f=()=>g(!1);return e.addEventListener("pointerdown",s),e.addEventListener("pointermove",l),e.addEventListener("pointerup",u),e.addEventListener("pointercancel",f),e.addEventListener("click",p,!0),()=>{e.removeEventListener("pointerdown",s),e.removeEventListener("pointermove",l),e.removeEventListener("pointerup",u),e.removeEventListener("pointercancel",f),e.removeEventListener("click",p,!0)}}function ur(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 dr(e,t){e.querySelectorAll('[role="tab"]')[t]?.focus()}function pr(e){let t=(n)=>{if(!n.target?.closest?.("[data-native-pressable]"))return;let i=L("haptics.prepare");if(i)Promise.resolve().then(()=>i("impact")).catch(()=>{})};return e.addEventListener("touchstart",t,{passive:!0,capture:!0}),()=>e.removeEventListener("touchstart",t,{capture:!0})}function ye(e){let t=S();try{return Boolean(t?.matchMedia?.(e).matches)}catch{return!1}}function Xe(e){return e!==null&&e!==void 0&&e!=="false"&&e!=="0"}function Je(){let e=S()?.document?.documentElement,t=Number.parseFloat(e?.style?.getPropertyValue("--craft-font-scale")||"");return{fontScale:Number.isFinite(t)&&t>0?t:1,reduceMotion:Xe(e?.getAttribute("data-craft-reduce-motion"))||ye("(prefers-reduced-motion: reduce)"),reduceTransparency:Xe(e?.getAttribute("data-craft-reduce-transparency"))||ye("(prefers-reduced-transparency: reduce)"),colorScheme:e?.classList?.contains("dark")||ye("(prefers-color-scheme: dark)")?"dark":"light"}}function It(e){let t=Je(),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 Qe(e,t={}){if(t.immediate!==!1)e(Je());return O("craftAppearance",(n)=>e(It(n)))}function hr(e){return O("craftResume",(t)=>e({backgroundedMs:Number(t.backgroundedMs)||0}))}function br(e){return O("craftMemoryWarning",()=>e())}function Ze(e){return(t)=>{Promise.resolve().then(()=>e(t)).then(()=>W.complete(!0),()=>W.complete(!1))}}function vr(e){let t=Ze(e);return O("craftSilentPush",(n)=>t(n.payload??{}))}function yr(e){let t=Ze(()=>e());return O("craftBackgroundRefresh",()=>t(void 0))}import{haptics as Ht}from"craft-native/mobile";function Se(){if(typeof window>"u")return;return window}function z(e=Se()){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 _t(e,t=Se()){if(!t)return()=>{};let n=!1,r=typeof requestAnimationFrame==="function"?requestAnimationFrame:(o)=>setTimeout(o,16),i=()=>{if(n)return;n=!0,r(()=>{n=!1,e(z(t))})};return e(z(t)),t.addEventListener("scroll",i,{passive:!0}),()=>t.removeEventListener("scroll",i)}function Dt(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 wr(e){let t=e.host??Se();if(!t)return()=>{};let n=e.threshold??72,r=null,i=!1,o=!1,a=typeof requestAnimationFrame==="function"?requestAnimationFrame:(h)=>setTimeout(h,16),s=null,l=(h)=>{s=null,e.onPull?.(h,i,{bounce:Math.min(h,Math.max(0,-z(t)))})},g=(h)=>{let k=s!==null;if(s=h,k)return;a(()=>{if(s!==null)l(s)})},p=(h)=>{let k=h.touches?.[0];return k?k.clientY:null},u=(h)=>{if(o||z(t)>0)return;r=p(h),i=!1},f=(h)=>{if(r===null)return;let k=p(h);if(k===null)return;let C=Dt(z(t),k-r);if(!i&&C>=n)i=!0,Promise.resolve(Ht.impact("medium")).catch(()=>{});else if(i&&C<n*0.8)i=!1;g(C)},d=async()=>{if(r===null)return;if(r=null,!i){l(0);return}i=!1,o=!0,l(n);try{await e.onRefresh()}finally{o=!1,l(0)}},m=()=>{if(r===null)return;r=null,i=!1,l(0)};return t.addEventListener("touchstart",u,{passive:!0}),t.addEventListener("touchmove",f,{passive:!0}),t.addEventListener("touchend",d),t.addEventListener("touchcancel",m),()=>{s=null,t.removeEventListener("touchstart",u),t.removeEventListener("touchmove",f),t.removeEventListener("touchend",d),t.removeEventListener("touchcancel",m)}}function Bt(e,t=52){let n=Math.max(1,t),r=Math.min(1,Math.max(0,e/n)),i=e<0?1+Math.min(0.1,-e/600):1;return{progress:Math.round(r*1000)/1000,stretch:Math.round(i*1000)/1000}}function Ar(e,t={}){let n="",r=()=>t.title?.offsetHeight||t.height||52;return _t((i)=>{let o=Bt(i,r()),a=`${o.progress}|${o.stretch}`;if(a===n)return;n=a,e.style.setProperty("--native-nav-progress",String(o.progress)),e.style.setProperty("--native-nav-stretch",String(o.stretch)),t.onChange?.(o)},t.host)}function kr(e){if(!e||typeof window>"u")return;let t=window.document?.querySelector(e);return t?t:void 0}function nt(){if(typeof window>"u")return;return window}var et="__stxPushed",Ft="__stxScroll";function Kt(e=nt()){let t=e?.history?.state;if(t===null||t===void 0)return!1;if(typeof t!=="object")return!0;let n=t;if(et in n)return n[et]===!0;return!(Ft in n)}function Tr(e=nt()){if(!Kt(e))return!1;return e.history.back(),!0}function Rr(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 Lr(e,t,n=12){let r=e?.title.trim()??"";return r&&r.length<=n?r:t}function Mr(){if(typeof window>"u")return[];let e=window;return e.__stacksNavTrail??=[]}function $t(e){try{let t=new URL(e,"http://local");return`${t.pathname}${t.search}`}catch{return e}}function Pr(){if(typeof window>"u")return;let e=window.stxRouter;if(typeof e?.screens!=="function")return;let t=e.screens(),n=t.find((i)=>i.active);if(!n)return;let r=t.filter((i)=>i.tab===n.tab&&i.depth<n.depth);if(!r.length)return null;return $t(r.reduce((i,o)=>o.depth>i.depth?o:i).url)}function Cr(e=typeof window>"u"?void 0:window){let t=e?.stxRouter;if(typeof t?.screens!=="function"||typeof e?.history?.go!=="function")return!1;let n=t.screens(),r=n.find((a)=>a.active);if(!r)return!1;let i=n.filter((a)=>a.tab===r.tab&&a.depth<r.depth);if(!i.length)return!1;let o=i.reduce((a,s)=>s.depth<a.depth?s:a);return e.history.go(o.depth-r.depth),!0}function Or(e,t){for(let n=e.length-1;n>=0;n--)if(e[n].path===t)return e[n];return null}function qt(e,t=Ut()){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 Ut(){if(typeof window>"u")return;return window.location?.origin}var tt="stacks-mobile-deep-link";function Nr(e,t){let n=(r)=>{let i=qt(r);if(i)e(i)};return t.getInitialURL().then((r)=>{if(!r)return;try{if(sessionStorage.getItem(tt)===r)return;sessionStorage.setItem(tt,r)}catch{}n(r)}).catch(()=>{}),t.onLink((r,i)=>{if(i?.initial)return;n(r)})}var Hr=5000;function Wt(e,t,n=5000){let r=t.filter((i)=>Number.isFinite(i.timestamp)&&Number.isFinite(i.bpm)&&i.bpm>0).slice().sort((i,o)=>i.timestamp-o.timestamp);if(!r.length)return e.slice();return e.map((i)=>{let o=0,a=r.length;while(o<a){let p=o+a>>1;if(r[p].timestamp<i.timestamp)o=p+1;else a=p}let s=r[o],l=r[o-1],g=!s?l:!l?s:i.timestamp-l.timestamp<=s.timestamp-i.timestamp?l:s;if(!g||Math.abs(g.timestamp-i.timestamp)>n)return i;return{...i,heartRate:Math.round(g.bpm)}})}var zt=6371008.8,Yt=30,jt=Yt;function Vt(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,i=(t.longitude-e.longitude)*n,o=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(i/2)**2;return 2*zt*Math.asin(Math.min(1,Math.sqrt(o)))}function Gt(e,t=25){let n=new Set;return e.filter((r)=>Number.isFinite(r.latitude)&&Number.isFinite(r.longitude)&&Number.isFinite(r.timestamp)&&Math.abs(r.latitude)<=90&&Math.abs(r.longitude)<=180&&Number.isFinite(r.accuracy)&&r.accuracy>=0&&r.accuracy<=t).sort((r,i)=>r.timestamp-i.timestamp).filter((r)=>{if(n.has(r.timestamp))return!1;return n.add(r.timestamp),!0})}function rt(e,t={}){let n=Gt(e,t.maxAccuracyM??25),r=t.paceWindowS??30,i=[],o=0,a=0,s=null;for(let u of n){let f=i[i.length-1],d=s?(u.timestamp-s.timestamp)/1000:0;if(s=u,!f){i.push({fix:u,cumM:0});continue}if(d>jt){i.push({fix:u,cumM:o});continue}let m=(u.timestamp-f.fix.timestamp)/1000,h=Vt(f.fix,u),k=Math.min(10,Math.max(3,f.fix.accuracy,u.accuracy));if(h<k)continue;if(o+=h,m>0&&h/m>=0.5)a+=m;i.push({fix:u,cumM:o})}let l=i[i.length-1],g=null,p=null;if(l&&n.at(-1).timestamp-l.fix.timestamp<=r*1000){let u=l.fix.timestamp-r*1000,f=i.find((h)=>h.fix.timestamp>=u)??l,d=l.cumM-f.cumM,m=(l.fix.timestamp-f.fix.timestamp)/1000;if(d>=20&&m>0)p=d/m,g=m/(d/1000)}return{distanceM:o,movingS:a,paceSPerKm:g,averagePaceSPerKm:o>=50&&a>0?a/(o/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 _r(e){if(e==null||e<=0||!Number.isFinite(e)||e>3600)return"–";let t=Math.round(e);return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function Dr(e){return e!=null&&e>0&&Number.isFinite(e)?(e*3.6).toFixed(1):"–"}var it={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function Br(e){let t=e.location,n=e.intervalMs??3000,r=it,i=null,o=e.heartRate,a=!1,s=[],l=()=>typeof document<"u"&&document.visibilityState==="hidden",g=0,p=null,u=Promise.resolve(),f=null,d=!1;function m(x){let b=u.then(x);return u=b.then(()=>{},()=>{}),b}function h(){if(p)return p;let x=g;return p=(async()=>{let b=await t.readRecording();if(x===g&&!d)r=rt(b,e),e.onUpdate?.(r);return r})().finally(()=>{p=null}),p}function k(){if(C(),d)return;i=setInterval(()=>{if(!l())h().catch(()=>{})},n)}function C(){if(i)clearInterval(i);i=null}async function F(x){if(!o||!a)return;await x(o).catch(()=>{})}return{get stats(){return r},get heartRate(){return s},start(){return f=null,m(async()=>{if(await t.startRecording({enableHighAccuracy:!0,...e.locationOptions}),s=[],a=!!o?.isAvailable(),await F((x)=>x.startRecording()),g++,r={...it},!d)e.onUpdate?.(r);return k(),r})},attach(){return m(async()=>{let x=await t.getRecordingState();if(!x?.active)return null;if(o?.isAvailable())a=!!(await o.getRecordingState().catch(()=>null))?.active;if(await h().catch(()=>{}),!x.paused)k();return x})},pause(){return m(async()=>{await t.pauseRecording(),await F((x)=>x.pauseRecording()),C(),await h().catch(()=>{})})},resume(){return m(async()=>{await t.resumeRecording(),await F((x)=>x.resumeRecording()),k()})},stop(){if(f)return f;return f=m(async()=>{C(),g++;let b=(await t.stopRecording())?.locations??[];if(o&&a){let y=await o.stopRecording().catch(()=>null);a=!1,s=y?.samples??[],b=Wt(b,s)}if(r=rt(b,e),!d)e.onUpdate?.(r);return b}).catch((x)=>{throw f=null,x}),f},dispose(){d=!0,g++,C()},refresh:h}}function Kr(e){return{startedAt:Number.isFinite(e)?e:null,pausedAt:null,pausedMs:0}}function $r(e,t){return e.startedAt===null||e.pausedAt!==null||!Number.isFinite(t)?e:{...e,pausedAt:Math.max(e.startedAt,t)}}function qr(e,t){return e.pausedAt===null||!Number.isFinite(t)?e:{...e,pausedAt:null,pausedMs:e.pausedMs+Math.max(0,t-e.pausedAt)}}function Ur(e,t){if(e.startedAt===null)return 0;let n=((e.pausedAt??t)-e.startedAt-e.pausedMs)/1000;return Number.isFinite(n)?Math.max(0,n):0}var zr=150;function Xt(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,i=(t.longitude-e.longitude)*n,o=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function Z(e,t){let n=[...e].sort((r,i)=>r-i);return n[Math.min(n.length-1,Math.floor(t*n.length))]}function Yr(e,t){let n=(e||[]).filter((a)=>Number.isFinite(a?.latitude)&&Number.isFinite(a?.longitude)&&Math.abs(a.latitude)<=90&&Math.abs(a.longitude)<=180),r=n.filter((a)=>a.accuracy!=null).map((a)=>Number(a.accuracy)).filter((a)=>Number.isFinite(a)&&a>=0),i=r.length?Z(r,0.5):Number.POSITIVE_INFINITY,o=0;if(n.length){let a={latitude:Z(n.map((s)=>s.latitude),0.5),longitude:Z(n.map((s)=>s.longitude),0.5)};o=Z(n.map((s)=>Xt(a,s)),0.8)}if(n.length>=10&&o>150&&i<=15)return"outside";if(t<150)return"unsure";if(n.length<3||i>30||o<25)return"indoors";if(o<50&&i>10)return"indoors";return"unsure"}function jr(e,t={}){let r=String(e||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d*)?|\.\d+)\s*(km|k|m|mi)?$/);if(!r)return null;let i=Number(r[1]),o=r[2]||t.defaultUnit||(i>100?"m":"km"),a=o==="m"?i/1000:o==="mi"?i*1.609344:i;return Number.isFinite(a)&&a>=0&&a<=2000?Math.round(a*1000)/1000:null}var ne=new Set,ot=!1,ee=null;function Jt(e){return e.isConnected&&e.getClientRects().length>0}function at(){return[...ne].find((e)=>Jt(e.element))}function te(){let e=at(),t=Boolean(e);if(t===ot)return;if(ot=t,t)I.enable(e?.tintColor?{tintColor:e.tintColor}:{});else I.disable()}function Qt(){let e=at();if(!e){I.end();return}Promise.resolve().then(()=>e.run()).catch(()=>{}).finally(()=>I.end())}function Xr(e,t){let n={element:e,tintColor:t.tintColor,run:t.onRefresh};ne.add(n);let r=e.ownerDocument?.defaultView;if(!ee){let i=I.onRefresh(Qt),o=()=>te();r?.addEventListener("stx:load",o),ee=()=>{i(),r?.removeEventListener("stx:load",o)}}return te(),r?.requestAnimationFrame?.(()=>te()),()=>{if(ne.delete(n),ne.size===0)ee?.(),ee=null;te()}}var Qr=0.5;function Zt(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((i,o)=>i.y-o.y)}function en(e){let{y:t,velocity:n,stops:r}=e,i=r.filter((s)=>s.name!=="dismiss"),o=r.find((s)=>s.name==="dismiss");if(i.length===0)return"dismiss";if(n>0.5)return(r.filter((l)=>l.y>t+1)[0]??o).name;if(n<-0.5){let s=i.filter((l)=>l.y<t-1);return(s[s.length-1]??i[0]).name}let a=i[i.length-1];if(t>a.y+(o.y-a.y)*0.5)return"dismiss";return i.reduce((s,l)=>Math.abs(l.y-t)<Math.abs(s.y-t)?l:s).name}function tn(e,t=400){if(e<=0)return 0;return e*t*0.55/(t+e*0.55)}function Zr(e){let{panel:t}=e,n=null,r=[],i=0,o=()=>e.viewport?.()??t.ownerDocument?.defaultView?.innerHeight??800,a=()=>Zt(t.offsetHeight||t.getBoundingClientRect().height,o(),e.detents()),s=(p)=>{let u=p;if(u.button!==void 0&&u.button!==0)return;if(u.target?.closest?.("button, a, input, select, textarea, [role=button]"))return;let f=a().find((d)=>d.name===e.detent())?.y??0;n={y:u.clientY,base:f,pointerId:u.pointerId},i=f,r=[{y:f,t:u.timeStamp}],t.classList.add("is-dragging");try{p.currentTarget?.setPointerCapture?.(u.pointerId)}catch{}},l=(p)=>{if(!n)return;let u=p,f=n.base+u.clientY-n.y;i=f<0?-tn(-f):f,r.push({y:i,t:u.timeStamp});while(r.length>2&&u.timeStamp-r[0].t>100)r.shift();t.style.transform=`translateY(${i}px)`;let d=t.offsetHeight||1;t.parentElement?.style.setProperty("--native-sheet-presence",String(Math.max(0,Math.min(1,1-i/d))))},g=(p)=>{if(!n)return;let u=p;n=null;let f=r[0],d=Math.max(1,u.timeStamp-f.t),m=(i-f.y)/d;t.classList.remove("is-dragging"),t.style.transform="",t.parentElement?.style.removeProperty("--native-sheet-presence"),e.onSettle(en({y:i,velocity:m,stops:a()}))};for(let p of e.handles)p.addEventListener("pointerdown",s),p.addEventListener("pointermove",l),p.addEventListener("pointerup",g),p.addEventListener("pointercancel",g);return()=>{for(let p of e.handles)p.removeEventListener("pointerdown",s),p.removeEventListener("pointermove",l),p.removeEventListener("pointerup",g),p.removeEventListener("pointercancel",g)}}var st=0,xe="";function ei(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;if(a.hasAttribute("data-native-sheet")&&a.getAttribute("aria-hidden")==="true")continue;a.setAttribute("inert",""),n.push(a)}r=r.parentElement}let i=t.documentElement;if(st++===0)xe=i.style.overflow||"",i.style.overflow="hidden";let o=!1;return()=>{if(o)return;o=!0;for(let a of n)a.removeAttribute("inert");if(--st===0)if(xe)i.style.overflow=xe;else i.style.removeProperty("overflow")}}function ti(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 ni(e,t){let n=e.documentElement;if(!t){n.removeAttribute("data-native-sheet-card");return}let r=e.defaultView,i=(r?.scrollY??0)+(r?.innerHeight??800)/2;n.style.setProperty("--native-sheet-card-origin",`${Math.round(i)}px`),n.setAttribute("data-native-sheet-card","")}function nn(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 rn(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 on(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&&!rn(r))return r}return null}function an(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 ai(e,t={}){let n=t.root??e.documentElement;U.setKeyboardAccessory(t.keyboardAccessory===!0);let r="",i="",o=()=>{let p=on(e);if(p&&p!==r)r=p,U.setUnderPageColor(p);let u=an(e)?"light":"dark";if(u!==i)i=u,Q.setStyle(u)},a=Qe((p)=>{nn(n,p),o()}),s=e.defaultView,l=typeof s?.MutationObserver==="function"?new s.MutationObserver(o):null;l?.observe(e.documentElement,{attributes:!0,attributeFilter:["class","style","data-theme"]});let g=s?.matchMedia?.("(prefers-color-scheme: dark)");return g?.addEventListener?.("change",o),s?.addEventListener("stx:load",o),o(),()=>{a(),l?.disconnect(),g?.removeEventListener?.("change",o),s?.removeEventListener("stx:load",o)}}var li=64;var sn=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,ln=/^(?:0|[1-9]\d*)$/;function ct(e){let t=[],n=[],r=e&&typeof e==="object"&&!Array.isArray(e)?e:{};for(let[i,o]of Object.entries(r)){let a=o&&typeof o==="object"?o:null;if(!a){n.push(`spotlight kind "${i}" is not an object`);continue}let{slots:s,route:l}=a,g=typeof a.noun==="string"&&a.noun.trim()?a.noun.trim():"Item";if(!sn.test(i)||i.includes("-slot-")){n.push(`spotlight kind "${i}" 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 "${i}" needs slots between 1 and 64, not ${String(s)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){n.push(`spotlight kind "${i}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}t.push({name:i,slots:s,route:l,noun:g})}return{kinds:t,problems:n}}function j(e,t){return e.find((n)=>n.name===t)??null}function Y(e,t,n){let r=j(e,t);if(!r||!Number.isInteger(n)||n<0||n>=r.slots)return null;return`${t}-slot-${n}`}function cn(e,t){if(typeof t!=="string")return null;let n=t.lastIndexOf("-slot-");if(n<=0)return null;let r=t.slice(0,n),i=t.slice(n+6);if(!ln.test(i))return null;let o=Number(i);return Y(e,r,o)===t?{kind:r,slot:o}:null}function ut(e){return e.flatMap((t)=>Array.from({length:t.slots},(n,r)=>`${t.name}-slot-${r}`))}function ci(e,t){let n=e&&typeof e==="object"?e:{};if(n.enabled===!1)return[];let i=[...(Array.isArray(n.activityTypes)?n.activityTypes.filter((o)=>typeof o==="string"&&o.trim().length>0):[]).map((o)=>o.trim()),...ut(ct(n.kinds).kinds)];return[...new Set(i)].map((o)=>`${t}.${o}`)}function dt(e,t,n){let r=typeof n.name==="string"?n.name.replace(/\s+/g," ").trim():"";if(!r)return`${j(e,t)?.noun??"Item"} #${n.id}`;return r.length>120?`${r.slice(0,119).trimEnd()}…`:r}function un(e,t,n,r,i=Date.now()){let o=j(e,n);if(!o||!Number.isInteger(r.id)||r.id<=0)return null;let a=t.filter((m)=>m.kind===n),s=dt(e,n,r),l=a.find((m)=>m.itemId===r.id)??null,g=l?null:mn(a,o.slots),p=l||g!==null?null:gn(a),u=l?.slot??g??p?.slot;if(u===void 0||u===null)return null;let f={kind:n,slot:u,itemId:r.id,title:s,donatedAt:i},d=t.filter((m)=>m.kind!==n||m.slot!==u&&m.itemId!==r.id);return{entries:pt(e,[...d,f]),entry:f,evicted:p,changed:!l||l.title!==s}}function dn(e,t,n){let r=e.find((i)=>i.kind===t&&i.itemId===n)??null;return{entries:r?e.filter((i)=>i!==r):[...e],removed:r}}function pn(e,t,n){let r=cn(e,n);if(!r)return null;let i=t.find((a)=>a.kind===r.kind&&a.slot===r.slot),o=j(e,r.kind)?.route;return i&&o?o.replace(":id",String(i.itemId)):null}function fn(e,t){if(!Array.isArray(t))return[];let n=new Map,r=new Set;for(let i of t){if(!i||typeof i!=="object")continue;let o=i,{kind:a,slot:s,itemId:l,title:g,donatedAt:p}=o;if(typeof a!=="string"||typeof s!=="number"||Y(e,a,s)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let u=`${a}-slot-${s}`,f=`${a}#${l}`;if(n.has(u)||r.has(f))continue;n.set(u,{kind:a,slot:s,itemId:l,title:typeof g==="string"&&g.trim()?g:dt(e,a,{id:l}),donatedAt:typeof p==="number"&&Number.isFinite(p)&&p>0?p:0}),r.add(f)}return pt(e,[...n.values()])}function pt(e,t){let n=new Map(e.map((r,i)=>[r.name,i]));return[...t].sort((r,i)=>(n.get(r.kind)??0)-(n.get(i.kind)??0)||r.slot-i.slot)}function mn(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 gn(e){return e.reduce((t,n)=>!t||n.donatedAt<t.donatedAt?n:t,null)}function hn(){let e=globalThis.craft;return e&&typeof e==="object"?e.siri:void 0}var bn="stacks_spotlight_index",vn=3000;function ui(e){let t=e.onProblem??((b)=>console.warn(`[spotlight] ${b}`)),n=Array.isArray(e.kinds)?{kinds:[...e.kinds],problems:[]}:ct(e.kinds);for(let b of n.problems)t(b);let r=e.enabled===!1?[]:n.kinds,i=e.storageKey??bn,o=e.legacyStorageKeys??[],a=e.timeoutMs??vn,s=e.now??(()=>Date.now()),l=e.bridge??hn,g=null;function p(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function u(){if(g)return g;g=[];let b=p();if(!b)return g;try{let y=[i,...o].map((w)=>b.getItem(w)).find((w)=>w);g=y?fn(r,JSON.parse(y)):[]}catch{g=[]}return g}function f(b){g=b;let y=p();if(!y)return;try{y.setItem(i,JSON.stringify(b));for(let w of o)y.removeItem(w)}catch{}}async function d(b){if(!b)return null;let y;try{return await Promise.race([b,new Promise((w)=>{y=setTimeout(()=>w(null),a)})])}catch{return null}finally{if(y!==void 0)clearTimeout(y)}}let m=Promise.resolve();function h(b){let y=m.then(b,b);return m=y.catch(()=>{return}),y}async function k(b,y){let w=l()?.register;if(!w||r.length===0)return!1;return h(async()=>{let T=un(r,u(),b,y,s()),H=T&&Y(r,b,T.entry.slot);if(!T||!H)return!1;if(!T.changed)return f(T.entries),!0;let K=await d(w(T.entry.title,H))!==null;if(K)f(T.entries);return K})}async function C(b,y){let w=l()?.remove;if(!w)return!1;return h(async()=>{let{entries:T,removed:H}=dn(u(),b,y);if(!H)return!1;let K=Y(r,b,H.slot),St=K?await d(w(K))!==null:!1;return f(T),St})}async function F(b,y){let w=j(r,b)?.slots;if(!w||!l()?.register)return 0;let T=0;for(let H of[...y].slice(0,w).reverse())if(await k(b,H))T++;return T}async function x(){let b=l()?.remove;if(!b)return f([]),0;return h(async()=>{let y=0;for(let w of u()){let T=Y(r,w.kind,w.slot);if(T&&await d(b(T))!==null)y++}return f([]),y})}return{kinds:r,index:k,sync:F,remove:C,clear:x,routeFor:(b)=>pn(r,u(),b),entries:()=>u(),activityTypes:(b)=>ut(r).map((y)=>`${b}.${y}`),reset:()=>{g=null}}}var lt=["craftShortcut","craftSiriShortcut"];function di(e,t){let n=(r)=>{let i=r.detail,o=typeof i==="string"?i:i&&typeof i==="object"?i.action??i.type:null,a=typeof o==="string"?e.routeFor(o):null;if(a)t(a)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let r of lt)globalThis.addEventListener(r,n);return()=>{for(let r of lt)globalThis.removeEventListener(r,n)}}import{tabBar as yn}from"craft-native/mobile";var Sn=yn;function xn(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 wn(e){return{tabs:e.map(({id:n,title:r,symbol:i,badge:o})=>o?{id:n,title:r,symbol:i,badge:o}:{id:n,title:r,symbol:i}),selected:e.find((n)=>n.current)?.id}}function mt(){if(typeof window>"u")return;let e=window.stxRouter;return e&&typeof e==="object"?e:void 0}function An(){return typeof mt()?.selectTab==="function"}function mi(e,t={}){let n=(r)=>{if(An()||r.defaultPrevented)return;let i=r.target?.closest?.("a[data-native-tab]");if(!i||!e.contains(i))return;if(!i.hasAttribute("data-stx-nav-current")&&!i.classList.contains("is-active")&&i.getAttribute("aria-current")!=="page")return;r.preventDefault();let o=e.ownerDocument.defaultView;if(t.scrollToTop)t.scrollToTop();else o?.scrollTo?.({top:0,behavior:o.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"});o?.dispatchEvent(new CustomEvent("stx:tabreselect",{detail:{href:i.getAttribute("href")||""}}))};return e.addEventListener("click",n),()=>e.removeEventListener("click",n)}function ft(e){let t=e.trim();return/^#[0-9a-f]{6}$/i.test(t)?t:void 0}var we="stacks:tab-bar-cover";function gi(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(we))}function hi(e,t={}){let n=t.api??Sn;if(!n.isAvailable())return null;let r=t.hidden??(()=>Boolean(e.ownerDocument?.querySelector("[data-native-hide-tab-bar], [data-native-covers-tab-bar]"))),i=typeof getComputedStyle==="function"?getComputedStyle(e):null,o=ft(i?.getPropertyValue("--native-tab-active")||""),a=ft(i?.getPropertyValue("--native-tab-active-dark")||""),s="",l=()=>{if(r()){if(s!=="hidden")n.hide();s="hidden";return}let{tabs:f,selected:d}=wn(xn(e)),m=JSON.stringify({tabs:f,selected:d});if(m===s)return;let h=s&&s!=="hidden"?JSON.parse(s):null;if(h&&d&&JSON.stringify(h.tabs)===JSON.stringify(f))n.select(d);else n.set(f,{selected:d,tint:o,tintDark:a});s=m},g=typeof MutationObserver==="function"?new MutationObserver(l):null;g?.observe(e,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let p=n.onSelect((f)=>{let d=mt();if(d?.selectTab){d.selectTab(f);return}Array.from(e.querySelectorAll("a[data-native-tab]")).find((h)=>h.getAttribute("href")===f)?.click()}),u=()=>l();if(typeof window<"u")window.addEventListener("stx:load",u),window.addEventListener("stx:screen-shown",u),window.addEventListener(we,u);return l(),()=>{if(g?.disconnect(),p(),typeof window<"u")window.removeEventListener("stx:load",u),window.removeEventListener("stx:screen-shown",u),window.removeEventListener(we,u);n.hide()}}var Rn={isAvailable:()=>c(()=>Ae.isAvailable()),getBiometricType:()=>c(()=>Ae.getBiometricType()),authenticate:(e)=>c(()=>Ae.authenticate(e))},Ln={takePicture:(e)=>c(()=>ie.takePicture(e)),pickImage:()=>c(()=>ie.pickImage()),pickMultiple:(e)=>c(()=>ie.pickMultiple(e)),isAvailable:()=>c(()=>ie.isAvailable())},Mn={getInfo:()=>c(()=>D.getInfo()),getCapabilities:()=>c(()=>D.getCapabilities()),isMobile:()=>D.isMobile(),isIOS:()=>D.isIOS(),isAndroid:()=>D.isAndroid(),getLocale:()=>D.getLocale(),getTimezone:()=>D.getTimezone()},Pn=En,Cn={getCurrentPosition:(e)=>c(()=>N.getCurrentPosition(e)),watchPosition:(e,t)=>N.watchPosition(e,t),clearWatch:(e)=>N.clearWatch(e),startRecording:(e)=>c(()=>N.startRecording(e)),pauseRecording:()=>c(()=>N.pauseRecording()),resumeRecording:()=>c(()=>N.resumeRecording()),stopRecording:()=>c(()=>N.stopRecording()),getRecordingState:()=>c(()=>N.getRecordingState()),readRecording:()=>c(()=>N.readRecording())},On={show:(e)=>c(()=>ae.show(e)),schedule:(e)=>c(()=>ae.schedule(e)),cancelAll:()=>c(()=>ae.cancelAll()),setBadge:(e)=>c(()=>ae.setBadge(e))},Nn={check:(e)=>c(()=>G.check(e)),request:(e)=>c(()=>G.request(e)),checkMultiple:(e)=>c(()=>G.checkMultiple(e)),requestMultiple:(e)=>c(()=>G.requestMultiple(e)),openSettings:()=>c(()=>G.openSettings())},In={set:(e,t)=>c(()=>se.set(e,t)),get:(e)=>c(()=>se.get(e)),delete:(e)=>c(()=>se.delete(e)),clear:()=>c(()=>se.clear())},Hn={share:(e)=>c(()=>vt.share(e)),isAvailable:()=>vt.isAvailable()},_n={request:()=>c(()=>kn.request())},ce={impact:(e)=>Promise.resolve().then(()=>oe.impact(e)).catch(()=>{}),notification:(e)=>Promise.resolve().then(()=>oe.notification(e)).catch(()=>{}),selection:()=>Promise.resolve().then(()=>oe.selection()).catch(()=>{}),vibrate:(e)=>Promise.resolve().then(()=>oe.vibrate(e)).catch(()=>{}),prepare:(e)=>{let t=L("haptics.prepare");return t?Promise.resolve().then(()=>t(e)).then(()=>{},()=>{}):Promise.resolve()}};function yt(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 Dn={async getInitialURL(){if(!await B())return null;return yt(await gt.getInitialURL?.())},onLink(e){let t=null,n=!1,r=()=>{if(n)return;t=gt.onLink?.((i,o)=>{let a=yt(i);if(a)e(a,{initial:o?.initial===!0})})??null};if(de()?.craft)r();else B().then(r);return()=>{n=!0,t?.()}}},xi={isAvailable:()=>le.isAvailable(),set:(e,t)=>le.set(e,t),remove:(e)=>le.remove(e),clear:()=>le.clear()},Bn={enable:()=>c(()=>ht.enable()),disable:()=>c(()=>ht.disable())},Fn={isAvailable:()=>re.isAvailable(),get:()=>c(()=>re.get()),set:(e)=>c(()=>re.set(e)),restore:()=>c(()=>re.restore())},Kn={isAvailable:()=>P.isAvailable(),supports:(e)=>P.supports(e),getAuthorizationStatus:()=>c(()=>P.getAuthorizationStatus()),requestAuthorization:()=>c(()=>P.requestAuthorization()),getNowPlaying:()=>c(()=>P.getNowPlaying()),play:()=>c(()=>P.play()),pause:()=>c(()=>P.pause()),togglePlayPause:()=>c(()=>P.togglePlayPause()),skipToNext:()=>c(()=>P.skipToNext()),skipToPrevious:(e)=>c(()=>P.skipToPrevious(e)),onChange:(e)=>_(()=>P.onChange(e))},$n={isAvailable:()=>A.isAvailable(),supports:(e)=>A.supports(e),getState:()=>c(()=>A.getState()),requestAuthorization:()=>c(()=>A.requestAuthorization()),scan:(e)=>c(()=>A.scan(e)),stopScan:()=>c(()=>A.stopScan()),getDevices:()=>c(()=>A.getDevices()),connect:(e)=>c(()=>A.connect(e)),reconnect:()=>c(()=>A.reconnect()),disconnect:(e)=>c(()=>A.disconnect(e)),startRecording:()=>c(()=>A.startRecording()),pauseRecording:()=>c(()=>A.pauseRecording()),resumeRecording:()=>c(()=>A.resumeRecording()),stopRecording:()=>c(()=>A.stopRecording()),getRecordingState:()=>c(()=>A.getRecordingState()),readRecording:(e)=>c(()=>A.readRecording(e)),onReading:(e)=>_(()=>A.onReading(e)),onDevice:(e)=>_(()=>A.onDevice(e)),onState:(e)=>_(()=>A.onState(e))},qn={isAvailable:()=>Te.isAvailable(),speak:(e,t)=>c(()=>Te.speak(e,t)),stop:()=>c(()=>Te.stop())},Un={getStatus:()=>c(()=>bt.getStatus()),onChange:(e)=>_(()=>bt.onChange(e))},Wn={register:()=>c(()=>Ee.register()),onToken:(e)=>Ee.onToken(e),onNotification:(e)=>_(()=>Ee.onNotification(e))},zn={requestAuthorization:(e,t)=>c(()=>V.requestAuthorization(e,t)),getData:(e,t)=>c(()=>V.getData(e,t)),saveWorkout:(e)=>c(()=>V.saveWorkout(e)),getWorkouts:(e)=>c(()=>V.getWorkouts(e)),getDailyStatistics:(e,t)=>c(()=>V.getDailyStatistics(e,t)),getHeartRateSamples:(e)=>v("health.getHeartRateSamples",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),getSleepIntervals:(e)=>v("health.getSleepIntervals",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),saveMindfulSession:(e)=>v("health.saveMindfulSession",[e],()=>null).then((t)=>t??null),getMindfulSessions:(e)=>v("health.getMindfulSessions",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),supports:(e)=>L(`health.${e}`)!==null},Yn={start:(e)=>c(()=>ke.start(e)),update:(e)=>c(()=>ke.update(e)),end:()=>c(()=>ke.end())},jn={send:(e)=>c(()=>X.send(e)),updateContext:(e)=>c(()=>X.updateContext(e)),isReachable:()=>c(()=>X.isReachable()),onMessage:(e)=>X.onMessage(e),onReachabilityChange:(e)=>X.onReachabilityChange(e)},wi=Tn;function de(){return S()}function ue(){let e=de()?.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 Re(){return ue()!==null}function Vn(e=2000){if(Re()||pe())return Promise.resolve(!0);let t=de();if(!t||!(t.craft||t.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(i),t.removeEventListener("craftReady",r),n(Re())},i=setTimeout(r,e);t.addEventListener("craftReady",r,{once:!0})})}function Gn(e){let t=de();if(!t)return()=>{};if(ue()){let r=!1;return queueMicrotask(()=>{if(!r)e(new Event("craftReady"))}),()=>{r=!0}}let n=(r)=>{if(!ue())return;t.removeEventListener("craftReady",n),e(r)};return t.addEventListener("craftReady",n),()=>t.removeEventListener("craftReady",n)}async function Xn(e){await ce.impact("light");try{let t=await e();return await ce.notification("success"),t}catch(t){throw await ce.notification("error"),t}}var Ai={get nativeBridge(){return ue()},biometrics:Rn,camera:Ln,device:Mn,haptics:ce,lifecycle:Pn,location:Cn,notifications:On,permissions:Nn,secureStorage:In,share:Hn,appReview:_n,deepLinks:Dn,keepAwake:Bn,brightness:Fn,music:Kn,heartRate:$n,speech:qn,network:Un,pushNotifications:Wn,health:zn,liveActivities:Yn,watchConnectivity:jn,dialog:q,contextMenu:ve,browser:Ke,symbols:$e,statusBar:Q,chrome:U,refresh:I,background:W,clipboard:qe,db:Ue,files:We,shortcuts:ze,widgets:Ye,orientation:je,auth:Ve,storeKit:Ge,isNativeMobile:Re,whenNative:Vn,onReady:Gn,withFeedback:Xn};export{Jn as BRIDGE_WAIT_MS,Hr as HEART_RATE_MATCH_MS,zr as INDOOR_CHECK_AFTER_S,li as MAX_SPOTLIGHT_SLOTS_PER_KIND,Yt as ROUTE_GAP_S,Qr as SHEET_FLICK_VELOCITY,we as TAB_BAR_COVER_EVENT,c as afterBridge,_n as appReview,nn as applyAppearance,Wt as attachHeartRate,Ve as auth,Lr as backLabelFor,W as background,Rn as biometrics,J as bridgePending,Fn as brightness,Ke as browser,v as callNative,Ln as camera,Kt as canGoBack,U as chrome,qe as clipboard,ir as confirmAction,ve as contextMenu,gi as coverTabBar,S as craftHost,xt as craftRoot,Br as createRouteRecorder,ui as createSpotlightIndex,Je as currentAppearance,Ue as db,qt as deepLinkPath,Dn as deepLinks,Mn as device,q as dialog,Rr as enterNavTrail,We as files,Vt as fixDistance,dr as focusSegment,Nr as followDeepLinks,ue as getNativeMobileBridge,Tr as goBack,Cr as goBackToTabRoot,mi as handleTabReselect,ce as haptics,pe as hasNativeMobileHost,zn as health,$n as heartRate,Yr as indoorVerdict,ai as installNativeChrome,pr as installPressables,Re as isNativeMobile,Jt as isShown,Bn as keepAwake,Bt as largeTitleMetrics,Pn as lifecycle,ti as liftToBody,Yn as liveActivities,Cn as location,ei as lockBackground,hi as mirrorTabBar,Ai as mobile,Kn as music,kt as nativeFunction,L as nativeFunctionNow,wn as nativeTabs,Mr as navTrail,Un as network,It as normalizeAppearance,yt as normalizeDeepLinkURL,On as notifications,Ar as observeLargeTitle,lr as observeLongPress,Xr as observeNativeRefresh,_t as observePageScroll,wr as observePullToRefresh,cr as observeSegmentScrub,Zr as observeSheetDrag,Qe as onAppearance,yr as onBackgroundRefresh,O as onCraftEvent,br as onMemoryWarning,Gn as onMobileReady,hr as onResume,vr as onSilentPush,di as onSpotlightTap,je as orientation,_r as paceLabel,on as pageBackground,an as pageIsDark,z as pageScrollTop,$r as pauseSessionClock,Nn as permissions,Mt as placeMenu,un as placeSpotlightItem,Ie as presentActionSheet,Oe as presentAlert,fe as presentChoice,Ne as presentConfirm,He as presentContextMenu,ni as presentPageAsCard,Pr as previousScreenPath,Dt as pullDistance,Wn as pushNotifications,fn as readSpotlightEntries,ct as readSpotlightKinds,xn as readTabLinks,I as refresh,dn as removeSpotlightItem,kr as resolveScrollHost,qr as resumeSessionClock,rt as routeStats,An as routerHandlesTabs,tn as rubberBand,In as secureStorage,Nt as segmentAt,ur as segmentForKey,Ur as sessionClockElapsed,en as settleSheet,Hn as share,Zt as sheetStops,ze as shortcuts,or as showContextMenuFor,xi as snapshots,qn as speech,Dr as speedLabel,wi as splash,Y as spotlightAction,ut as spotlightActions,ci as spotlightActivityTypes,hn as spotlightBridge,j as spotlightKind,pn as spotlightRoute,cn as spotlightSlot,dt as spotlightTitle,Kr as startSessionClock,Q as statusBar,Ge as storeKit,_ as subscribeWhenReady,$e as symbols,Sn as tabBar,be as toNativeRect,Or as trailEntryFor,Lt as trapFocus,jr as typedDistanceKm,Gt as usableFixes,rr as useActionSheet,jn as watchConnectivity,B as whenBridgeReady,Vn as whenNativeMobile,Ye as widgets,Xn as withNativeFeedback};
55
+ `;function Oe(){return S()?.document}function Pt(e){if(e.getElementById(Ce))return;let t=e.createElement("style");t.id=Ce,t.textContent=Mt,(e.head??e.documentElement).appendChild(t)}var Ct=0;function E(e,t,n,r){let o=e.createElement(t);if(o.className=n,r!==void 0)o.textContent=r;return o}var Ne='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ot(e,t){if(t.key!=="Tab")return;let n=Array.from(e.querySelectorAll(Ne));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 Ie(e,t,n,r){Pt(e);let o=S(),i=e.activeElement,a=E(e,"div",`native-dialog native-dialog--${t}`);return a.setAttribute("data-native-dialog",t),a.appendChild(E(e,"div","native-dialog-backdrop")),new Promise((s)=>{let l=!1,g=(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(),g(r());return}Ot(u,h)},u=n({root:a,settle:g});a.appendChild(u),e.body.appendChild(a),e.addEventListener("keydown",p,!0);let f=o;(typeof f?.requestAnimationFrame==="function"?(h)=>f.requestAnimationFrame(()=>f.requestAnimationFrame(h)):(h)=>setTimeout(h,16))(()=>{if(!l)a.classList.add("is-open")}),(u.querySelector("[data-native-autofocus]")??u.querySelector(Ne))?.focus()})}function he(e){let t=Oe();if(!t?.body)return Promise.resolve(null);let n=`native-dialog-${++Ct}`,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 Ie(t,e.variant,({root:a,settle:s})=>{let l=(d)=>d.style==="cancel"?null:d.id,g=E(t,"div","native-dialog-panel");g.setAttribute("role","alertdialog"),g.setAttribute("aria-modal","true"),g.tabIndex=-1;let p=E(t,"div","native-dialog-group");if(e.title||e.message){let d=E(t,"div","native-dialog-header");if(e.title){let m=E(t,"p","native-dialog-title",e.title);m.id=`${n}-title`,d.appendChild(m),g.setAttribute("aria-labelledby",m.id)}if(e.message){let m=E(t,"p","native-dialog-message",e.message);m.id=`${n}-message`,d.appendChild(m),g.setAttribute("aria-describedby",m.id)}p.appendChild(d)}let u=E(t,"div","native-dialog-actions");if(e.variant==="alert"&&o.length===2)u.classList.add("is-row");for(let d of o){let m=E(t,"button",`native-dialog-action${d.style==="destructive"?" is-destructive":""}${d.style==="cancel"?" is-cancel":""}`,d.title);m.type="button",m.setAttribute("data-action-id",d.id),m.addEventListener("click",()=>s(l(d))),u.appendChild(m)}if(p.appendChild(u),g.appendChild(p),i){let d=E(t,"div","native-dialog-group"),m=E(t,"button","native-dialog-action is-cancel",i.title);m.type="button",m.setAttribute("data-action-id",i.id),m.addEventListener("click",()=>s(null)),d.appendChild(m),g.appendChild(d)}let f=a.querySelector(".native-dialog-backdrop");if(e.variant==="sheet")f?.addEventListener("click",()=>s(null));return g},()=>{if(e.variant==="sheet")return null;if(r)return null;return o.length===1?o[0].id:null})}async function He(e){await he({variant:"alert",title:e.title,message:e.message,actions:[{id:"ok",title:e.okLabel||"OK"}]})}async function De(e){return await he({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 _e(e){return he({variant:"sheet",title:e.title,message:e.message,actions:e.actions,cancelLabel:e.cancelLabel})}function Nt(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,g=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:g,left:i,origin:`${s||l<12?"top":"bottom"} ${p}`}}function Be(e){let t=Oe();if(!t?.body)return Promise.resolve(null);let n=S();return Ie(t,"menu",({root:r,settle:o})=>{let i=E(t,"div","native-menu native-dialog-panel");if(i.setAttribute("role","menu"),e.title)i.appendChild(E(t,"p","native-menu-title",e.title)),i.setAttribute("aria-label",e.title);for(let a of e.items){let s=E(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(E(t,"span","native-menu-label",a.title)),a.icon){let l=E(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=Nt(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 $e=()=>!0,T=()=>!1,M=()=>null;function Fe(){return S()?.navigator??(typeof navigator>"u"?void 0:navigator)}function Se(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 z={alert:(e)=>v("dialog.alert",[e],()=>He(e),{fallbackOnError:!0}).then(()=>{}),confirm:(e)=>v("dialog.confirm",[e],()=>De(e),{fallbackOnError:!0}).then(Boolean),actionSheet:async(e)=>{let t={...e,anchor:e.anchor?Se(e.anchor):void 0},n=await v("dialog.actionSheet",[t],()=>_e(e),{fallbackOnError:!0});if(typeof n!=="string")return null;return e.actions.find((r)=>r.id===n)?.style==="cancel"?null:n}};function ur(){return(e)=>z.actionSheet(e)}async function dr(e){if((e.style??(e.destructive?"sheet":"alert"))==="alert")return z.confirm(e);return await z.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 xe={show:async(e)=>{let t={title:e.title,anchor:Se(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 v("contextMenu.show",[t],()=>Be(e),{fallbackOnError:!0});return typeof n==="string"?n:null}};function pr(e,t){return xe.show({...t,anchor:Se(e.getBoundingClientRect())})}function It(e,t){let n=S();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 ze={open:async(e,t={})=>{let n=await v("browser.open",[e,t],()=>It(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)}}},be=new Map,ve=new Map;function We(e,t){return`${e}|${t.pointSize??""}|${t.weight??""}|${t.color??""}|${t.scale??""}`}var qe={isAvailable:()=>L("symbols.image")!==null,image:(e,t={})=>{let n=We(e,t),r=be.get(n);if(r)return r;let o=v("symbols.image",[e,t],M).then((i)=>typeof i==="string"&&i.startsWith("data:")?i:null,M).then((i)=>(ve.set(n,i),i));return be.set(n,o),o},cached:(e,t={})=>ve.get(We(e,t)),clearCache:()=>{be.clear(),ve.clear()}},Z={setStyle:(e)=>v("statusBar.setStyle",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1)},q={setUnderPageColor:(e)=>v("chrome.setUnderPageColor",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1),setKeyboardAccessory:(e)=>v("chrome.setKeyboardAccessory",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1)},I={isAvailable:()=>L("refresh.enable")!==null,enable:(e)=>v("refresh.enable",[e??{}],T,{fallbackOnError:!0}).then((t)=>t!==!1),disable:()=>v("refresh.disable",[],T,{fallbackOnError:!0}).then((e)=>e!==!1),end:()=>v("refresh.end",[],T,{fallbackOnError:!0}).then((e)=>e!==!1),onRefresh:(e)=>O("craftRefresh",()=>e())},U={complete:(e)=>v("background.complete",[e],T,{fallbackOnError:!0}).then((t)=>t!==!1)},Ue={write:(e)=>v("clipboard.write",[e],async()=>{let t=Fe()?.clipboard;if(!t?.writeText)return!1;return t.writeText(e).then($e,T)},{fallbackOnError:!0}).then((t)=>t!==!1),read:()=>v("clipboard.read",[],async()=>{let e=Fe()?.clipboard;if(!e?.readText)return null;return e.readText().catch(M)},{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null)},je={isAvailable:()=>L("db.query")!==null,query:(e,t=[])=>v("db.query",[e,t],M).then((n)=>Array.isArray(n)?n:null),execute:(e,t=[])=>v("db.execute",[e,t],M).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 ye(e,t){let n=S()?.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 Ht(e){let t=S()?.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 Ye={openPDF:(e,t=0)=>v("openPDF",[e,t],()=>{let n=S();return Boolean(n?.open?.(e,"_blank","noopener"))}).then((n)=>n!==!1),takeScreenshot:()=>v("takeScreenshot",[],M,{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null),scanQRCode:()=>v("scanQRCode",[],M).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},M),pickFile:(e=[])=>v("pickFile",[e],()=>Ht(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}},M),saveFile:(e,t,n)=>v("saveFile",[e,t,n],()=>{if(e.startsWith("data:"))return ye(e,t);let r=new Blob([e],{type:n||"text/plain"}),o=URL.createObjectURL(r),i=ye(o,t);return setTimeout(()=>URL.revokeObjectURL(o),1000),i}).then((r)=>typeof r==="string"?r:null),downloadFile:(e,t)=>v("downloadFile",[e,t],()=>ye(e,t)).then((n)=>typeof n==="string"?n:null)},Ge={set:(e)=>v("shortcuts.set",[e.map(({symbol:t,...n})=>t?{...n,iconName:t}:n)],T).then((t)=>t!==!1),clear:()=>v("shortcuts.clear",[],T).then((e)=>e!==!1),onShortcut:(e)=>O("craftShortcut",(t)=>{if(typeof t.type==="string")e(t.type)})},Ve={update:(e)=>v("widget.update",[e],T).then((t)=>t!==!1),reload:()=>v("widget.reload",[],T).then((e)=>e!==!1)},Dt={portrait:"portrait-primary",portraitUpsideDown:"portrait-secondary",landscape:"landscape",landscapeLeft:"landscape-primary",landscapeRight:"landscape-secondary"};function Ke(){return S()?.screen?.orientation}var Xe={lock:(e)=>v("lockOrientation",[e],()=>{let t=Ke();return t?.lock?t.lock(Dt[e]).then($e,T):!1}).then((t)=>t!==!1),unlock:()=>v("unlockOrientation",[],()=>(Ke()?.unlock?.(),!0)).then((e)=>e!==!1)},Je={signInWithApple:(e={})=>v("signInWithApple",e.nonce?[{nonce:e.nonce}]:[],M).then((t)=>{if(!t||typeof t!=="object"||typeof t.userId!=="string")return null;return t})},Qe={isAvailable:()=>L("iap.purchase")!==null,products:(e)=>v("iap.getProducts",[e],()=>[]).then((t)=>Array.isArray(t)?t:[]),purchase:(e)=>v("iap.purchase",[e],M).then((t)=>t&&typeof t==="object"?t:null,(t)=>{if(/cancel/i.test(String(t?.message??t)))return null;throw t}),restore:()=>v("iap.restore",[],()=>[]).then((e)=>Array.isArray(e)?e:[])};var _t=["authorized","denied","notDetermined","restricted","unsupported"];function ee(){let e=me(),t=e?.scheduledWorkouts;if(!t||typeof t!=="object"||e?.capabilities?.scheduledWorkouts!==!0)return;return t}function Bt(){return Object.assign(Error("unsupported"),{code:"UNSUPPORTED"})}function Ze(e){return _t.includes(e)?e:"unsupported"}function Ft(e){if(!e||typeof e!=="object")return null;let t=e;if(typeof t.id!=="string"||!t.id||typeof t.date!=="string"||!/^\d{4}-\d{2}-\d{2}$/.test(t.date))return null;let n={id:t.id.toLowerCase(),date:t.date,complete:t.complete===!0};if(typeof t.hour==="number"&&Number.isFinite(t.hour))n.hour=t.hour;if(typeof t.minute==="number"&&Number.isFinite(t.minute))n.minute=t.minute;return n}function F(e,t,...n){return c(async()=>{let r=ee();if(typeof r?.[e]!=="function")throw Bt();return t(await r[e](...n))})}var et={isAvailable:()=>typeof ee()?.isSupported==="function",supports:(e)=>typeof ee()?.[e]==="function",isSupported:()=>c(async()=>{let e=ee();if(typeof e?.isSupported!=="function")return!1;try{return await e.isSupported()===!0}catch{return!1}}),authorization:()=>F("authorization",Ze),requestAuthorization:()=>F("requestAuthorization",Ze),list:()=>F("list",(e)=>Array.isArray(e)?e.map(Ft).filter((t)=>t!==null):[]),schedule:(e)=>{if(!e||typeof e!=="object"||typeof e.id!=="string")return Promise.reject(Object.assign(Error("schedule needs a plan with an id"),{code:"INVALID_ARGUMENT"}));return F("schedule",(t)=>{let n=t&&typeof t==="object"?t:{},r={id:(typeof n.id==="string"?n.id:e.id).toLowerCase()};if(Array.isArray(n.droppedAlerts)&&n.droppedAlerts.length)r.droppedAlerts=n.droppedAlerts.filter((o)=>typeof o==="string");return r},e)},remove:(e)=>F("remove",(t)=>t===!0,e),removeAll:()=>F("removeAll",(e)=>typeof e==="number"&&Number.isFinite(e)?e:0)};function br(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=(f)=>{let d=f;if(d.button!==void 0&&d.button!==0)return;a=!1,i={x:d.clientX,y:d.clientY},t.onPressStart?.(),o=setTimeout(()=>{if(o=null,!i)return;a=!0,t.onLongPress({...i}),i=null},n)},g=(f)=>{if(!i)return;let d=f;if(Math.hypot(d.clientX-i.x,d.clientY-i.y)>r)s()},p=(f)=>{if(!a)return;a=!1,f.preventDefault(),f.stopPropagation()},u=(f)=>f.preventDefault();return e.addEventListener("pointerdown",l),e.addEventListener("pointermove",g),e.addEventListener("pointerup",s),e.addEventListener("pointercancel",s),e.addEventListener("pointerleave",s),e.addEventListener("click",p,!0),e.addEventListener("contextmenu",u),()=>{s(),e.removeEventListener("pointerdown",l),e.removeEventListener("pointermove",g),e.removeEventListener("pointerup",s),e.removeEventListener("pointercancel",s),e.removeEventListener("pointerleave",s),e.removeEventListener("click",p,!0),e.removeEventListener("contextmenu",u)}}function Wt(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 vr(e,t){let n=null,r=null,o=!1,i=0,a=(d)=>{let m=e.getBoundingClientRect();return Wt(d,{left:m.left+2,width:m.width-4},t.count())},s=(d)=>{let m=d;if(m.button!==void 0&&m.button!==0)return;let h=a(m.clientX);if(h!==t.selected())return;n=h,i=h,o=!1,r=m.pointerId;try{e.setPointerCapture?.(m.pointerId)}catch{}t.onPress?.(!0)},l=(d)=>{if(n===null)return;let m=a(d.clientX);if(m===i)return;o=!0,i=m,t.onScrub(m)},g=(d)=>{if(n===null)return;if(r!==null)try{e.releasePointerCapture?.(r)}catch{}if(t.onPress?.(!1),d&&o)t.onCommit(i);else if(o)t.onScrub(n);n=null,r=null},p=(d)=>{if(!o)return;o=!1,d.preventDefault(),d.stopPropagation()},u=()=>g(!0),f=()=>g(!1);return e.addEventListener("pointerdown",s),e.addEventListener("pointermove",l),e.addEventListener("pointerup",u),e.addEventListener("pointercancel",f),e.addEventListener("click",p,!0),()=>{e.removeEventListener("pointerdown",s),e.removeEventListener("pointermove",l),e.removeEventListener("pointerup",u),e.removeEventListener("pointercancel",f),e.removeEventListener("click",p,!0)}}function yr(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 Sr(e,t){e.querySelectorAll('[role="tab"]')[t]?.focus()}function xr(e){let t=(n)=>{if(!n.target?.closest?.("[data-native-pressable]"))return;let o=L("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 Ae(e){let t=S();try{return Boolean(t?.matchMedia?.(e).matches)}catch{return!1}}function tt(e){return e!==null&&e!==void 0&&e!=="false"&&e!=="0"}function nt(){let e=S()?.document?.documentElement,t=Number.parseFloat(e?.style?.getPropertyValue("--craft-font-scale")||"");return{fontScale:Number.isFinite(t)&&t>0?t:1,reduceMotion:tt(e?.getAttribute("data-craft-reduce-motion"))||Ae("(prefers-reduced-motion: reduce)"),reduceTransparency:tt(e?.getAttribute("data-craft-reduce-transparency"))||Ae("(prefers-reduced-transparency: reduce)"),colorScheme:e?.classList?.contains("dark")||Ae("(prefers-color-scheme: dark)")?"dark":"light"}}function Kt(e){let t=nt(),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 rt(e,t={}){if(t.immediate!==!1)e(nt());return O("craftAppearance",(n)=>e(Kt(n)))}function Er(e){return O("craftResume",(t)=>e({backgroundedMs:Number(t.backgroundedMs)||0}))}function Rr(e){return O("craftMemoryWarning",()=>e())}function ot(e){return(t)=>{Promise.resolve().then(()=>e(t)).then(()=>U.complete(!0),()=>U.complete(!1))}}function Tr(e){let t=ot(e);return O("craftSilentPush",(n)=>t(n.payload??{}))}function Lr(e){let t=ot(()=>e());return O("craftBackgroundRefresh",()=>t(void 0))}import{haptics as $t}from"craft-native/mobile";function we(){if(typeof window>"u")return;return window}function j(e=we()){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 zt(e,t=we()){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(j(t))})};return e(j(t)),t.addEventListener("scroll",o,{passive:!0}),()=>t.removeEventListener("scroll",o)}function qt(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 Cr(e){let t=e.host??we();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,-j(t)))})},g=(h)=>{let k=s!==null;if(s=h,k)return;a(()=>{if(s!==null)l(s)})},p=(h)=>{let k=h.touches?.[0];return k?k.clientY:null},u=(h)=>{if(i||j(t)>0)return;r=p(h),o=!1},f=(h)=>{if(r===null)return;let k=p(h);if(k===null)return;let C=qt(j(t),k-r);if(!o&&C>=n)o=!0,Promise.resolve($t.impact("medium")).catch(()=>{});else if(o&&C<n*0.8)o=!1;g(C)},d=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)}},m=()=>{if(r===null)return;r=null,o=!1,l(0)};return t.addEventListener("touchstart",u,{passive:!0}),t.addEventListener("touchmove",f,{passive:!0}),t.addEventListener("touchend",d),t.addEventListener("touchcancel",m),()=>{s=null,t.removeEventListener("touchstart",u),t.removeEventListener("touchmove",f),t.removeEventListener("touchend",d),t.removeEventListener("touchcancel",m)}}function Ut(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 Or(e,t={}){let n="",r=()=>t.title?.offsetHeight||t.height||52;return zt((o)=>{let i=Ut(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 Nr(e){if(!e||typeof window>"u")return;let t=window.document?.querySelector(e);return t?t:void 0}function st(){if(typeof window>"u")return;return window}var it="__stxPushed",jt="__stxScroll";function Yt(e=st()){let t=e?.history?.state;if(t===null||t===void 0)return!1;if(typeof t!=="object")return!0;let n=t;if(it in n)return n[it]===!0;return!(jt in n)}function Hr(e=st()){if(!Yt(e))return!1;return e.history.back(),!0}function Dr(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 _r(e,t,n=12){let r=e?.title.trim()??"";return r&&r.length<=n?r:t}function Br(){if(typeof window>"u")return[];let e=window;return e.__stacksNavTrail??=[]}function Gt(e){try{let t=new URL(e,"http://local");return`${t.pathname}${t.search}`}catch{return e}}function Fr(){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 Gt(r.reduce((o,i)=>i.depth>o.depth?i:o).url)}function Wr(e=typeof window>"u"?void 0:window){let t=e?.stxRouter;if(typeof t?.screens!=="function"||typeof e?.history?.go!=="function")return!1;let n=t.screens(),r=n.find((a)=>a.active);if(!r)return!1;let o=n.filter((a)=>a.tab===r.tab&&a.depth<r.depth);if(!o.length)return!1;let i=o.reduce((a,s)=>s.depth<a.depth?s:a);return e.history.go(i.depth-r.depth),!0}function Kr(e,t){for(let n=e.length-1;n>=0;n--)if(e[n].path===t)return e[n];return null}function Vt(e,t=Xt()){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 Xt(){if(typeof window>"u")return;return window.location?.origin}var at="stacks-mobile-deep-link";function $r(e,t){let n=(r)=>{let o=Vt(r);if(o)e(o)};return t.getInitialURL().then((r)=>{if(!r)return;try{if(sessionStorage.getItem(at)===r)return;sessionStorage.setItem(at,r)}catch{}n(r)}).catch(()=>{}),t.onLink((r,o)=>{if(o?.initial)return;n(r)})}var qr=5000;function Jt(e,t,n=5000){let r=t.filter((o)=>Number.isFinite(o.timestamp)&&Number.isFinite(o.bpm)&&o.bpm>0).slice().sort((o,i)=>o.timestamp-i.timestamp);if(!r.length)return e.slice();return e.map((o)=>{let i=0,a=r.length;while(i<a){let p=i+a>>1;if(r[p].timestamp<o.timestamp)i=p+1;else a=p}let s=r[i],l=r[i-1],g=!s?l:!l?s:o.timestamp-l.timestamp<=s.timestamp-o.timestamp?l:s;if(!g||Math.abs(g.timestamp-o.timestamp)>n)return o;return{...o,heartRate:Math.round(g.bpm)}})}var Qt=6371008.8,Zt=30,en=Zt;function tn(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 2*Qt*Math.asin(Math.min(1,Math.sqrt(i)))}function nn(e,t=25){let n=new Set;return e.filter((r)=>Number.isFinite(r.latitude)&&Number.isFinite(r.longitude)&&Number.isFinite(r.timestamp)&&Math.abs(r.latitude)<=90&&Math.abs(r.longitude)<=180&&Number.isFinite(r.accuracy)&&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 lt(e,t={}){let n=nn(e,t.maxAccuracyM??25),r=t.paceWindowS??30,o=[],i=0,a=0,s=null;for(let u of n){let f=o[o.length-1],d=s?(u.timestamp-s.timestamp)/1000:0;if(s=u,!f){o.push({fix:u,cumM:0});continue}if(d>en){o.push({fix:u,cumM:i});continue}let m=(u.timestamp-f.fix.timestamp)/1000,h=tn(f.fix,u),k=Math.min(10,Math.max(3,f.fix.accuracy,u.accuracy));if(h<k)continue;if(i+=h,m>0&&h/m>=0.5)a+=m;o.push({fix:u,cumM:i})}let l=o[o.length-1],g=null,p=null;if(l&&n.at(-1).timestamp-l.fix.timestamp<=r*1000){let u=l.fix.timestamp-r*1000,f=o.find((h)=>h.fix.timestamp>=u)??l,d=l.cumM-f.cumM,m=(l.fix.timestamp-f.fix.timestamp)/1000;if(d>=20&&m>0)p=d/m,g=m/(d/1000)}return{distanceM:i,movingS:a,paceSPerKm:g,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 Ur(e){if(e==null||e<=0||!Number.isFinite(e)||e>3600)return"–";let t=Math.round(e);return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function jr(e){return e!=null&&e>0&&Number.isFinite(e)?(e*3.6).toFixed(1):"–"}var ct={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function Yr(e){let t=e.location,n=e.intervalMs??3000,r=ct,o=null,i=e.heartRate,a=!1,s=[],l=()=>typeof document<"u"&&document.visibilityState==="hidden",g=0,p=null,u=Promise.resolve(),f=null,d=!1;function m(x){let b=u.then(x);return u=b.then(()=>{},()=>{}),b}function h(){if(p)return p;let x=g;return p=(async()=>{let b=await t.readRecording();if(x===g&&!d)r=lt(b,e),e.onUpdate?.(r);return r})().finally(()=>{p=null}),p}function k(){if(C(),d)return;o=setInterval(()=>{if(!l())h().catch(()=>{})},n)}function C(){if(o)clearInterval(o);o=null}async function W(x){if(!i||!a)return;await x(i).catch(()=>{})}return{get stats(){return r},get heartRate(){return s},start(){return f=null,m(async()=>{if(await t.startRecording({enableHighAccuracy:!0,...e.locationOptions}),s=[],a=!!i?.isAvailable(),await W((x)=>x.startRecording()),g++,r={...ct},!d)e.onUpdate?.(r);return k(),r})},attach(){return m(async()=>{let x=await t.getRecordingState();if(!x?.active)return null;if(i?.isAvailable())a=!!(await i.getRecordingState().catch(()=>null))?.active;if(await h().catch(()=>{}),!x.paused)k();return x})},pause(){return m(async()=>{await t.pauseRecording(),await W((x)=>x.pauseRecording()),C(),await h().catch(()=>{})})},resume(){return m(async()=>{await t.resumeRecording(),await W((x)=>x.resumeRecording()),k()})},stop(){if(f)return f;return f=m(async()=>{C(),g++;let b=(await t.stopRecording())?.locations??[];if(i&&a){let y=await i.stopRecording().catch(()=>null);a=!1,s=y?.samples??[],b=Jt(b,s)}if(r=lt(b,e),!d)e.onUpdate?.(r);return b}).catch((x)=>{throw f=null,x}),f},dispose(){d=!0,g++,C()},refresh:h}}function Vr(e){return{startedAt:Number.isFinite(e)?e:null,pausedAt:null,pausedMs:0}}function Xr(e,t){return e.startedAt===null||e.pausedAt!==null||!Number.isFinite(t)?e:{...e,pausedAt:Math.max(e.startedAt,t)}}function Jr(e,t){return e.pausedAt===null||!Number.isFinite(t)?e:{...e,pausedAt:null,pausedMs:e.pausedMs+Math.max(0,t-e.pausedAt)}}function Qr(e,t){if(e.startedAt===null)return 0;let n=((e.pausedAt??t)-e.startedAt-e.pausedMs)/1000;return Number.isFinite(n)?Math.max(0,n):0}var eo=150;function rn(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 te(e,t){let n=[...e].sort((r,o)=>r-o);return n[Math.min(n.length-1,Math.floor(t*n.length))]}function to(e,t){let n=(e||[]).filter((a)=>Number.isFinite(a?.latitude)&&Number.isFinite(a?.longitude)&&Math.abs(a.latitude)<=90&&Math.abs(a.longitude)<=180),r=n.filter((a)=>a.accuracy!=null).map((a)=>Number(a.accuracy)).filter((a)=>Number.isFinite(a)&&a>=0),o=r.length?te(r,0.5):Number.POSITIVE_INFINITY,i=0;if(n.length){let a={latitude:te(n.map((s)=>s.latitude),0.5),longitude:te(n.map((s)=>s.longitude),0.5)};i=te(n.map((s)=>rn(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 no(e,t={}){let r=String(e||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d*)?|\.\d+)\s*(km|k|m|mi)?$/);if(!r)return null;let o=Number(r[1]),i=r[2]||t.defaultUnit||(o>100?"m":"km"),a=i==="m"?o/1000:i==="mi"?o*1.609344:o;return Number.isFinite(a)&&a>=0&&a<=2000?Math.round(a*1000)/1000:null}var oe=new Set,ut=!1,ne=null;function on(e){return e.isConnected&&e.getClientRects().length>0}function dt(){return[...oe].find((e)=>on(e.element))}function re(){let e=dt(),t=Boolean(e);if(t===ut)return;if(ut=t,t)I.enable(e?.tintColor?{tintColor:e.tintColor}:{});else I.disable()}function an(){let e=dt();if(!e){I.end();return}Promise.resolve().then(()=>e.run()).catch(()=>{}).finally(()=>I.end())}function io(e,t){let n={element:e,tintColor:t.tintColor,run:t.onRefresh};oe.add(n);let r=e.ownerDocument?.defaultView;if(!ne){let o=I.onRefresh(an),i=()=>re();r?.addEventListener("stx:load",i),ne=()=>{o(),r?.removeEventListener("stx:load",i)}}return re(),r?.requestAnimationFrame?.(()=>re()),()=>{if(oe.delete(n),oe.size===0)ne?.(),ne=null;re()}}var so=0.5;function sn(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 ln(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 cn(e,t=400){if(e<=0)return 0;return e*t*0.55/(t+e*0.55)}function lo(e){let{panel:t}=e,n=null,r=[],o=0,i=()=>e.viewport?.()??t.ownerDocument?.defaultView?.innerHeight??800,a=()=>sn(t.offsetHeight||t.getBoundingClientRect().height,i(),e.detents()),s=(p)=>{let u=p;if(u.button!==void 0&&u.button!==0)return;if(u.target?.closest?.("button, a, input, select, textarea, [role=button]"))return;let f=a().find((d)=>d.name===e.detent())?.y??0;n={y:u.clientY,base:f,pointerId:u.pointerId},o=f,r=[{y:f,t:u.timeStamp}],t.classList.add("is-dragging");try{p.currentTarget?.setPointerCapture?.(u.pointerId)}catch{}},l=(p)=>{if(!n)return;let u=p,f=n.base+u.clientY-n.y;o=f<0?-cn(-f):f,r.push({y:o,t:u.timeStamp});while(r.length>2&&u.timeStamp-r[0].t>100)r.shift();t.style.transform=`translateY(${o}px)`;let d=t.offsetHeight||1;t.parentElement?.style.setProperty("--native-sheet-presence",String(Math.max(0,Math.min(1,1-o/d))))},g=(p)=>{if(!n)return;let u=p;n=null;let f=r[0],d=Math.max(1,u.timeStamp-f.t),m=(o-f.y)/d;t.classList.remove("is-dragging"),t.style.transform="",t.parentElement?.style.removeProperty("--native-sheet-presence"),e.onSettle(ln({y:o,velocity:m,stops:a()}))};for(let p of e.handles)p.addEventListener("pointerdown",s),p.addEventListener("pointermove",l),p.addEventListener("pointerup",g),p.addEventListener("pointercancel",g);return()=>{for(let p of e.handles)p.removeEventListener("pointerdown",s),p.removeEventListener("pointermove",l),p.removeEventListener("pointerup",g),p.removeEventListener("pointercancel",g)}}var pt=0,ke="";function co(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;if(a.hasAttribute("data-native-sheet")&&a.getAttribute("aria-hidden")==="true")continue;a.setAttribute("inert",""),n.push(a)}r=r.parentElement}let o=t.documentElement;if(pt++===0)ke=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(--pt===0)if(ke)o.style.overflow=ke;else o.style.removeProperty("overflow")}}function uo(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 po(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 un(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 dn(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 pn(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&&!dn(r))return r}return null}function fn(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 ho(e,t={}){let n=t.root??e.documentElement;q.setKeyboardAccessory(t.keyboardAccessory===!0);let r="",o="",i=()=>{let p=pn(e);if(p&&p!==r)r=p,q.setUnderPageColor(p);let u=fn(e)?"light":"dark";if(u!==o)o=u,Z.setStyle(u)},a=rt((p)=>{un(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 g=s?.matchMedia?.("(prefers-color-scheme: dark)");return g?.addEventListener?.("change",i),s?.addEventListener("stx:load",i),i(),()=>{a(),l?.disconnect(),g?.removeEventListener?.("change",i),s?.removeEventListener("stx:load",i)}}var vo=64;var mn=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,gn=/^(?:0|[1-9]\d*)$/;function mt(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,g=typeof a.noun==="string"&&a.noun.trim()?a.noun.trim():"Item";if(!mn.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:g})}return{kinds:t,problems:n}}function G(e,t){return e.find((n)=>n.name===t)??null}function Y(e,t,n){let r=G(e,t);if(!r||!Number.isInteger(n)||n<0||n>=r.slots)return null;return`${t}-slot-${n}`}function hn(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(!gn.test(o))return null;let i=Number(o);return Y(e,r,i)===t?{kind:r,slot:i}:null}function gt(e){return e.flatMap((t)=>Array.from({length:t.slots},(n,r)=>`${t.name}-slot-${r}`))}function yo(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()),...gt(mt(n.kinds).kinds)];return[...new Set(o)].map((i)=>`${t}.${i}`)}function ht(e,t,n){let r=typeof n.name==="string"?n.name.replace(/\s+/g," ").trim():"";if(!r)return`${G(e,t)?.noun??"Item"} #${n.id}`;return r.length>120?`${r.slice(0,119).trimEnd()}…`:r}function bn(e,t,n,r,o=Date.now()){let i=G(e,n);if(!i||!Number.isInteger(r.id)||r.id<=0)return null;let a=t.filter((m)=>m.kind===n),s=ht(e,n,r),l=a.find((m)=>m.itemId===r.id)??null,g=l?null:xn(a,i.slots),p=l||g!==null?null:An(a),u=l?.slot??g??p?.slot;if(u===void 0||u===null)return null;let f={kind:n,slot:u,itemId:r.id,title:s,donatedAt:o},d=t.filter((m)=>m.kind!==n||m.slot!==u&&m.itemId!==r.id);return{entries:bt(e,[...d,f]),entry:f,evicted:p,changed:!l||l.title!==s}}function vn(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 yn(e,t,n){let r=hn(e,n);if(!r)return null;let o=t.find((a)=>a.kind===r.kind&&a.slot===r.slot),i=G(e,r.kind)?.route;return o&&i?i.replace(":id",String(o.itemId)):null}function Sn(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:g,donatedAt:p}=i;if(typeof a!=="string"||typeof s!=="number"||Y(e,a,s)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let u=`${a}-slot-${s}`,f=`${a}#${l}`;if(n.has(u)||r.has(f))continue;n.set(u,{kind:a,slot:s,itemId:l,title:typeof g==="string"&&g.trim()?g:ht(e,a,{id:l}),donatedAt:typeof p==="number"&&Number.isFinite(p)&&p>0?p:0}),r.add(f)}return bt(e,[...n.values()])}function bt(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 xn(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 An(e){return e.reduce((t,n)=>!t||n.donatedAt<t.donatedAt?n:t,null)}function wn(){let e=globalThis.craft;return e&&typeof e==="object"?e.siri:void 0}var kn="stacks_spotlight_index",En=3000;function So(e){let t=e.onProblem??((b)=>console.warn(`[spotlight] ${b}`)),n=Array.isArray(e.kinds)?{kinds:[...e.kinds],problems:[]}:mt(e.kinds);for(let b of n.problems)t(b);let r=e.enabled===!1?[]:n.kinds,o=e.storageKey??kn,i=e.legacyStorageKeys??[],a=e.timeoutMs??En,s=e.now??(()=>Date.now()),l=e.bridge??wn,g=null;function p(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function u(){if(g)return g;g=[];let b=p();if(!b)return g;try{let y=[o,...i].map((A)=>b.getItem(A)).find((A)=>A);g=y?Sn(r,JSON.parse(y)):[]}catch{g=[]}return g}function f(b){g=b;let y=p();if(!y)return;try{y.setItem(o,JSON.stringify(b));for(let A of i)y.removeItem(A)}catch{}}async function d(b){if(!b)return null;let y;try{return await Promise.race([b,new Promise((A)=>{y=setTimeout(()=>A(null),a)})])}catch{return null}finally{if(y!==void 0)clearTimeout(y)}}let m=Promise.resolve();function h(b){let y=m.then(b,b);return m=y.catch(()=>{return}),y}async function k(b,y){let A=l()?.register;if(!A||r.length===0)return!1;return h(async()=>{let R=bn(r,u(),b,y,s()),H=R&&Y(r,b,R.entry.slot);if(!R||!H)return!1;if(!R.changed)return f(R.entries),!0;let K=await d(A(R.entry.title,H))!==null;if(K)f(R.entries);return K})}async function C(b,y){let A=l()?.remove;if(!A)return!1;return h(async()=>{let{entries:R,removed:H}=vn(u(),b,y);if(!H)return!1;let K=Y(r,b,H.slot),Et=K?await d(A(K))!==null:!1;return f(R),Et})}async function W(b,y){let A=G(r,b)?.slots;if(!A||!l()?.register)return 0;let R=0;for(let H of[...y].slice(0,A).reverse())if(await k(b,H))R++;return R}async function x(){let b=l()?.remove;if(!b)return f([]),0;return h(async()=>{let y=0;for(let A of u()){let R=Y(r,A.kind,A.slot);if(R&&await d(b(R))!==null)y++}return f([]),y})}return{kinds:r,index:k,sync:W,remove:C,clear:x,routeFor:(b)=>yn(r,u(),b),entries:()=>u(),activityTypes:(b)=>gt(r).map((y)=>`${b}.${y}`),reset:()=>{g=null}}}var ft=["craftShortcut","craftSiriShortcut"];function xo(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 ft)globalThis.addEventListener(r,n);return()=>{for(let r of ft)globalThis.removeEventListener(r,n)}}import{tabBar as Rn}from"craft-native/mobile";var Tn=Rn;function Ln(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 yt(){if(typeof window>"u")return;let e=window.stxRouter;return e&&typeof e==="object"?e:void 0}function Pn(){return typeof yt()?.selectTab==="function"}function ko(e,t={}){let n=(r)=>{if(Pn()||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 vt(e){let t=e.trim();return/^#[0-9a-f]{6}$/i.test(t)?t:void 0}var Ee="stacks:tab-bar-cover";function Eo(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(Ee))}function Ro(e,t={}){let n=t.api??Tn;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=vt(o?.getPropertyValue("--native-tab-active")||""),a=vt(o?.getPropertyValue("--native-tab-active-dark")||""),s="",l=()=>{if(r()){if(s!=="hidden")n.hide();s="hidden";return}let{tabs:f,selected:d}=Mn(Ln(e)),m=JSON.stringify({tabs:f,selected:d});if(m===s)return;let h=s&&s!=="hidden"?JSON.parse(s):null;if(h&&d&&JSON.stringify(h.tabs)===JSON.stringify(f))n.select(d);else n.set(f,{selected:d,tint:i,tintDark:a});s=m},g=typeof MutationObserver==="function"?new MutationObserver(l):null;g?.observe(e,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let p=n.onSelect((f)=>{let d=yt();if(d?.selectTab){d.selectTab(f);return}Array.from(e.querySelectorAll("a[data-native-tab]")).find((h)=>h.getAttribute("href")===f)?.click()}),u=()=>l();if(typeof window<"u")window.addEventListener("stx:load",u),window.addEventListener("stx:screen-shown",u),window.addEventListener(Ee,u);return l(),()=>{if(g?.disconnect(),p(),typeof window<"u")window.removeEventListener("stx:load",u),window.removeEventListener("stx:screen-shown",u),window.removeEventListener(Ee,u);n.hide()}}var In={isAvailable:()=>c(()=>Re.isAvailable()),getBiometricType:()=>c(()=>Re.getBiometricType()),authenticate:(e)=>c(()=>Re.authenticate(e))},Hn={takePicture:(e)=>c(()=>ae.takePicture(e)),pickImage:()=>c(()=>ae.pickImage()),pickMultiple:(e)=>c(()=>ae.pickMultiple(e)),isAvailable:()=>c(()=>ae.isAvailable())},Dn={getInfo:()=>c(()=>_.getInfo()),getCapabilities:()=>c(()=>_.getCapabilities()),isMobile:()=>_.isMobile(),isIOS:()=>_.isIOS(),isAndroid:()=>_.isAndroid(),getLocale:()=>_.getLocale(),getTimezone:()=>_.getTimezone()},_n=On,Bn={getCurrentPosition:(e)=>c(()=>N.getCurrentPosition(e)),watchPosition:(e,t)=>N.watchPosition(e,t),clearWatch:(e)=>N.clearWatch(e),startRecording:(e)=>c(()=>N.startRecording(e)),pauseRecording:()=>c(()=>N.pauseRecording()),resumeRecording:()=>c(()=>N.resumeRecording()),stopRecording:()=>c(()=>N.stopRecording()),getRecordingState:()=>c(()=>N.getRecordingState()),readRecording:()=>c(()=>N.readRecording())},Fn={show:(e)=>c(()=>le.show(e)),schedule:(e)=>c(()=>le.schedule(e)),cancelAll:()=>c(()=>le.cancelAll()),setBadge:(e)=>c(()=>le.setBadge(e))},Wn={check:(e)=>c(()=>X.check(e)),request:(e)=>c(()=>X.request(e)),checkMultiple:(e)=>c(()=>X.checkMultiple(e)),requestMultiple:(e)=>c(()=>X.requestMultiple(e)),openSettings:()=>c(()=>X.openSettings())},Kn={set:(e,t)=>c(()=>ce.set(e,t)),get:(e)=>c(()=>ce.get(e)),delete:(e)=>c(()=>ce.delete(e)),clear:()=>c(()=>ce.clear())},$n={share:(e)=>c(()=>wt.share(e)),isAvailable:()=>wt.isAvailable()},zn={request:()=>c(()=>Cn.request())},de={impact:(e)=>Promise.resolve().then(()=>se.impact(e)).catch(()=>{}),notification:(e)=>Promise.resolve().then(()=>se.notification(e)).catch(()=>{}),selection:()=>Promise.resolve().then(()=>se.selection()).catch(()=>{}),vibrate:(e)=>Promise.resolve().then(()=>se.vibrate(e)).catch(()=>{}),prepare:(e)=>{let t=L("haptics.prepare");return t?Promise.resolve().then(()=>t(e)).then(()=>{},()=>{}):Promise.resolve()}};function kt(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 qn={async getInitialURL(){if(!await B())return null;return kt(await St.getInitialURL?.())},onLink(e){let t=null,n=!1,r=()=>{if(n)return;t=St.onLink?.((o,i)=>{let a=kt(o);if(a)e(a,{initial:i?.initial===!0})})??null};if(fe()?.craft)r();else B().then(r);return()=>{n=!0,t?.()}}},Oo={isAvailable:()=>ue.isAvailable(),set:(e,t)=>ue.set(e,t),remove:(e)=>ue.remove(e),clear:()=>ue.clear()},Un={enable:()=>c(()=>xt.enable()),disable:()=>c(()=>xt.disable())},jn={isAvailable:()=>ie.isAvailable(),get:()=>c(()=>ie.get()),set:(e)=>c(()=>ie.set(e)),restore:()=>c(()=>ie.restore())},Yn={isAvailable:()=>P.isAvailable(),supports:(e)=>P.supports(e),getAuthorizationStatus:()=>c(()=>P.getAuthorizationStatus()),requestAuthorization:()=>c(()=>P.requestAuthorization()),getNowPlaying:()=>c(()=>P.getNowPlaying()),play:()=>c(()=>P.play()),pause:()=>c(()=>P.pause()),togglePlayPause:()=>c(()=>P.togglePlayPause()),skipToNext:()=>c(()=>P.skipToNext()),skipToPrevious:(e)=>c(()=>P.skipToPrevious(e)),onChange:(e)=>D(()=>P.onChange(e))},Gn={isAvailable:()=>w.isAvailable(),supports:(e)=>w.supports(e),getState:()=>c(()=>w.getState()),requestAuthorization:()=>c(()=>w.requestAuthorization()),scan:(e)=>c(()=>w.scan(e)),stopScan:()=>c(()=>w.stopScan()),getDevices:()=>c(()=>w.getDevices()),connect:(e)=>c(()=>w.connect(e)),reconnect:()=>c(()=>w.reconnect()),disconnect:(e)=>c(()=>w.disconnect(e)),startRecording:()=>c(()=>w.startRecording()),pauseRecording:()=>c(()=>w.pauseRecording()),resumeRecording:()=>c(()=>w.resumeRecording()),stopRecording:()=>c(()=>w.stopRecording()),getRecordingState:()=>c(()=>w.getRecordingState()),readRecording:(e)=>c(()=>w.readRecording(e)),onReading:(e)=>D(()=>w.onReading(e)),onDevice:(e)=>D(()=>w.onDevice(e)),onState:(e)=>D(()=>w.onState(e))},Vn={isAvailable:()=>Me.isAvailable(),speak:(e,t)=>c(()=>Me.speak(e,t)),stop:()=>c(()=>Me.stop())},Xn={getStatus:()=>c(()=>At.getStatus()),onChange:(e)=>D(()=>At.onChange(e))},Jn={register:()=>c(()=>Le.register()),onToken:(e)=>Le.onToken(e),onNotification:(e)=>D(()=>Le.onNotification(e))},Qn={requestAuthorization:(e,t)=>c(()=>V.requestAuthorization(e,t)),getData:(e,t)=>c(()=>V.getData(e,t)),saveWorkout:(e)=>c(()=>V.saveWorkout(e)),getWorkouts:(e)=>c(()=>V.getWorkouts(e)),getDailyStatistics:(e,t)=>c(()=>V.getDailyStatistics(e,t)),getHeartRateSamples:(e)=>v("health.getHeartRateSamples",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),getSleepIntervals:(e)=>v("health.getSleepIntervals",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),saveMindfulSession:(e)=>v("health.saveMindfulSession",[e],()=>null).then((t)=>t??null),getMindfulSessions:(e)=>v("health.getMindfulSessions",[e??{}],()=>[]).then((t)=>Array.isArray(t)?t:[]),supports:(e)=>L(`health.${e}`)!==null},Zn={start:(e)=>c(()=>Te.start(e)),update:(e)=>c(()=>Te.update(e)),end:()=>c(()=>Te.end())},er={send:(e)=>c(()=>J.send(e)),updateContext:(e)=>c(()=>J.updateContext(e)),isReachable:()=>c(()=>J.isReachable()),onMessage:(e)=>J.onMessage(e),onReachabilityChange:(e)=>J.onReachabilityChange(e)},No=Nn;function fe(){return S()}function pe(){let e=fe()?.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 Pe(){return pe()!==null}function tr(e=2000){if(Pe()||ge())return Promise.resolve(!0);let t=fe();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(Pe())},o=setTimeout(r,e);t.addEventListener("craftReady",r,{once:!0})})}function nr(e){let t=fe();if(!t)return()=>{};if(pe()){let r=!1;return queueMicrotask(()=>{if(!r)e(new Event("craftReady"))}),()=>{r=!0}}let n=(r)=>{if(!pe())return;t.removeEventListener("craftReady",n),e(r)};return t.addEventListener("craftReady",n),()=>t.removeEventListener("craftReady",n)}async function rr(e){await de.impact("light");try{let t=await e();return await de.notification("success"),t}catch(t){throw await de.notification("error"),t}}var Io={get nativeBridge(){return pe()},biometrics:In,camera:Hn,device:Dn,haptics:de,lifecycle:_n,location:Bn,notifications:Fn,permissions:Wn,secureStorage:Kn,share:$n,appReview:zn,deepLinks:qn,keepAwake:Un,brightness:jn,music:Yn,heartRate:Gn,scheduledWorkouts:et,speech:Vn,network:Xn,pushNotifications:Jn,health:Qn,liveActivities:Zn,watchConnectivity:er,dialog:z,contextMenu:xe,browser:ze,symbols:qe,statusBar:Z,chrome:q,refresh:I,background:U,clipboard:Ue,db:je,files:Ye,shortcuts:Ge,widgets:Ve,orientation:Xe,auth:Je,storeKit:Qe,isNativeMobile:Pe,whenNative:tr,onReady:nr,withFeedback:rr};export{or as BRIDGE_WAIT_MS,qr as HEART_RATE_MATCH_MS,eo as INDOOR_CHECK_AFTER_S,vo as MAX_SPOTLIGHT_SLOTS_PER_KIND,Zt as ROUTE_GAP_S,so as SHEET_FLICK_VELOCITY,Ee as TAB_BAR_COVER_EVENT,c as afterBridge,zn as appReview,un as applyAppearance,Jt as attachHeartRate,Je as auth,_r as backLabelFor,U as background,In as biometrics,Q as bridgePending,jn as brightness,ze as browser,v as callNative,Hn as camera,Yt as canGoBack,q as chrome,Ue as clipboard,dr as confirmAction,xe as contextMenu,Eo as coverTabBar,S as craftHost,me as craftRoot,Yr as createRouteRecorder,So as createSpotlightIndex,nt as currentAppearance,je as db,Vt as deepLinkPath,qn as deepLinks,Dn as device,z as dialog,Dr as enterNavTrail,Ye as files,tn as fixDistance,Sr as focusSegment,$r as followDeepLinks,pe as getNativeMobileBridge,Hr as goBack,Wr as goBackToTabRoot,ko as handleTabReselect,de as haptics,ge as hasNativeMobileHost,Qn as health,Gn as heartRate,to as indoorVerdict,ho as installNativeChrome,xr as installPressables,Pe as isNativeMobile,on as isShown,Un as keepAwake,Ut as largeTitleMetrics,_n as lifecycle,uo as liftToBody,Zn as liveActivities,Bn as location,co as lockBackground,Ro as mirrorTabBar,Io as mobile,Yn as music,Lt as nativeFunction,L as nativeFunctionNow,Mn as nativeTabs,Br as navTrail,Xn as network,Kt as normalizeAppearance,kt as normalizeDeepLinkURL,Ft as normalizeScheduledWorkout,Fn as notifications,Or as observeLargeTitle,br as observeLongPress,io as observeNativeRefresh,zt as observePageScroll,Cr as observePullToRefresh,vr as observeSegmentScrub,lo as observeSheetDrag,rt as onAppearance,Lr as onBackgroundRefresh,O as onCraftEvent,Rr as onMemoryWarning,nr as onMobileReady,Er as onResume,Tr as onSilentPush,xo as onSpotlightTap,Xe as orientation,Ur as paceLabel,pn as pageBackground,fn as pageIsDark,j as pageScrollTop,Xr as pauseSessionClock,Wn as permissions,Nt as placeMenu,bn as placeSpotlightItem,_e as presentActionSheet,He as presentAlert,he as presentChoice,De as presentConfirm,Be as presentContextMenu,po as presentPageAsCard,Fr as previousScreenPath,qt as pullDistance,Jn as pushNotifications,Sn as readSpotlightEntries,mt as readSpotlightKinds,Ln as readTabLinks,I as refresh,vn as removeSpotlightItem,Nr as resolveScrollHost,Jr as resumeSessionClock,lt as routeStats,Pn as routerHandlesTabs,cn as rubberBand,et as scheduledWorkouts,Bt as scheduledWorkoutsUnsupported,Kn as secureStorage,Wt as segmentAt,yr as segmentForKey,Qr as sessionClockElapsed,ln as settleSheet,$n as share,sn as sheetStops,Ge as shortcuts,pr as showContextMenuFor,Oo as snapshots,Vn as speech,jr as speedLabel,No as splash,Y as spotlightAction,gt as spotlightActions,yo as spotlightActivityTypes,wn as spotlightBridge,G as spotlightKind,yn as spotlightRoute,hn as spotlightSlot,ht as spotlightTitle,Vr as startSessionClock,Z as statusBar,Qe as storeKit,D as subscribeWhenReady,qe as symbols,Tn as tabBar,Se as toNativeRect,Kr as trailEntryFor,Ot as trapFocus,no as typedDistanceKm,nn as usableFixes,ur as useActionSheet,er as watchConnectivity,B as whenBridgeReady,tr as whenNativeMobile,Ve as widgets,rr as withNativeFeedback};
@@ -0,0 +1,20 @@
1
+ import type { AppleWorkoutPlan, ScheduledWorkout, ScheduledWorkoutsAuthorization } from './scheduled-workouts';
2
+ export declare function createScheduledWorkoutsFake(options?: ScheduledWorkoutsFakeOptions): ScheduledWorkoutsFake;
3
+ /** The activities Craft's shell knows by name (HKWorkoutActivityType cases). */
4
+ export declare const SCHEDULED_WORKOUT_ACTIVITIES: readonly string[];
5
+ export declare interface ScheduledWorkoutsFakeOptions {
6
+ supported?: boolean
7
+ authorization?: ScheduledWorkoutsAuthorization
8
+ grant?: 'authorized' | 'denied'
9
+ maxCount?: number
10
+ refuse?: (plan: AppleWorkoutPlan) => string | null | undefined
11
+ dropAlerts?: (plan: AppleWorkoutPlan) => string[]
12
+ }
13
+ export declare interface ScheduledWorkoutsFake {
14
+ readonly bridge: Record<ScheduledWorkoutsMethod, (...args: any[]) => Promise<unknown>>
15
+ readonly craft: { platform: 'ios', capabilities: { scheduledWorkouts: true }, scheduledWorkouts: ScheduledWorkoutsFake['bridge'] }
16
+ readonly scheduled: ScheduledWorkout[]
17
+ readonly calls: string[]
18
+ authorization: ScheduledWorkoutsAuthorization
19
+ }
20
+ declare type ScheduledWorkoutsMethod = 'isSupported' | 'authorization' | 'requestAuthorization' | 'list' | 'schedule' | 'remove' | 'removeAll';
@@ -0,0 +1,72 @@
1
+ declare function native(): Record<string, any> | undefined;
2
+ /** The rejection every call but `isSupported()` gets where nothing can schedule. */
3
+ export declare function scheduledWorkoutsUnsupported(): Error;
4
+ declare function authorizationOf(value: unknown): ScheduledWorkoutsAuthorization;
5
+ /** A row of `list()`, or null for one that is not a scheduled plan. */
6
+ export declare function normalizeScheduledWorkout(value: unknown): ScheduledWorkout | null;
7
+ declare function call<T>(method: ScheduledWorkoutsMethod, normalize: (value: unknown) => T, ...args: unknown[]): Promise<T>;
8
+ export declare const scheduledWorkouts: ScheduledWorkoutsApi;
9
+ export declare interface AppleWorkoutStep {
10
+ goal: AppleWorkoutGoal
11
+ alert?: AppleWorkoutAlert
12
+ displayName?: string
13
+ }
14
+ export declare interface AppleIntervalBlock {
15
+ iterations: number
16
+ steps: Array<{ purpose: 'work' | 'recovery', step: AppleWorkoutStep }>
17
+ }
18
+ export declare interface AppleCustomWorkout {
19
+ activity: string
20
+ location: 'indoor' | 'outdoor' | 'unknown'
21
+ swimmingLocation?: 'pool' | 'openWater'
22
+ poolLengthMeters?: number
23
+ displayName: string
24
+ warmup?: AppleWorkoutStep
25
+ cooldown?: AppleWorkoutStep
26
+ blocks: AppleIntervalBlock[]
27
+ }
28
+ export declare interface AppleWorkoutPlan {
29
+ id: string
30
+ date: string
31
+ hour?: number
32
+ minute?: number
33
+ workout: AppleCustomWorkout
34
+ }
35
+ /** A plan on the watch's schedule. */
36
+ export declare interface ScheduledWorkout {
37
+ id: string
38
+ date: string
39
+ hour?: number
40
+ minute?: number
41
+ complete: boolean
42
+ }
43
+ export declare interface ScheduleWorkoutResult {
44
+ id: string
45
+ droppedAlerts?: string[]
46
+ }
47
+ export declare interface ScheduledWorkoutsApi {
48
+ isAvailable: () => boolean
49
+ supports: (method: ScheduledWorkoutsMethod) => boolean
50
+ isSupported: () => Promise<boolean>
51
+ authorization: () => Promise<ScheduledWorkoutsAuthorization>
52
+ requestAuthorization: () => Promise<ScheduledWorkoutsAuthorization>
53
+ list: () => Promise<ScheduledWorkout[]>
54
+ schedule: (plan: AppleWorkoutPlan) => Promise<ScheduleWorkoutResult>
55
+ remove: (id: string) => Promise<boolean>
56
+ removeAll: () => Promise<number>
57
+ }
58
+ export type ScheduledWorkoutsAuthorization = 'authorized' | 'denied' | 'notDetermined' | 'restricted' | 'unsupported';
59
+ export type AppleWorkoutGoal = | { type: 'open' }
60
+ | { type: 'time', seconds: number }
61
+ | { type: 'distance', meters: number }
62
+ | { type: 'energy', kilocalories: number }
63
+ export type AppleWorkoutAlert = | { type: 'heartRate', min: number, max: number }
64
+ | { type: 'heartRateZone', zone: number }
65
+ /** Watts (PowerRangeAlert). */
66
+ | { type: 'power', min: number, max: number }
67
+ | { type: 'powerZone', zone: number }
68
+ /** Metres per second, the current speed (SpeedRangeAlert); a pace range is sent as speed. */
69
+ | { type: 'speed', min: number, max: number }
70
+ /** Per minute (CadenceRangeAlert). */
71
+ | { type: 'cadence', min: number, max: number }
72
+ export type ScheduledWorkoutsMethod = 'isSupported' | 'authorization' | 'requestAuthorization' | 'list' | 'schedule' | 'remove' | 'removeAll';
package/dist/testing.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Bundled TypeScript declarations
3
- * Generated from 1 source files
3
+ * Generated from 4 source files
4
4
  */
5
5
 
6
6
  import { IosMobileConfig } from '@stacksjs/types';
@@ -9,7 +9,194 @@ import { IosMobileConfig } from '@stacksjs/types';
9
9
  /** Bun-only build/test entrypoint. The browser runtime never imports the iOS builder. */
10
10
  declare function prepareIosSimulatorDriver(config: IosMobileConfig, root?: string): { output: string, projectName: string };
11
11
 
12
- export { prepareIosSimulatorDriver };
12
+ // From: src/scheduled-workouts-fake.ts
13
+ declare function createScheduledWorkoutsFake(options?: ScheduledWorkoutsFakeOptions): ScheduledWorkoutsFake;
14
+ /** The activities Craft's shell knows by name (HKWorkoutActivityType cases). */
15
+ declare const SCHEDULED_WORKOUT_ACTIVITIES: readonly string[];
16
+ declare interface ScheduledWorkoutsFakeOptions {
17
+ supported?: boolean
18
+ authorization?: ScheduledWorkoutsAuthorization
19
+ grant?: 'authorized' | 'denied'
20
+ maxCount?: number
21
+ refuse?: (plan: AppleWorkoutPlan) => string | null | undefined
22
+ dropAlerts?: (plan: AppleWorkoutPlan) => string[]
23
+ }
24
+ declare interface ScheduledWorkoutsFake {
25
+ readonly bridge: Record<ScheduledWorkoutsMethod, (...args: any[]) => Promise<unknown>>
26
+ readonly craft: { platform: 'ios', capabilities: { scheduledWorkouts: true }, scheduledWorkouts: ScheduledWorkoutsFake['bridge'] }
27
+ readonly scheduled: ScheduledWorkout[]
28
+ readonly calls: string[]
29
+ authorization: ScheduledWorkoutsAuthorization
30
+ }
31
+ declare type ScheduledWorkoutsMethod = 'isSupported' | 'authorization' | 'requestAuthorization' | 'list' | 'schedule' | 'remove' | 'removeAll';
32
+
33
+ // From: src/scheduled-workouts.ts
34
+ declare function native(): Record<string, any> | undefined;
35
+ /** The rejection every call but `isSupported()` gets where nothing can schedule. */
36
+ declare function scheduledWorkoutsUnsupported(): Error;
37
+ declare function authorizationOf(value: unknown): ScheduledWorkoutsAuthorization;
38
+ /** A row of `list()`, or null for one that is not a scheduled plan. */
39
+ declare function normalizeScheduledWorkout(value: unknown): ScheduledWorkout | null;
40
+ declare function call<T>(method: ScheduledWorkoutsMethod_1, normalize: (value: unknown) => T, ...args: unknown[]): Promise<T>;
41
+ declare const scheduledWorkouts: ScheduledWorkoutsApi;
42
+ declare interface AppleWorkoutStep {
43
+ goal: AppleWorkoutGoal
44
+ alert?: AppleWorkoutAlert
45
+ displayName?: string
46
+ }
47
+ declare interface AppleIntervalBlock {
48
+ iterations: number
49
+ steps: Array<{ purpose: 'work' | 'recovery', step: AppleWorkoutStep }>
50
+ }
51
+ declare interface AppleCustomWorkout {
52
+ activity: string
53
+ location: 'indoor' | 'outdoor' | 'unknown'
54
+ swimmingLocation?: 'pool' | 'openWater'
55
+ poolLengthMeters?: number
56
+ displayName: string
57
+ warmup?: AppleWorkoutStep
58
+ cooldown?: AppleWorkoutStep
59
+ blocks: AppleIntervalBlock[]
60
+ }
61
+ declare interface AppleWorkoutPlan {
62
+ id: string
63
+ date: string
64
+ hour?: number
65
+ minute?: number
66
+ workout: AppleCustomWorkout
67
+ }
68
+ /** A plan on the watch's schedule. */
69
+ declare interface ScheduledWorkout {
70
+ id: string
71
+ date: string
72
+ hour?: number
73
+ minute?: number
74
+ complete: boolean
75
+ }
76
+ declare interface ScheduleWorkoutResult {
77
+ id: string
78
+ droppedAlerts?: string[]
79
+ }
80
+ declare interface ScheduledWorkoutsApi {
81
+ isAvailable: () => boolean
82
+ supports: (method: ScheduledWorkoutsMethod_1) => boolean
83
+ isSupported: () => Promise<boolean>
84
+ authorization: () => Promise<ScheduledWorkoutsAuthorization>
85
+ requestAuthorization: () => Promise<ScheduledWorkoutsAuthorization>
86
+ list: () => Promise<ScheduledWorkout[]>
87
+ schedule: (plan: AppleWorkoutPlan) => Promise<ScheduleWorkoutResult>
88
+ remove: (id: string) => Promise<boolean>
89
+ removeAll: () => Promise<number>
90
+ }
91
+ type ScheduledWorkoutsAuthorization = 'authorized' | 'denied' | 'notDetermined' | 'restricted' | 'unsupported';
92
+ type AppleWorkoutGoal = | { type: 'open' }
93
+ | { type: 'time', seconds: number }
94
+ | { type: 'distance', meters: number }
95
+ | { type: 'energy', kilocalories: number }
96
+ type AppleWorkoutAlert = | { type: 'heartRate', min: number, max: number }
97
+ | { type: 'heartRateZone', zone: number }
98
+ /** Watts (PowerRangeAlert). */
99
+ | { type: 'power', min: number, max: number }
100
+ | { type: 'powerZone', zone: number }
101
+ /** Metres per second, the current speed (SpeedRangeAlert); a pace range is sent as speed. */
102
+ | { type: 'speed', min: number, max: number }
103
+ /** Per minute (CadenceRangeAlert). */
104
+ | { type: 'cadence', min: number, max: number }
105
+ type ScheduledWorkoutsMethod_1 = 'isSupported' | 'authorization' | 'requestAuthorization' | 'list' | 'schedule' | 'remove' | 'removeAll';
106
+
107
+ // From: src/bridge.ts
108
+ /** The page's window, when there is one. */
109
+ declare function craftHost(): CraftHost | undefined;
110
+ /** `window.craft`, the bridge object, once installed. */
111
+ declare function craftRoot(): Record<string, any> | undefined;
112
+ /**
113
+ * Whether this page runs inside Craft's phone shell, before the bridge exists.
114
+ *
115
+ * Craft installs `window.craft` once the page has finished loading on an older
116
+ * shell — images and all — so a bridge check answers `false` during setup on
117
+ * a phone, and a layout that decides then renders the website's chrome in the
118
+ * app. The transports are there from the start: Android's `CraftAndroid`
119
+ * interface, and on iOS the `craft` message handler. Craft's macOS windows
120
+ * carry that handler too, so on iOS an iPhone or iPad user agent is what makes
121
+ * it the phone app.
122
+ */
123
+ declare function hasNativeMobileHost(): boolean;
124
+ /** A native host whose bridge object is not installed yet: worth waiting for. */
125
+ declare function bridgePending(): boolean;
126
+ /**
127
+ * Resolves once the bridge object (`window.craft`) is installed: `true` then,
128
+ * `false` in a browser at once, or after `timeoutMs` in a host that never
129
+ * installs it.
130
+ *
131
+ * Not whenNativeMobile(), which answers `true` as soon as the phone shell is
132
+ * recognisable, before the bridge exists and before anything can be asked of it.
133
+ */
134
+ declare function whenBridgeReady(timeoutMs?: unknown): Promise<boolean>;
135
+ /**
136
+ * The bridge function at `path` (`'dialog.confirm'`), or null when this host
137
+ * has none. Synchronous: no waiting for a bridge still on its way.
138
+ */
139
+ declare function nativeFunctionNow(path: string): ((...args: any[]) => unknown) | null;
140
+ /**
141
+ * The bridge function at `path`, waiting for a native host's bridge to arrive
142
+ * first. Null in a browser, on a shell that predates the API, or when the
143
+ * bridge did not come within `timeoutMs`.
144
+ */
145
+ declare function nativeFunction(path: string, timeoutMs?: unknown): Promise<((...args: any[]) => unknown) | null>;
146
+ /**
147
+ * Calls the bridge function at `path`, or `fallback` where there is none.
148
+ *
149
+ * Inside a native host whose bridge is still loading, the call is held until
150
+ * it arrives, so an early call reaches the native implementation rather than
151
+ * the web one.
152
+ */
153
+ declare function callNative<T>(path: string, args: unknown[], fallback: () => T | Promise<T>, options?: CallNativeOptions): Promise<T>;
154
+ /**
155
+ * Runs `run` once a native host's bridge is installed: at once when it is
156
+ * there or in a browser, after it arrives (or `BRIDGE_WAIT_MS` passes) in a
157
+ * host still loading it.
158
+ *
159
+ * craft-native's services read `window.craft` at call time and take their web
160
+ * path when it is missing, which during an older shell's launch it is. The
161
+ * services this package exports call through here, as plain object literals
162
+ * rather than wrapped at import: a bundler drops an object literal nobody
163
+ * imports, and could not drop a call made at module scope once minified.
164
+ */
165
+ declare function afterBridge<T>(run: () => T | Promise<T>, timeoutMs?: unknown): Promise<T>;
166
+ /**
167
+ * Subscribes once the bridge can take the subscription: at once when it is
168
+ * there or in a browser, otherwise when it arrives. The returned function
169
+ * unsubscribes either way, including before the subscription was made.
170
+ */
171
+ declare function subscribeWhenReady(subscribe: () => (() => void) | void, timeoutMs?: unknown): () => void;
172
+ /** Listens for a Craft DOM event on the window; the detail is passed through. */
173
+ declare function onCraftEvent<T = Record<string, unknown>>(name: string, callback: (detail: T) => void): () => void;
174
+ /**
175
+ * Reaching Craft's bridge at the right moment.
176
+ *
177
+ * Craft's iOS shell injects `window.craft` at document start, but an older
178
+ * shell installs it once the page has finished loading. A call made before
179
+ * then used to find no bridge and quietly take the web path: a secure-storage
180
+ * read answered from localStorage, a confirm drew the browser's own dialog.
181
+ * Inside a native host, a call now waits for the bridge (briefly: a host that
182
+ * never installs one gets the web fallback after `BRIDGE_WAIT_MS`), and only a
183
+ * browser takes the fallback at once.
184
+ */
185
+ /** How long a call waits for a native host's bridge before using the web fallback. */
186
+ declare const BRIDGE_WAIT_MS: 2500;
187
+ declare interface CraftHost extends EventTarget {
188
+ craft?: unknown
189
+ CraftAndroid?: unknown
190
+ webkit?: { messageHandlers?: Record<string, unknown> }
191
+ document?: Document
192
+ navigator?: Navigator
193
+ }
194
+ declare interface CallNativeOptions {
195
+ fallbackOnError?: boolean
196
+ timeoutMs?: number
197
+ }
198
+
199
+ export { prepareIosSimulatorDriver, ScheduledWorkoutsFake, ScheduledWorkoutsFakeOptions, createScheduledWorkoutsFake, SCHEDULED_WORKOUT_ACTIVITIES };
13
200
  export { NativeMutationValidator } from 'craft-native/ios';
14
201
  export { NativeValidationResult } from 'craft-native/ios';
15
202
  export { SimulatorStep } from 'craft-native/ios';
package/dist/testing.js CHANGED
@@ -3,6 +3,142 @@
3
3
  import { resolve } from "path";
4
4
  import { initSimulatorDriver } from "craft-native/ios";
5
5
  import { createNativeMutationValidator, restoreShell, serializeSimulatorSteps } from "craft-native/ios";
6
+
7
+ // src/scheduled-workouts-fake.ts
8
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9
+ var SCHEDULED_WORKOUT_ACTIVITIES = [
10
+ "running",
11
+ "cycling",
12
+ "swimming",
13
+ "walking",
14
+ "hiking",
15
+ "traditionalStrengthTraining",
16
+ "functionalStrengthTraining",
17
+ "rowing",
18
+ "yoga",
19
+ "flexibility",
20
+ "crossTraining",
21
+ "elliptical",
22
+ "highIntensityIntervalTraining",
23
+ "other",
24
+ "coreTraining",
25
+ "mixedCardio",
26
+ "stairClimbing",
27
+ "stairs",
28
+ "stepTraining",
29
+ "pilates",
30
+ "cardioDance",
31
+ "kickboxing",
32
+ "boxing",
33
+ "jumpRope",
34
+ "cooldown",
35
+ "crossCountrySkiing",
36
+ "paddleSports",
37
+ "handCycling",
38
+ "wheelchairRunPace",
39
+ "wheelchairWalkPace"
40
+ ];
41
+ function failure(message, code) {
42
+ return Object.assign(new Error(message), { code });
43
+ }
44
+ function realDay(date) {
45
+ if (typeof date !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(date))
46
+ return false;
47
+ const [year, month, day] = date.split("-").map(Number);
48
+ const parsed = new Date(Date.UTC(year, month - 1, day));
49
+ return parsed.getUTCFullYear() === year && parsed.getUTCMonth() === month - 1 && parsed.getUTCDate() === day;
50
+ }
51
+ function wholeIn(value, min, max) {
52
+ return typeof value === "number" && Number.isInteger(value) && value >= min && value <= max;
53
+ }
54
+ function createScheduledWorkoutsFake(options = {}) {
55
+ const supported = options.supported !== false;
56
+ const maxCount = options.maxCount ?? 15;
57
+ const scheduled = [];
58
+ const calls = [];
59
+ const state = { authorization: supported ? options.authorization ?? "notDetermined" : "unsupported" };
60
+ const allowed = () => {
61
+ if (!supported)
62
+ throw failure("unsupported", "UNSUPPORTED");
63
+ if (state.authorization !== "authorized")
64
+ throw failure("Scheduling workouts on the Apple Watch has not been allowed", "NOT_AUTHORIZED");
65
+ };
66
+ const bridge = {
67
+ isSupported: async () => {
68
+ calls.push("isSupported");
69
+ return supported;
70
+ },
71
+ authorization: async () => {
72
+ calls.push("authorization");
73
+ return state.authorization;
74
+ },
75
+ requestAuthorization: async () => {
76
+ calls.push("requestAuthorization");
77
+ if (supported && state.authorization === "notDetermined")
78
+ state.authorization = options.grant ?? "authorized";
79
+ return state.authorization;
80
+ },
81
+ list: async () => {
82
+ calls.push("list");
83
+ allowed();
84
+ return scheduled.map((row) => ({ ...row }));
85
+ },
86
+ schedule: async (plan) => {
87
+ calls.push("schedule");
88
+ allowed();
89
+ if (!plan || typeof plan.id !== "string" || !UUID.test(plan.id))
90
+ throw failure("A scheduled workout needs an id (a UUID)", "INVALID_ARGUMENT");
91
+ const hour = plan.hour ?? 7;
92
+ const minute = plan.minute ?? 0;
93
+ if (!realDay(plan.date) || !wholeIn(hour, 0, 23) || !wholeIn(minute, 0, 59))
94
+ throw failure("A scheduled workout needs a date ('YYYY-MM-DD') and, when given, an hour 0-23 and a minute 0-59", "INVALID_ARGUMENT");
95
+ const activity = plan.workout?.activity;
96
+ if (!SCHEDULED_WORKOUT_ACTIVITIES.includes(activity))
97
+ throw failure(`WorkoutKit has no activity '${activity ?? ""}'`, "INVALID_ARGUMENT");
98
+ const refusal = options.refuse?.(plan);
99
+ if (refusal)
100
+ throw failure(refusal, "UNSUPPORTED_GOAL");
101
+ const id = plan.id.toLowerCase();
102
+ const same = scheduled.filter((row) => row.id === id);
103
+ if (!same.some((row) => row.date === plan.date && row.hour === hour && row.minute === minute)) {
104
+ if (scheduled.length - same.length >= maxCount)
105
+ throw failure(`The Apple Watch holds at most ${maxCount} scheduled workouts; remove one first`, "LIMIT_REACHED");
106
+ scheduled.splice(0, scheduled.length, ...scheduled.filter((row) => row.id !== id));
107
+ scheduled.push({ id, date: plan.date, hour, minute, complete: false });
108
+ }
109
+ const dropped = options.dropAlerts?.(plan) ?? [];
110
+ return dropped.length ? { id, droppedAlerts: dropped } : { id };
111
+ },
112
+ remove: async (id) => {
113
+ calls.push("remove");
114
+ allowed();
115
+ if (typeof id !== "string" || !UUID.test(id))
116
+ throw failure("remove needs a plan id (a UUID)", "INVALID_ARGUMENT");
117
+ const before = scheduled.length;
118
+ scheduled.splice(0, scheduled.length, ...scheduled.filter((row) => row.id !== id.toLowerCase()));
119
+ return scheduled.length < before;
120
+ },
121
+ removeAll: async () => {
122
+ calls.push("removeAll");
123
+ allowed();
124
+ return scheduled.splice(0).length;
125
+ }
126
+ };
127
+ return {
128
+ bridge,
129
+ craft: { platform: "ios", capabilities: { scheduledWorkouts: true }, scheduledWorkouts: bridge },
130
+ scheduled,
131
+ calls,
132
+ get authorization() {
133
+ return state.authorization;
134
+ },
135
+ set authorization(value) {
136
+ state.authorization = value;
137
+ }
138
+ };
139
+ }
140
+
141
+ // src/testing.ts
6
142
  function prepareIosSimulatorDriver(config, root = process.cwd()) {
7
143
  const simulator = config.simulator ?? {};
8
144
  const output = resolve(root, simulator.output ?? "storage/framework/mobile/ios-driver");
@@ -17,7 +153,9 @@ function prepareIosSimulatorDriver(config, root = process.cwd()) {
17
153
  return { output, projectName };
18
154
  }
19
155
  export {
156
+ SCHEDULED_WORKOUT_ACTIVITIES,
20
157
  createNativeMutationValidator,
158
+ createScheduledWorkoutsFake,
21
159
  prepareIosSimulatorDriver,
22
160
  restoreShell as restoreIosShell,
23
161
  serializeSimulatorSteps
package/dist/types.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare interface CraftMobileCapabilities {
23
23
  deepLinks?: boolean
24
24
  flashlight?: boolean
25
25
  music?: boolean
26
+ scheduledWorkouts?: boolean
26
27
  network?: boolean
27
28
  deviceInfo?: boolean
28
29
  badge?: boolean
@@ -71,6 +72,7 @@ export declare interface MobileApi {
71
72
  brightness: BrightnessApi
72
73
  music: MusicApi
73
74
  heartRate: HeartRateApi
75
+ scheduledWorkouts: import('./scheduled-workouts').ScheduledWorkoutsApi
74
76
  speech: SpeechApi
75
77
  network: NetworkApi
76
78
  pushNotifications: PushNotificationsApi
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/mobile",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.165",
5
+ "version": "0.75.167",
6
6
  "description": "Craft-powered native mobile runtime for Stacks and STX applications",
7
7
  "author": "Chris Breuer",
8
8
  "license": "MIT",
@@ -38,11 +38,11 @@
38
38
  "test": "bun test"
39
39
  },
40
40
  "dependencies": {
41
- "@stacksjs/types": "0.75.165",
41
+ "@stacksjs/types": "0.75.167",
42
42
  "craft-native": ">=0.0.162"
43
43
  },
44
44
  "devDependencies": {
45
- "@stacksjs/build": "0.75.165",
45
+ "@stacksjs/build": "0.75.167",
46
46
  "better-dx": "^0.2.24"
47
47
  }
48
48
  }