1import{d as e,f as t}from"./use-service-k6uz85f2.js";import{t as n}from"./service-ixrgesy3.js";import{G as r,U as i,a,at as o,ct as s,i as c,ot as l,q as u,t as d}from"./athlete-data-mjnqm81x.js";import{M as f}from"./external-workout-provider-type-mzo7k423.js";import{s as p}from"./calendar.api-c44hy8nk.js";import"./member-hjcrv54i.js";import{_ as m,b as h,g,l as _,r as v,y}from"./mobx.esm-d47kztp6.js";import{n as b}from"./race-priority-c3fjeos4.js";import{n as x,t as S}from"./decorate-nyiu1wsn.js";import{t as ee}from"./shared-worker-messages-bwtim10w.js";import{d as C,l as w,s as T}from"./utils-c3idkeyo.js";import{r as E}from"./types-ci41grw1.js";import{n as D,t as O}from"./message-bus-message-type-i2gnyusk.js";import{a as k,d as A,h as j,l as M}from"./tr-enums-bvtp9axg.js";import{t as N}from"./localization-hf9jy747.js";import{a as P,o as F}from"./known-workout-ids-mjuipmt6.js";import{t as I}from"./decorate-param-cli1id0x.js";import{t as L}from"./v4-epydndzf.js";import{t as R}from"./service-nx63m87w.js";import{n as z}from"./admincalendar.api-jr4tgdpa.js";var B=class{constructor(e){this.deps=e,this.quietTimer=null,this.unsubscribeStatus=null,this.visibilityHandler=null,this.quietMs=e.quietMs??15e3}start(){this.unsubscribeStatus===null&&(this.unsubscribeStatus=this.deps.onStatusChange(e=>{e===ee.Connected&&this.deps.hasPending()&&this.deps.reconcile().catch(()=>{})}),typeof document<`u`&&(this.visibilityHandler=()=>{document.visibilityState===`visible`&&this.deps.hasPending()&&this.deps.reconcile().catch(()=>{})},document.addEventListener(`visibilitychange`,this.visibilityHandler)))}armQuietTimer(){this.clearQuietTimer(),this.quietTimer=setTimeout(()=>{this.quietTimer=null,this.deps.hasPending()&&this.deps.reconcile().catch(()=>{}).finally(()=>{this.deps.hasPending()&&this.armQuietTimer()})},this.quietMs)}notifyProgress(){this.deps.hasPending()&&this.armQuietTimer()}clearQuietTimer(){this.quietTimer!==null&&(clearTimeout(this.quietTimer),this.quietTimer=null)}dispose(){this.clearQuietTimer(),this.unsubscribeStatus?.(),this.unsubscribeStatus=null,this.visibilityHandler&&(document.removeEventListener(`visibilitychange`,this.visibilityHandler),this.visibilityHandler=null)}},V=function(e){return e[e.FtpChange=17]=`FtpChange`,e[e.FtpRecord=18]=`FtpRecord`,e[e.WattKgChange=21]=`WattKgChange`,e[e.WattKgRecord=22]=`WattKgRecord`,e[e.ViewedAiFtpDetection=23]=`ViewedAiFtpDetection`,e[e.OnboardingFtpDetectionUnviewed=24]=`OnboardingFtpDetectionUnviewed`,e[e.OnboardingFtpDetectionRejected=25]=`OnboardingFtpDetectionRejected`,e}({}),H=e=>typeof e==`object`&&!!e,U=e=>{if(!H(e)||!H(e.response))return!1;if(e.response.status===403)return!0;if(e.response.status!==500||!H(e.response.data))return!1;let t=e.response.data;return[t.Title,t.title,t.Detail,t.detail,t.Message,t.message,t.ExceptionMessage,t.exceptionMessage].some(e=>e===`Private data`||e===`This athlete has requested that we keep their data private.`)},W=new Set([j.RecommendationPredictionEasy,j.RecommendationPredictionModerate,j.RecommendationPredictionHard,j.RecommendationPredictionVeryHard,j.RecommendationPredictionAllOut,j.RecommendationPredictionFailed,j.AdaptedRecommendationPredictionEasy,j.AdaptedRecommendationPredictionModerate,j.AdaptedRecommendationPredictionHard,j.AdaptedRecommendationPredictionVeryHard,j.AdaptedRecommendationPredictionAllOut,j.AdaptedRecommendationPredictionFailed,j.IsOverRecommendedFailRate,j.AdaptedIsOverRecommendedFailRate]),G=new Set([...W,j.RecommendationSettingsMaxFailRate,j.RecommendationSettingsEasy,j.RecommendationSettingsModerate,j.RecommendationSettingsHard,j.RecommendationSettingsVeryHard,j.RecommendationSettingsAllOut,j.RecommendationSettingsFailed,j.RecommendationSettingsModelCommitDate]);function K(e,t){return Object.fromEntries(Object.entries(e??{}).filter(([e])=>!t.has(Number(e))))}var q=e=>K(e,G),J,Y,X,Z,Q,te=e=>{let t=e.type===b.Cycling&&!e.manuallyCompleted,n=e.model!=null&&e.model.activityType===b.Rest&&(e.model.alternateWorkout!=null||e.model.adaptationReason!=null),r=e.model!=null&&e.model.activityType===b.Cycling&&e.model.workout!=null&&(P(e.model.workout.id)||F(e.model.workout.id)),i=e.model!=null&&e.model.activityType===b.Cycling&&e.model.workout!=null&&e.model.workout.typeId==409,a=e.model!=null&&e.model.activityType===b.Cycling&&e.model.workout!=null&&(!e.model.workout.zoneId||!e.model.workout.profileId);return!e.isManuallySkipped&&(t&&!r&&!i&&!a||n)},ne=60;function re(e,t){return{...K(e,W),...t??{}}}var ie=3e3;function ae(e,t){let n=t.durationSeconds??e.durationInSeconds,r=t.name??e.name,i={...e,name:r,durationInSeconds:n,tss:t.tss??e.tss,stressEstimateValue:t.tss??e.stressEstimateValue,metrics:re(e.metrics,t.metrics)};return`recommendationReason`in i&&(i.recommendationReason=t.recommendationReason??i.recommendationReason),`workout`in i&&i.workout!=null&&t.workoutId!=null&&(i.workout={...i.workout,id:t.workoutId,name:r,duration:t.durationSeconds==null?i.workout.duration:t.durationSeconds/ne}),i}var $=class{constructor(e,t,n,d,m){this.messageBus=e,this.memberService=t,this.athleteData=n,this.dateTimeService=d,this.toastNotificationsService=m,this._failureToastOwners=new Set,this._failureToastId=null,this.show
1FailureToast=(e,t)=>{this._failureToastOwners.has(e)||(this._failureToastOwners.add(e),this._failureToastId!=null&&this.toastNotificationsService.hide(this._failureToastId),this._failureToastId=this.toastNotificationsService.show({message:t??N(`Your calendar could not be updated.`),type:`error`,action:{label:N(`Retry`),onClick:()=>void this.retryFailedFlushForward(e)}},{sticky:!0,testId:`flush-forward-failure-toast`}))},this.hideFailureToast=()=>{this._failureToastId!=null&&(this.toastNotificationsService.hide(this._failureToastId),this._failureToastId=null)},this.retryFailedFlushForward=async e=>{let t=this.memberService.memberInfo?.memberId;if(t==null)return;this.hideFailureToast();let n=L();console.debug(`[${n}] Retrying flush forward after failed walk ${e}`),this.flushForward(C(this.calendarData.today),n,{force:!0});try{await s(t,!1,n)}catch(t){console.error(`[${n}] Flush forward retry request failed`,t),this._failureToastOwners.delete(e),this._reconcileScheduler?.armQuietTimer()}},this._lastUpdatedPlannedActivityId=null,this._idsExcludedFromSwap=new Set,this._cohortHoldIds=new Set,this.setCohortHold=e=>{this._cohortHoldIds.add(e),this._pendingPlannedActivityFlushForwardUpdates.add(e)},this.clearCohortHold=e=>{this._cohortHoldIds.delete(e)&&this._pendingPlannedActivityFlushForwardUpdates.delete(e)},this._pendingFitnessThresholdProjectionIds=new Set,this._flushForwardOwner=null,this._deferredFlushForwardPending=!1,this._progressDeniedMemberId=null,this._reconcileScheduler=null,this._reconcileInFlight=null,this._reconcileGeneration=0,this.reconcile=()=>{let e=this.memberService.memberInfo?.memberId??null;if(this._reconcileInFlight&&e===this._reconcileMemberId)return this._reconcileInFlight;let t=this._reconcileMemberId!==void 0&&e!==this._reconcileMemberId;this._reconcileMemberId=e,t&&(this._reconcileGeneration++,h(()=>{this._progressDeniedMemberId=null,this._deferredFlushForwardPending=e!==null,this._flushForwardOwner=null,this._currentFlushForwardDate=null,this._lastUpdatedPlannedActivityId=null,this._pendingPlannedActivityFlushForwardUpdates.clear(),this._pendingFitnessThresholdProjectionIds.clear(),this._idsExcludedFromSwap.clear(),this._cohortHoldIds.clear()}),e!==null&&this._reconcileScheduler?.armQuietTimer());let n=this._reconcile(t).finally(()=>{this._reconcileInFlight===n&&(this._reconcileInFlight=null)});return this._reconcileInFlight=n,n},this.readFailureLeftOnHead=async()=>{let e=this.memberService.memberInfo?.memberId;if(e==null||this.hasPendingFlushForward||this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing)return;let t;try{t=await o(e,!1)}catch(e){console.error(`[load] Error fetching flush forward progress`,e);return}t.failed&&t.owner!=null&&t.failureWasRecorded&&!t.pending&&this.showFailureToast(t.owner,t.failureReason)},this._reconcile=async(e=!1)=>{if(this.progressUnavailable||!e&&!this.hasPendingFlushForward)return;if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`),h(()=>{this._deferredFlushForwardPending=!1});return}this.flushReveal();let t=this.memberService.memberInfo?.memberId??null,n=this._reconcileGeneration;if(t==null)return;let r=this._flushForwardOwner,i;try{i=await o(t,!1)}catch(e){if(n!==this._reconcileGeneration||t!==(this.memberService.memberInfo?.memberId??null))return;if(U(e)){let e=this.flushForwardPendingActivityIds;h(()=>{this._progressDeniedMemberId=t,this._deferredFlushForwardPending=!1,this._flushForwardOwner=null,this._currentFlushForwardDate=null,this._lastUpdatedPlannedActivityId=null,this._pendingFitnessThresholdProjectionIds.clear(),this._idsExcludedFromSwap.clear();for(let t of e)this._pendingPlannedActivityFlushForwardUpdates.delete(t)}),this._reconcileScheduler?.clearQuietTimer();return}console.error(`[reconcile] Error fetching flush forward progress`,e);return}if(n!==this._reconcileGeneration||t!==(this.memberService.memberInfo?.memberId??null)||this._flushForwardOwner!==r)return;h(()=>{this._deferredFlushForwardPending=i.pending,this._flushForwardOwner===null&&(this._flushForwardOwner=i.owner)}),e&&this.hasPendingFlushForward&&this._reconcileScheduler?.armQuietTimer();let a=this._flushForwardOwner;if(i.owner!=null&&a!=null&&i.owner!==a&&i.isActive){console.debug(`[reconcile] FF owner changed from ${a} to ${i.owner}`);let e=i.currentDay==null?C(this.calendarData.today):f(i.currentDay);this.flushForward(e,i.owner,{force:!0});return}if(!i.pending&&(i.owner==null||i.failed)){i.failed&&i.owner!=null&&i.failureWasRecorded?this.show
1FailureToast(i.owner,i.failureReason):i.failed||this.hideFailureToast();let e=this.flushForwardPendingActivityIds,r=[...this._provisionalPlannedActivityIds].filter(t=>!e.includes(t)),a=await this.refetchAndClearPending([...e,...r]);if(n!==this._reconcileGeneration||t!==(this.memberService.memberInfo?.memberId??null))return;h(()=>{if(this._flushForwardOwner=null,this._currentFlushForwardDate=null,this._lastUpdatedPlannedActivityId=null,a){for(let t of e)this._pendingPlannedActivityFlushForwardUpdates.delete(t);this._provisionalPlannedActivityIds.clear(),this.revertProvisionalFitnessThresholds(),this._pendingFitnessThresholdProjectionIds.clear()}}),a?this._reconcileScheduler?.clearQuietTimer():this._reconcileScheduler?.armQuietTimer();return}if(i.currentDay!=null){let e=f(i.currentDay);h(()=>{this._currentFlushForwardDate=e})}},this.refetchAndClearPending=async e=>{if(e.length===0)return!0;let t=this.memberService.memberInfo?.memberId??null;if(t==null)return!1;let n=this._reconcileGeneration;try{let r=await p(t,e,!1);return n!==this._reconcileGeneration||t!==(this.memberService.memberInfo?.memberId??null)?!1:(h(()=>{for(let e of r)this.plannedActivitySaved(e)}),!0)}catch(e){return console.error(`FF reconcile: planned-activity refetch failed`,e),!1}},this.init=async()=>{this._initalized||(console.debug(`Initializing FlushForwardStateManager`),this.messageBus.subscribe(O.FlushForwardStatus,this.handleFlushForwardStatusMessage),this.messageBus.subscribe(O.PlannedActivityFlushForwardComplete,this.handleFlushForwardPlannedActivityComplete),this.messageBus.subscribe(O.RedLightGreenLightStatusUpdate,this.handleRedLightGreenLightStatusUpdate),this.messageBus.subscribe(O.FlushForwardOwnerChanged,this.handleFlushForwardOwnerChanged),this.messageBus.subscribe(O.FlushForwardWalkComplete,this.handleFlushForwardWalkComplete),this.messageBus.subscribe(O.FlushForwardV2Answered,this.handleFlushForwardV2Answered),this.messageBus.subscribe(O.FlushForwardV2Complete,this.handleFlushForwardV2Complete),this.messageBus.subscribe(O.FitnessThresholdCreated,this.handleFitnessThresholdAddedOrUpdated),this.messageBus.subscribe(O.FitnessThresholdUpdated,this.handleFitnessThresholdAddedOrUpdated),this.messageBus.subscribe(O.FitnessThresholdDeleted,this.handleFitnessThresholdDeleted),this.loadLastFlushForwardTriggered(),this.readFailureLeftOnHead(),this._reconcileScheduler=new B({reconcile:()=>this.reconcile(),hasPending:()=>this.hasPendingFlushForward,onStatusChange:e=>y(()=>this.messageBus.status,t=>e(t))}),this._reconcileScheduler.start(),this._reconcileMemberId=this.memberService.memberInfo?.memberId??null,y(()=>this.memberService.memberInfo?.memberId??null,()=>{this.reconcile()}),this._initalized=!0)},this.adminFlushFromHere=e=>{let t=e??C(this.calendarData.today);console.debug(`Admin flush forward from`,i(t));let n=L(),r=this.flushForward(t,n);r&&z({date:w(r)},n)},this._pendingPlannedActivityFlushForwardUpdates=new Set,this._provisionalPlannedActivityIds=new Set,this._provisionalFitnessThresholds=new Map,this._revealHeldFitnessThresholdIds=new Set,this._initalized=!1,this._currentFlushForwardDate=null,this.loadLastFlushForwardTriggered=()=>{try{if(this.memberService.memberInfo==null)return;l(this.memberService.memberInfo.memberId)}catch(e){console.error(`Error loading last flush forward triggered`,e)}},this.handleFlushForwardOwnerChanged=e=>{if(this.memberService.memberInfo==null)return;if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let{params:{date:t},owner:n}=e;console.debug(`[${n}] Flush forward owner changed: ${i(t)}`),this.flushForward(t,n,{force:!0})},this.handleFlushForwardStatusMessage=e=>{if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let{params:{current:t},owner:n}=e;if(this._flushForwardOwner!==null&&this._flushForwardOwner!==n){console.debug(`[${n}] Ignoring flush forward status message as another owner is active`);return}this._currentFlushForwardDate=t,this.flushForward(t,n),console.debug(`[${n}] Flush forward status message: ${i(t)} -> ${i(this.calendarData.endOfAiWindow)}`),this._reconcileScheduler?.notifyProgress()},this.handleFlushForwardPlannedActivityComplete=e=>{if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let{params:{stub:{id:t}},owner:n}=e;if(console.debug(`[${n}] Planned activity flush forward updated`,t),this._flushForwardOwner!==n){console.debug(`[${n}] Ignoring flush forward status message as another owner is active`);return}let a=this.calendarData.plannedActivityStates.get(t)?.date;if(e.apiData==null){console.debug(`[${n}] ApiData missing for planned activity: ${t}`);return}try{let o=e.apiData;if(console.debug(`[${n}] Fetch planned activity complete for ${t}`,i(o.date)),this._currentFlushForwardDate!==null&&a&&r(this._currentFlushForwardDate,a)){console.debug(`[${n}] Ignoring flush forward status message as the PlannedActivity date is after the current flush forward date: ${i(this._currentFlushForwardDate)}(current) -> ${i(a)}(event)`);return}if(this._flushForwardOwner!==n){console.debug(`[${n}] Ignoring flush forward status message as another owner is active`);return}if(a&&!u(o.date,a)){console.debug(`[${n}] Ignoring flush forward status message as the PlannedActivity date has changed (assuming server update is stale): ${i(a)}(client) -> ${i(o.date)}(server)`);return}if(this.calendarData.plannedActivityStates.get(t)?.isManuallySkipped&&!o.values?.[M.ManuallySkipped]){console.debug(`[${n}] Ignoring FF update for ${t} â locally ManuallySkipped but server response is not`),h(()=>
1this._pendingPlannedActivityFlushForwardUpdates.delete(t));return}h(()=>{this._idsExcludedFromSwap.delete(t),this.plannedActivitySaved(o),this._pendingPlannedActivityFlushForwardUpdates.delete(t)}),this._reconcileScheduler?.notifyProgress()}catch(e){console.error(`[${n}] Error handling PA flush forward complete for ${t}:`,e),h(()=>this._pendingPlannedActivityFlushForwardUpdates.delete(t))}},this.handleFlushForwardWalkComplete=async e=>{if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let{owner:t}=e,n=this._flushForwardOwner,r=n===null||n===t;r||console.debug(`[${t}] Healing stranded pending on walk complete from foreign owner (tracking ${this._flushForwardOwner})`),console.debug(`[${t}] Flush forward walk complete`);let i=this.flushForwardPendingActivityIds,a=await this.refetchAndClearPending(i),o=r&&this._flushForwardOwner===n;this.hideFailureToast(),h(()=>{if(a)for(let e of i)this._pendingPlannedActivityFlushForwardUpdates.delete(e);o&&(a&&this._pendingFitnessThresholdProjectionIds.clear(),this._flushForwardOwner=null,this._currentFlushForwardDate=null,this._lastUpdatedPlannedActivityId=null)}),this.calendarData.clearAdminFtpRanges(),o&&a&&!this._deferredFlushForwardPending&&this._reconcileScheduler?.clearQuietTimer()},this.handleFlushForwardV2Complete=async e=>{if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let t=this._flushForwardOwner,n=this._failureToastId;if(await this.revealSettled(),this._flushForwardOwner!==t){console.debug(`[${e.owner}] Ignoring flush forward v2 complete: the tracked walk became ${this._flushForwardOwner??`none`} while the reveal drained`);return}let{owner:r,params:i}=e,a=this._flushForwardOwner,o=a===null||a===r;console.debug(`[${r}] Flush forward v2 complete`,i.plannedActivityIds.length,`rows changed`);let s=[...this._pendingPlannedActivityFlushForwardUpdates].filter(e=>!this._cohortHoldIds.has(e));if(e.apiData==null){console.debug(`[${r}] ApiData missing for flush forward v2 complete; refetching pending rows`);let e=o?[...this._provisionalPlannedActivityIds].filter(e=>!s.includes(e)):[],t=await this.refetchAndClearPending([...s,...e]),n=o&&this._flushForwardOwner===a;h(()=>{if(t)for(let e of s)this._pendingPlannedActivityFlushForwardUpdates.delete(e);n&&t&&(this.applyDayColors(i.dayColors,i.from,i.to),this.revertProvisionalFitnessThresholds(),this._pendingFitnessThresholdProjectionIds.clear(),this._provisionalPlannedActivityIds.clear(),this._flushForwardOwner=null,this._currentFlushForwardDate=null,this._lastUpdatedPlannedActivityId=null)}),this.hideFailureToast(),this.calendarData.clearAdminFtpRanges(),n&&t&&this._reconcileScheduler?.clearQuietTimer();return}let c=o,l=new Set((e.apiData??[]).map(e=>e.id)),u=c?[...this._provisionalPlannedActivityIds].filter(e=>!l.has(e)&&!s.includes(e)&&!this._cohortHoldIds.has(e)):[],d=await this.refetchAndClearPending(u);if(h(()=>{for(let t of e.apiData??[])if(!this._cohortHoldIds.has(t.id)){if(this.calendarData.plannedActivityStates.get(t.id)?.isManuallySkipped&&!t.values?.[M.ManuallySkipped]){console.debug(`[${r}] Ignoring FF update for ${t.id} â locally ManuallySkipped but server response is not`);continue}this._idsExcludedFromSwap.delete(t.id),this.plannedActivitySaved(t)}for(let e of s)this._pendingPlannedActivityFlushForwardUpdates.delete(e);c&&(this.applyDayColors(i.dayColors,i.from,i.to),this._provisionalFitnessThresholds.clear(),this._pendingFitnessThresholdProjectionIds.clear(),d&&this._provisionalPlannedActivityIds.clear(),this._flushForwardOwner=null,this._currentFlushForwardDate=null,this._lastUpdatedPlannedActivityId=null)}),this._failureToastId===n&&this.hideFailureToast(),this.calendarData.clearAdminFtpRanges(),c&&this._reconcileScheduler?.clearQuietTimer(),!o){let t=new Set((e.apiData??[]).map(e=>e.id)),n=s.filter(e=>!t.has(e));n.length>0&&await this.refetchAndClearPending(n)}},this.handleFlushForwardV2Answered=e=>{if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let{owner:t,params:n}=e,r=this._flushForwardOwner;if(r!==null&&r!==t){console.debug(`[${t}] Ignoring flush forward v2 answer from foreign owner (tracking ${r})`);return}console.debug(`[${t}] Flush forward v2 answered`,n.rows.length,`rows`);let i=this.dateTimeService.fromDateOnly(n.from),a=this.dateTimeService.fromDateOnly(n.to),o=e=>{let t=this.dateTimeService.fromDateOnly(e);return T(i,t)&&T(t,a)},s=new Map,c=e=>{let t=s.get(e);if(t!=null)return t;let n={dateKey:e,rows:[],pendingIds:[],dayColor:null,aiFtp:null};return s.set(e,n),n};for(let e of n.rows)c(w(e.date)).rows.push(e);for(let e of[...this._pendingPlannedActivityFlushForwardUpdates]){if(this._cohortHoldIds.has(e))continue;let t=this.calendarData.plannedActivities.get(e)?.date??this.calendarData.plannedActivityStates.get(e)?.date;
1t!=null&&o(t)&&c(w(t)).pendingIds.push(e)}for(let e of n.aiFtp??[])c(w(e.date)).aiFtp=e;let l=n.dayColors.length>0;if(l)for(let e of n.dayColors)c(e.date).dayColor=e;l&&h(()=>this.clearDayColorsInWindow(n.from,n.to));let u=[...s.keys()].sort();this.startReveal(u.map(e=>()=>this.revealDate(t,s.get(e))),u),this._reconcileScheduler?.notifyProgress()},this.revealDate=(e,t)=>{this._revealPendingDateKeys.delete(t.dateKey);for(let n of t.rows){if(this._cohortHoldIds.has(n.id))continue;let t=this.calendarData.plannedActivities.get(n.id);if(t!=null){if(this.calendarData.plannedActivityStates.get(n.id)?.isManuallySkipped){console.debug(`[${e}] Ignoring provisional FF row for ${n.id} â locally ManuallySkipped`);continue}this._idsExcludedFromSwap.delete(n.id),this.plannedActivitySaved(ae(t,n)),this._provisionalPlannedActivityIds.add(n.id),this._pendingPlannedActivityFlushForwardUpdates.delete(n.id)}}for(let e of t.pendingIds)this._cohortHoldIds.has(e)||this._pendingPlannedActivityFlushForwardUpdates.delete(e);this.revealAiFtp(e,t.dateKey,t.aiFtp?.watts??null),t.dayColor!=null&&t.dayColor.color!==k.Green&&this.calendarData.rlglStatus.set(t.dayColor.date,t.dayColor)},this.revealAiFtp=(e,t,n)=>{let r=this.calendarData.allFitnessThresholdProjections.get(t);if(!(r==null||!this._pendingFitnessThresholdProjectionIds.has(r.id))){if(!this._revealHeldFitnessThresholdIds.delete(r.id)){if(n==null)return;let i=this.calendarData.fitnessThresholdStatesMap.get(r.id);if(i==null){console.debug(`[${e}] Ignoring provisional FF AI FTP for ${t} - no loaded projection row`);return}this._provisionalFitnessThresholds.set(r.id,i),this.calendarData.ftpUpdateAdded({...i,value:n})}this.calendarData.clearAdminFtpRanges(t),this._pendingFitnessThresholdProjectionIds.delete(r.id)}},this.revertProvisionalFitnessThresholds=()=>{if(this._provisionalFitnessThresholds.size!==0){for(let e of this._provisionalFitnessThresholds.values())this.calendarData.ftpUpdateAdded(e);this._provisionalFitnessThresholds.clear(),this.calendarData.clearAdminFtpRanges()}},this._revealSteps=[],this._revealPendingDateKeys=new Set,this._revealDrained=[],this._revealStepMs=100,this._revealTimer=null,this.startReveal=(e,t=[])=>{if(this.applyRemainingSteps(),e.length===0){this.settleRevealWaiters();return}this._revealSteps=e,this._revealPendingDateKeys=new Set(t),this._revealStepMs=Math.max(1,Math.min(100,Math.round(ie/e.length))),this.runRevealStep()},this.runRevealStep=()=>{let e=this._revealSteps.shift();if(e===void 0){this._revealTimer=null,this.settleRevealWaiters();return}this._revealTimer=this._revealSteps.length>0?setTimeout(this.runRevealStep,this._revealStepMs):null;try{h(e)}catch(e){console.error(`Error painting a flush forward reveal step`,e)}finally{this._revealSteps.length===0&&this.settleRevealWaiters()}},this.revealSettled=()=>this._revealSteps.length===0&&this._revealTimer===null?Promise.resolve():new Promise(e=>this._revealDrained.push(e)),this.settleRevealWaiters=()=>{let e=this._revealDrained;this._revealDrained=[];for(let t of e)t()},this.flushReveal=()=>{this.applyRemainingSteps(),this.settleRevealWaiters()},this.applyRemainingSteps=()=>{this.clearRevealTimer();let e=this._revealSteps;this._revealSteps=[],e.length!==0&&h(()=>{for(let t of e)t()})},this.cancelReveal=()=>{this.clearRevealTimer(),this._revealSteps=[],this._revealPendingDateKeys.clear(),this._revealHeldFitnessThresholdIds.clear(),this.settleRevealWaiters()},this.clearRevealTimer=()=>{this._revealTimer!==null&&(clearTimeout(this._revealTimer),this._revealTimer=null)},this.clearDayColorsInWindow=(e,t)=>{let n=this.dateTimeService.fromDateOnly(e),r=this.dateTimeService.fromDateOnly(t);for(let e of[...this.calendarData.rlglStatus.keys()]){let t=this.dateTimeService.fromDateOnly(f(e));T(n,t)&&T(t,r)&&this.calendarData.rlglStatus.delete(e)}},this.applyDayColors=(e,t,n)=>{if(e.length!==0){this.clearDayColorsInWindow(t,n);for(let t of e)t.color===k.Green?this.calendarData.rlglStatus.delete(t.date):this.calendarData.rlglStatus.set(t.date,t)}},this.plannedActivitySaved=e=>{this.calendarData.plannedActivityStates.set(e.id,new a(c(e),this.calendarData)),this.calendarData.plannedActivities.set(e.id,e),this._lastUpdatedPlannedActivityId=e.id},this.handleRedLightGreenLightStatusUpdate=e=>{if(this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing){console.log(`Local flush forward processing is disabled by admin setting`);return}let t=e.params.date;if(this._flushForwardOwner!==e.owner){console.debug(`[${e.owner}] Ignoring RLGL status update as another owner is active`);return}if(this._currentFlushForwardDate!==null&&r(this._currentFlushForwardDate,f(t))){console.debug(`[${e.owner}] Ignoring RLGL status update as the date is after the current flush forward date: ${i(this._currentFlushForwardDate)}(current) -> ${t}(update)`);return}console.debug(`[${e.owner}] RLGL status update for ${t}`,e.params),e.params.color===k.Green?this.calendarData.rlglStatus.delete(t):this.calendarData.rlglStatus.set(t,e.params)},this.handleFitnessThresholdAddedOrUpdated=e=>{let{id:t,date:n,isEnabled:r,isApplied:i,isLowConfidence:a,parentId:o,source:s,type:c,value:l,viewed:u}=e.params;console.debug(`Fitness threshold ${e.name}: id=${t}, value=${l}, source=${s}, isEnabled=${r}`);let d=s===A.AiFtp3Prediction||s===A.AiFtp1Prediction||s===A.AiFtp3Breakthrough,f=d?this.dateTimeService.fromServer(n).setZone(this.calendarData.tz).toISODate():null;f&&this.calendarData.clearAdminFtpRanges(f),d&&t>
10&&(l===0?(this._pendingFitnessThresholdProjectionIds.add(t),this.calendarData.adminSettings?.unsentSessionSettings?.disableLocalFlushForwardProcessing||this._reconcileScheduler?.armQuietTimer()):f!=null&&this._revealPendingDateKeys.has(f)&&this._pendingFitnessThresholdProjectionIds.has(t)?this._revealHeldFitnessThresholdIds.add(t):this._pendingFitnessThresholdProjectionIds.delete(t)),c===V.FtpChange?(this.calendarData.ftpUpdateAdded({id:t,date:n,isEnabled:r,source:s,value:l,isApplied:i,viewed:u}),(s===A.RampTestResult||o!==null&&i&&this.calendarData.pendingAiFtpChange?.id===o)&&this.calendarData.setPendingAiFtpChange(null)):c===V.ViewedAiFtpDetection&&s!==A.AiFtp3HardFail&&this.calendarData.setPendingAiFtpChange({id:t,date:n,isLowConfidence:a,levels:null,value:l,source:s})},this.handleFitnessThresholdDeleted=e=>{let{id:t}=e.params;console.debug(`Fitness threshold deleted: id=${t}`),this.calendarData.ftpUpdateDeleted(t),this.calendarData.clearAdminFtpRanges()},g(this)}get lastUpdatedPlannedActivityId(){return this._lastUpdatedPlannedActivityId}get idsExcludedFromSwap(){if(this._cohortHoldIds.size===0)return this._idsExcludedFromSwap;let e=new Set(this._idsExcludedFromSwap);for(let t of this._cohortHoldIds)e.add(t);return e}get pendingFitnessThresholdProjectionIds(){return this._pendingFitnessThresholdProjectionIds}get flushForwardOwner(){return this._flushForwardOwner}get progressUnavailable(){return this._progressDeniedMemberId!==null&&this._progressDeniedMemberId===(this.memberService.memberInfo?.memberId??null)}get hasPendingFlushForward(){if(this.progressUnavailable)return!1;if(this._flushForwardOwner!==null||this._deferredFlushForwardPending||this._pendingFitnessThresholdProjectionIds.size>0||this._provisionalFitnessThresholds.size>0||this._provisionalPlannedActivityIds.size>0)return!0;for(let e of this._pendingPlannedActivityFlushForwardUpdates)if(!this._cohortHoldIds.has(e))return!0;return!1}get flushForwardPendingActivityIds(){return[...this._pendingPlannedActivityFlushForwardUpdates].filter(e=>!this._cohortHoldIds.has(e))}get calendarData(){return this.athleteData.calendarData}get pending(){return{plannedActivities:this._pendingPlannedActivityFlushForwardUpdates}}flushForward(e,t,n={force:!1,excludedIds:[],idsExcludedFromSwap:[]}){let{force:a=!1,excludedIds:o=[],idsExcludedFromSwap:s=[]}=n;console.debug(`[${t}] Flush forward from ${i(e)}`);let c=r(e,this.calendarData.today)?this.calendarData.today:this.dateTimeService.fromDateOnly(e),l=c,d=this.calendarData.endOfAiWindow;if(!(a||this._currentFlushForwardDate===null||this._flushForwardOwner===null||r(l,this._currentFlushForwardDate)||this._flushForwardOwner!==t&&u(l,this._currentFlushForwardDate))){console.debug(`[${t}] Flush forward already processed up to ${i(l)}`);return}this.cancelReveal(),this._idsExcludedFromSwap=new Set(s);let f=this._flushForwardOwner!==t;for(this._flushForwardOwner!==t&&(this._lastUpdatedPlannedActivityId=null,this._pendingFitnessThresholdProjectionIds.clear(),this._pendingPlannedActivityFlushForwardUpdates.clear(),this._provisionalPlannedActivityIds.clear(),this._provisionalFitnessThresholds.clear()),this._flushForwardOwner=t,this._currentFlushForwardDate=C(l);T(l,d);)this.addPendingStatesForDate(l,u(e,l)?!1:f,{excludedIds:o}),l=l.plus({days:1});return this._reconcileScheduler?.armQuietTimer(),C(c)}get currentFlushForwardDate(){return this._currentFlushForwardDate}addPendingStatesForDate(e,t,{excludedIds:n}){let r=i(e),a=i(this.calendarData.today);if(this.calendarData.plannedActivityStates.items.length===0&&this.calendarData.events.items.length===0&&this.calendarData.allFitnessThresholdProjections.has(r)){console.warn(`No planned activities loaded, cannot add pending states for date`);return}if(this.calendarData.allFitnessThresholdProjections.has(r)){let e=!0,t=this.calendarData.allFitnessThresholdProjections.get(r);r===a&&t?.value!=null&&(e=!1),e&&t?.id&&this._pendingFitnessThresholdProjectionIds.add(t.id)}if(!this.calendarData.hiatusDays.has(r)){let e=this.calendarData.plannedActivityStates.getItemsForDay(r).filter(te).filter(e=>!n.includes(e.id));
1for(let t of e)this._pendingPlannedActivityFlushForwardUpdates.add(t.id)}t&&this.calendarData.rlglStatus.delete(r)}};S([m,x(`design:type`,Object)],$.prototype,`_lastUpdatedPlannedActivityId`,void 0),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`lastUpdatedPlannedActivityId`,null),S([m,x(`design:type`,Object)],$.prototype,`_idsExcludedFromSwap`,void 0),S([m,x(`design:type`,Object)],$.prototype,`_cohortHoldIds`,void 0),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`idsExcludedFromSwap`,null),S([v,x(`design:type`,Object)],$.prototype,`setCohortHold`,void 0),S([v,x(`design:type`,Object)],$.prototype,`clearCohortHold`,void 0),S([m,x(`design:type`,Object)],$.prototype,`_pendingFitnessThresholdProjectionIds`,void 0),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`pendingFitnessThresholdProjectionIds`,null),S([m,x(`design:type`,Object)],$.prototype,`_flushForwardOwner`,void 0),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`flushForwardOwner`,null),S([m,x(`design:type`,Object)],$.prototype,`_deferredFlushForwardPending`,void 0),S([m,x(`design:type`,Object)],$.prototype,`_progressDeniedMemberId`,void 0),S([_,x(`design:type`,Boolean),x(`design:paramtypes`,[])],$.prototype,`progressUnavailable`,null),S([_,x(`design:type`,Boolean),x(`design:paramtypes`,[])],$.prototype,`hasPendingFlushForward`,null),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`calendarData`,null),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`pending`,null),S([v,x(`design:type`,Object)],$.prototype,`adminFlushFromHere`,void 0),S([v,x(`design:type`,Function),x(`design:paramtypes`,[Object,String,Object]),x(`design:returntype`,void 0)],$.prototype,`flushForward`,null),S([m,x(`design:type`,Object)],$.prototype,`_pendingPlannedActivityFlushForwardUpdates`,void 0),S([m,x(`design:type`,Object)],$.prototype,`_provisionalPlannedActivityIds`,void 0),S([m,x(`design:type`,Object)],$.prototype,`_provisionalFitnessThresholds`,void 0),S([m,x(`design:type`,Object)],$.prototype,`_currentFlushForwardDate`,void 0),S([_,x(`design:type`,Object),x(`design:paramtypes`,[])],$.prototype,`currentFlushForwardDate`,null),S([v,x(`design:type`,Function),x(`design:paramtypes`,[Object,Boolean,Object]),x(`design:returntype`,void 0)],$.prototype,`addPendingStatesForDate`,null),S([v,x(`design:type`,Object)],$.prototype,`handleFlushForwardOwnerChanged`,void 0),S([v,x(`design:type`,Object)],$.prototype,`handleFlushForwardStatusMessage`,void 0),S([v,x(`design:type`,Object)],$.prototype,`handleFlushForwardPlannedActivityComplete`,void 0),S([v,x(`design:type`,Object)],$.prototype,`plannedActivitySaved`,void 0),S([v,x(`design:type`,Object)],$.prototype,`handleRedLightGreenLightStatusUpdate`,void 0),S([v,x(`design:type`,Object)],$.prototype,`handleFitnessThresholdAddedOrUpdated`,void 0),S([v,x(`design:type`,Object)],$.prototype,`handleFitnessThresholdDeleted`,void 0),$=S([e(),I(0,t(D)),I(1,t(E)),I(2,t(d)),I(3,t(n)),I(4,t(R)),x(`design:paramtypes`,[typeof(J=D!==void 0&&D)==`function`?J:Object,typeof(Y=E!==void 0&&E)==`function`?Y:Object,typeof(X=d!==void 0&&d)==`function`?X:Object,typeof(Z=n!==void 0&&n)==`function`?Z:Object,typeof(Q=R!==void 0&&R)==`function`?Q:Object])],$);export{q as n,$ as t}; 2//# sourceMappingURL=flush-forward-state-manager-h9o7l8gx.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.