1var J=Object.defineProperty;var Q=(f,e,t)=>e in f?J(f,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):f[e]=t;var x=(f,e,t)=>Q(f,typeof e!="symbol"?e+"":e,t);import{S as U,M as X,V as Y,f as Z}from"./chunkReloadRecoveryC4XyrbqR.js";import{e as z,j as D,G as b,k as $,l as G,m as K,o as O,q as V}from"./OperationQueueDV3oPNrt.js";import{T as N}from"./TaskCompletionRefStateServiceDdf6mDfD.js";import{T as E}from"./TaskItemServicebcTJdb3h.js";import"./vue-runtimeBcw72k-n.js";import"./cjs-helpersC4iS2aBk.js";import"./bootstrap-vue-nextD6HU9H8G.js";import"./dexie2jmnBxhj.js";import"./item-name.utilsCH3lkmjj.js";import"./item.typesx7Q7rrX9.js";import"./content.typesCQ2lHcy0.js";import"./constantsDsHwd9pV.js";import"./extraction.pure.utilsDQPW8yIh.js";import"./url.utilsCetgXmY_.js";import"./refStateBatchSupportMYTqvJH3.js";import"./ItemService6OxqWBM_.js";import"./noteAttachmentCnCPBIlX.js";import"./file_utilsBz4gEirg.js";import"./freshSignInBREx9Dbx.js";import"./textEmbeddingUtilsMpr6oSwV.js";import"./searchContentKindsBCsa2n8P.js";import"./feedback.utilscwcZGi10.js";import"./feedDiscoveryCsjZq3pR.js";import"./itemImageSourcesB5F3pjKY.js";import"./search-provider.utilsCsDdSKl9.js";import"./statusFacetsB0tsuUpJ.js";import"./browseFacets8dSOpUAG.js";import"./rolloutCapsCGgnGdEe.js";import"./libraryWriteGuardsCy3HE0P2.js";import"./restrictedSiteAccessWarning.utilsBXR3LbfE.js";function R(){var f,e;try{return((e=(f=globalThis==null?void 0:globalThis.localStorage)==null?void 0:f.getItem)==null?void 0:e.call(f,"debug.taskCompletion"))==="true"}catch{return!1}}function _(...f){(Y||R())&&Z("[TASK_COMPLETION]",...f)}const L=class L{static get instance(){return this._staticInstance||(this._staticInstance=new L),this._staticInstance}async getAccountId(){const e=await U.instance.getCurrentUser();if(!(e!=null&&e.accountId))throw new Error("TaskService: no accountId");return e.accountId}async getTaskStore(){const e=await this.getAccountId();return z.getValueStore("account:tasks",e)}async getCompletionStore(){const e=await this.getAccountId();return z.getValueStore("account:taskCompletions",e)}async useItemBackedTasks(){return!await X()}async fetchCompletionsForTasks(e){const t=[],s=[];for(const d of e.tasks)D({viewerType:e.viewerType??"",forUserId:e.forUserId,task:d})===b?t.push(d.taskId):s.push(d.taskId);const o=e.viewerType==="admin"?e.forUserId:void 0,[r,n]=await Promise.all([t.length?N.instance.listCompletionsForTasks({taskIds:t,ownerId:b,occurrenceStartMsGte:e.occurrenceStartMsGte,occurrenceStartMsLte:e.occurrenceStartMsLte}):Promise.resolve(new Map),s.length?N.instance.listCompletionsForTasks({taskIds:s,ownerId:o,occurrenceStartMsGte:e.occurrenceStartMsGte,occurrenceStartMsLte:e.occurrenceStartMsLte}):Promise.resolve(new Map)]),l=new Map;for(const d of[r,n])for(const[w,T]of d)l.set(w,T);return l}async getTaskByIdOrNull(e){if(!e)return null;if(!await this.useItemBackedTasks())return(await(await this.getTaskStore()).get("all")||[]).find(n=>(n==null?void 0:n.taskId)===e)||null;const t=await E.instance.getTaskById({taskId:e});return(t==null?void 0:t.task)||null}async listVisibleActiveTasksForUser(e){return await this.useItemBackedTasks()?(await this.listTasks({assignedToUserId:e.userId,includeArchived:!1})).tasks||[]:e.viewer.type==="restricted"&&e.viewer._id===e.userId?((await this.listTasks({includeArchived:!1})).tasks||[]).filter(r=>{const n=(r.assignedUserIds||[]).includes(e.userId),l=r.visibleToRestricted===!0;return n||l}):(await this.listTasks({assignedToUserId:e.userId,includeArchived:!1})).tasks||[]}async listTasks(e){if(!await this.useItemBackedTasks()){let r=await(await this.getTaskStore()).get("all")||[];return e.includeArchived||(r=r.filter(n=>n.status!=="archived")),e.assignedToUserId&&(r=r.filter(n=>(n.assignedUserIds||[]).includes(e.assignedToUserId))),{tasks:r}}const t=await U.instance.getCurrentUser();if(!(t!=null&&t._id))throw new Error("TaskService: not signed in");if(e.assignedToUserId){if(t._id!==e.assignedToUserId&&t.type!=="admin")throw new Error("Not permitted to view tasks for this user");if(t.type==="admin"&&t._id!==e.assignedToUserId){let s={tasks:[]};try{s=await E.instance.listAssignedTasks({userId:e.assignedToUserId,includeArchived:e.includeArchived})}catch{}let o={tasks:[]};try{o=await E.instance.listTasksAssignedToUserAsAdmin({assignedUserId:e.assignedToUserId,includeArchived:e.includeArchived})}catch{}const r=new Map;for(const n of[...s.tasks||[],...o.tasks||[]])n!=null&&n.taskId&&r.set(n.taskId,n);return{tasks:Array.from(r.values())}}return await E.instance.listAssignedTasks({userId:e.assignedToUserId,includeArchived:e.includeArchived})}return t.type==="admin"?await E.instance.listOwnedTasks({userId:t._id,includeArchived:e.includeArchived}):await E.instance.listAssignedTasks({userId:t._id,includeArchived:e.includeArchived})}async upsertTask(e){if(!await this.useItemBackedTasks()){const t=await this.getTaskStore(),r=[...await t.get("all")||[]],n=r.findIndex(l=>l.taskId===e.task.taskId);return n>=0?r[n]=e.task:r.push(e.task),await t.set("all",r),{task:e.task}}return await E.instance.upsertTaskItem({task:e.task})}async archiveTask(e){if(!await this.useItemBackedTasks()){const s=await this.getTaskStore(),r=await s.get("all")||[],n=e.archived?"archived":"active",l=r.map(d=>d.taskId!==e.taskId?d:{...d,status:n,updatedAt:Date.now()});return await s.set("all",l),{success:!0}}const t=await this.getTaskByIdOrNull(e.taskId);if(!t)throw new Error("Task not found");return await this.upsertTask({task:{...t,status:e.archived?"archived":"active",updatedAt:Date.now()}}),{success:!0}}async completeTask(e){var n,l,d,w,T,M;if(!await this.useItemBackedTasks()){const I=await this.getCompletionStore(),y=await this.getTaskByIdOrNull(e.completion.taskId),S=(y==null?void 0:y.completionScope)==="once"?b:e.completion.userId,g=`${e.completion.taskId}:${S}:${e.completion.occurrenceStartMs}`;return await I.set(g,e.completion),{completion:e.completion}}const t=await U.instance.getCurrentUser();if(!(t!=null&&t._id))throw new Error("TaskService: not signed in");if(t._id!==e.completion.userId&&t.type!=="admin")throw new Error("Not permitted to complete tasks for this user");const s=await this.getTaskByIdOrNull(e.completion.taskId);if(!s)throw new Error("Task not found");const o=D({viewerType:t.type,forUserId:e.completion.userId,task:s});_("completeTask: request",{viewerId:t._id,viewerType:t.type,taskId:e.completion.taskId,completingForUserId:e.completion.userId,ownerIdUsed:o,occurrenceStartMs:e.completion.occurrenceStartMs,completedAtMs:e.completion.completedAtMs,completedBy:e.completion.completedBy,hasNote:typeof e.completion.note=="string"&&e.completion.note.length>0,noteLen:typeof e.completion.note=="string"?e.completion.note.length:0});const r=await N.instance.upsertCompletion({taskId:e.completion.taskId,ownerId:o,occurrenceStartMs:e.completion.occurrenceStartMs,completed:!0,completionStatus:"completed",completedAtMs:e.completion.completedAtMs,completedByRole:e.completion.completedBy,note:e.completion.note,evidenceSummary:e.completion.evidenceSummary});return _("completeTask: upsertResp",{entryId:(n=r==null?void 0:r.entry)==null?void 0:n._id,entryOwnerId:(l=r==null?void 0:r.entry)==null?void 0:l.ownerId,entryStateSubKey:(d=r==null?void 0:r.entry)==null?void 0:d.stateSubKey,entryUpdatedAt:(w=r==null?void 0:r.entry)==null?void 0:w.updatedAt,entryEncrypted:(T=r==null?void 0:r.entry)==null?void 0:T.encrypted,entryDataKeys:Object.keys(((M=r==null?void 0:r.entry)==null?void 0:M.data)||{})}),{completion:e.completion}}async skipTaskOccurrence(e){const t=await this.getTaskByIdOrNull(e.completion.taskId);if(!t)throw new Error("Task not found");if(!t.recurrence||t.recurrence.type==="none")throw new Error("Only recurring tasks can be skipped");const s={...e.completion,status:"skipped"};if(!await this.useItemBackedTasks()){const n=await this.getCompletionStore(),l=(t==null?void 0:t.completionScope)==="once"?b:s.userId,d=`${s.taskId}:${l}:${s.occurrenceStartMs}`;return await n.set(d,s),{completion:s}}const o=await U.instance.getCurrentUser();if(!(o!=null&&o._id))throw new Error("TaskService: not signed in");if(o._id!==s.userId&&o.type!=="admin")throw new Error("Not permitted to skip tasks for this user");const r=D({viewerType:o.type,forUserId:s.userId,task:t});return _("skipTaskOccurrence: request",{viewerId:o._id,viewerType:o.type,taskId:s.taskId,skippingForUserId:s.userId,ownerIdUsed:r,occurrenceStartMs:s.occurrenceStartMs,completedAtMs:s.completedAtMs}),await N.instance.upsertCompletion({taskId:s.taskId,ownerId:r,occurrenceStartMs:s.occurrenceStartMs,completed:!0,completionStatus:"skipped",completedAtMs:s.completedAtMs,completedByRole:s.completedBy,note:s.note,evidenceSummary:s.evidenceSummary,completionData:{action:"skipped"}}
1),{completion:s}}async snoozeTask(e){const t=typeof e.snoozeMs=="number"&&Number.isFinite(e.snoozeMs)&&e.snoozeMs>0?Math.round(e.snoozeMs):864e5;if(!await this.useItemBackedTasks()){const w=await this.getTaskStore(),M=await w.get("all")||[],I=M.find(u=>u.taskId===e.taskId);if(!I)throw new Error("Task not found");const y=I==null?void 0:I.recurrence;if(y&&y.type!=="none")throw new Error("Only non-recurring tasks can be snoozed");if(typeof I.dueAtMs!="number"||!Number.isFinite(I.dueAtMs))throw new Error("Task has no due date to snooze");const g=Math.max(Date.now(),I.dueAtMs)+t,v=M.map(u=>u.taskId!==e.taskId?u:{...u,dueAtMs:g,updatedAt:Date.now()});return await w.set("all",v),{task:v.find(u=>u.taskId===e.taskId)}}const s=await U.instance.getCurrentUser();if(!(s!=null&&s._id))throw new Error("TaskService: not signed in");const o=await this.getTaskByIdOrNull(e.taskId);if(!o)throw new Error("Task not found");if(s.type!=="admin"&&s._id!==o.createdByUserId)throw new Error("Not permitted to snooze this task");const r=o==null?void 0:o.recurrence;if(r&&r.type!=="none")throw new Error("Only non-recurring tasks can be snoozed");if(typeof o.dueAtMs!="number"||!Number.isFinite(o.dueAtMs))throw new Error("Task has no due date to snooze");const l=Math.max(Date.now(),o.dueAtMs)+t;return{task:(await this.upsertTask({task:{...o,dueAtMs:l,updatedAt:Date.now()}})).task}}async uncompleteTask(e){if(!await this.useItemBackedTasks()){const r=await this.getCompletionStore(),n=await this.getTaskByIdOrNull(e.taskId),l=(n==null?void 0:n.completionScope)==="once"?b:e.userId,d=`${e.taskId}:${l}:${e.occurrenceStartMs}`;return await r.invalidate(d),{success:!0}}const t=await U.instance.getCurrentUser();if(!(t!=null&&t._id))throw new Error("TaskService: not signed in");if(t._id!==e.userId&&t.type!=="admin")throw new Error("Not permitted to uncomplete tasks for this user");const s=await this.getTaskByIdOrNull(e.taskId);if(!s)throw new Error("Task not found");const o=D({viewerType:t.type,forUserId:e.userId,task:s});return _("uncompleteTask: request",{viewerId:t._id,viewerType:t.type,taskId:e.taskId,uncompletingForUserId:e.userId,ownerIdUsed:o,occurrenceStartMs:e.occurrenceStartMs}),await N.instance.upsertCompletion({taskId:e.taskId,ownerId:o,occurrenceStartMs:e.occurrenceStartMs,completed:!1,completedByRole:t.type==="admin"?"admin":"child",note:void 0}),{success:!0}}async listStatus(e){var T,M,I,y,S,g,v,C;const t=e.nowMs??Date.now(),s=await U.instance.getCurrentUser();if(!(s!=null&&s._id))throw new Error("TaskService: not signed in");if(s._id!==e.userId&&s.type!=="admin")throw new Error("Not permitted to view tasks for this user");_("listStatus: start",{viewerId:s._id,viewerType:s.type,forUserId:e.userId,nowMs:t});const o=await this.listVisibleActiveTasksForUser({viewer:s,userId:e.userId});if(!await this.useItemBackedTasks()){const u=await this.getCompletionStore(),h=[];for(const a of o){const i=$({task:a,nowMs:t}),m=G({task:a,occurrenceStartMs:i}),A=(a==null?void 0:a.completionScope)==="once"?b:e.userId,c=`${a.taskId}:${A}:${i}`,p=await u.get(c),k=!!p,B=k?(p==null?void 0:p.status)==="skipped"?"skipped":"completed":void 0,q=p==null?void 0:p.completedAtMs,j=p==null?void 0:p.note,W=p==null?void 0:p.userId,H=!k&&typeof m=="number"?t>m:!1;h.push({task:a,occurrenceStartMs:i,completed:k,completionStatus:B,completionAtMs:q,completionNote:j,completedByUserId:W,dueAtMs:m,overdue:H})}return{nowMs:t,due:h}}const r=new Map;for(const u of o)r.set(u.taskId,$({task:u,nowMs:t}));const n=Array.from(r.values()),l=await this.fetchCompletionsForTasks({tasks:o,viewerType:s.type,forUserId:e.userId,occurrenceStartMsGte:n.length?Math.min(...n):void 0,occurrenceStartMsLte:n.length?Math.max(...n):void 0}),d=new Map;for(const u of o){const h=r.get(u.taskId),a=l.get(u.taskId);d.set(u.taskId,h===void 0||a==null?void 0:a.get(h))}const w=[];for(const u of o){const h=$({task:u,nowMs:t}),a=G({task:u,occurrenceStartMs:h}),i=d.get(u.taskId),m=i?((T=i==null?void 0:i.data)==null?void 0:T.completed)===!0||((M=i==null?void 0:i.data)==null?void 0:M.completed)==null:!1,A=m?((I=i==null?void 0:i.data)==null?void 0:I.completionStatus)==="skipped"||((S=(y=i==null?void 0:i.data)==null?void 0:y.completionData)==null?void 0:S.action)==="skipped"?"skipped":"completed":void 0,c=typeof((g=i==null?void 0:i.data)==null?void 0:g.completedAtMs)=="number"?i.data.completedAtMs:void 0,p=typeof((v
1=i==null?void 0:i.data)==null?void 0:v.note)=="string"?i.data.note:void 0,k=typeof((C=i==null?void 0:i.data)==null?void 0:C.completedByUserId)=="string"?i.data.completedByUserId:void 0,B=!m&&typeof a=="number"?t>a:!1;w.push({task:u,occurrenceStartMs:h,completed:m,completionStatus:A,completionAtMs:c,completionNote:p,completedByUserId:k,dueAtMs:a,overdue:B}),m||_("listStatus: noMatchForOccurrence",{taskId:u.taskId,computedOccurrenceStartMs:h,hasCompletionEntry:!!i})}return{nowMs:t,due:w}}async listOccurrencesByRange(e){var I,y,S,g,v,C,u,h;if(!Number.isFinite(e.startMs)||!Number.isFinite(e.endMs)||e.endMs<=e.startMs)throw new Error("TaskService.listOccurrencesByRange: invalid range");const t=e.nowMs??Date.now(),s=e.includeCompleted!==!1,o=await U.instance.getCurrentUser();if(!(o!=null&&o._id))throw new Error("TaskService: not signed in");if(o._id!==e.userId&&o.type!=="admin")throw new Error("Not permitted to view tasks for this user");const r=await this.listVisibleActiveTasksForUser({viewer:o,userId:e.userId}),n=[];if(!await this.useItemBackedTasks()){const a=await this.getCompletionStore();for(const i of r){const m=K({task:i,startMs:e.startMs,endMs:e.endMs}),A=(i==null?void 0:i.completionScope)==="once"?b:e.userId;for(const c of m){const p=`${i.taskId}:${A}:${c}`,k=await a.get(p),B=!!k;!s&&B||n.push(O({task:i,userId:e.userId,occurrenceStartMs:c,completed:B,completionStatus:B?(k==null?void 0:k.status)==="skipped"?"skipped":"completed":void 0,completionAtMs:k==null?void 0:k.completedAtMs,completionNote:k==null?void 0:k.note,completedByUserId:k==null?void 0:k.userId,nowMs:t}))}}return n.sort(V),{nowMs:t,occurrences:n}}const l=new Map;let d,w;for(const a of r){const i=K({task:a,startMs:e.startMs,endMs:e.endMs});if(i.length!==0){l.set(a.taskId,i);for(const m of i)(d===void 0||m<d)&&(d=m),(w===void 0||m>w)&&(w=m)}}const T=r.filter(a=>l.has(a.taskId)),M=await this.fetchCompletionsForTasks({tasks:T,viewerType:o.type,forUserId:e.userId,occurrenceStartMsGte:d,occurrenceStartMsLte:w});for(const a of T){const i=l.get(a.taskId)||[],m=M.get(a.taskId);for(const A of i){const c=m==null?void 0:m.get(A),p=c?((I=c==null?void 0:c.data)==null?void 0:I.completed)===!0||((y=c==null?void 0:c.data)==null?void 0:y.completed)==null:!1;if(!s&&p)continue;const k=p?((S=c==null?void 0:c.data)==null?void 0:S.completionStatus)==="skipped"||((v=(g=c==null?void 0:c.data)==null?void 0:g.completionData)==null?void 0:v.action)==="skipped"?"skipped":"completed":void 0;n.push(O({task:a,userId:e.userId,occurrenceStartMs:A,completed:p,completionStatus:k,completionAtMs:typeof((C=c==null?void 0:c.data)==null?void 0:C.completedAtMs)=="number"?c.data.completedAtMs:void 0,completionNote:typeof((u=c==null?void 0:c.data)==null?void 0:u.note)=="string"?c.data.note:void 0,completedByUserId:typeof((h=c==null?void 0:c.data)==null?void 0:h.completedByUserId)=="string"?c.data.completedByUserId:void 0,nowMs:t}))}}return n.sort(V),{nowMs:t,occurrences:n}}};x(L,"_staticInstance",null);let P=L;export{P as TaskService};
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.