@outbuild-company/schedule-core 1.12.0 → 1.13.0

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/dist/index.cjs CHANGED
@@ -1,6 +1,19 @@
1
1
  'use strict';
2
2
 
3
+ // src/activity-types/constants.ts
4
+ var ACTIVITY_TYPE = {
5
+ TASK: "task",
6
+ PROJECT: "project",
7
+ MILESTONE: "milestone"
8
+ };
9
+ var ACTIVITY_TYPES = Object.values(ACTIVITY_TYPE);
10
+ function isActivityType(value) {
11
+ return ACTIVITY_TYPES.includes(value);
12
+ }
13
+
3
14
  // src/types.ts
15
+ var NOTIFICATION_TYPE = {
16
+ CONSTRAINT: "constraint"};
4
17
  var WORK_TIME_DIRECTION = {
5
18
  FUTURE: "future",
6
19
  PAST: "past"
@@ -25,6 +38,11 @@ var STATUS = {
25
38
  WAITING: "Waiting",
26
39
  DOING: "Doing"
27
40
  };
41
+ var ENTITY_CHANGE_KIND = {
42
+ CREATED: "created",
43
+ UPDATED: "updated",
44
+ DELETED: "deleted"
45
+ };
28
46
 
29
47
  // src/constraints/index.ts
30
48
  var CONSTRAINT_TYPE = {
@@ -38,12 +56,12 @@ var CONSTRAINT_TYPE = {
38
56
  MFO: "mfo"
39
57
  };
40
58
  var VIOLATION_RULES = {
41
- mso: () => true,
42
- mfo: () => true,
43
- snlt: (constraint, projected) => constraint < projected,
44
- snet: (constraint, projected) => constraint > projected,
45
- fnlt: (constraint, projected) => constraint < projected,
46
- fnet: (constraint, projected) => constraint > projected
59
+ [CONSTRAINT_TYPE.MSO]: () => true,
60
+ [CONSTRAINT_TYPE.MFO]: () => true,
61
+ [CONSTRAINT_TYPE.SNLT]: (constraint, projected) => constraint < projected,
62
+ [CONSTRAINT_TYPE.SNET]: (constraint, projected) => constraint > projected,
63
+ [CONSTRAINT_TYPE.FNLT]: (constraint, projected) => constraint < projected,
64
+ [CONSTRAINT_TYPE.FNET]: (constraint, projected) => constraint > projected
47
65
  };
48
66
  function checkConstraintViolation(constraintType, constraintDate, projectedDate) {
49
67
  if (!constraintDate) return { violated: false };
@@ -55,16 +73,16 @@ function checkConstraintViolation(constraintType, constraintDate, projectedDate)
55
73
  return { violated: false };
56
74
  }
57
75
  var START_BASED_CONSTRAINTS = /* @__PURE__ */ new Set([
58
- "mso",
59
- "snet",
60
- "snlt"
76
+ CONSTRAINT_TYPE.MSO,
77
+ CONSTRAINT_TYPE.SNET,
78
+ CONSTRAINT_TYPE.SNLT
61
79
  ]);
62
80
  function pickProjectedDateForConstraint(constraintType, projectedStart, projectedEnd) {
63
81
  return START_BASED_CONSTRAINTS.has(constraintType) ? projectedStart : projectedEnd;
64
82
  }
65
83
  function buildConstraintNotification(constraintType, constraintDate, projectedDate) {
66
84
  return {
67
- type: "constraint",
85
+ type: NOTIFICATION_TYPE.CONSTRAINT,
68
86
  messageKey: "constraint_violation",
69
87
  data: {
70
88
  constraintType,
@@ -74,12 +92,30 @@ function buildConstraintNotification(constraintType, constraintDate, projectedDa
74
92
  };
75
93
  }
76
94
  var CONSTRAINT_CASES = {
77
- snet: { startOfDay: true, direction: WORK_TIME_DIRECTION.FUTURE },
78
- snlt: { startOfDay: true, direction: WORK_TIME_DIRECTION.PAST },
79
- fnet: { startOfDay: false, direction: WORK_TIME_DIRECTION.FUTURE },
80
- fnlt: { startOfDay: false, direction: WORK_TIME_DIRECTION.PAST },
81
- mso: { startOfDay: true, direction: WORK_TIME_DIRECTION.FUTURE },
82
- mfo: { startOfDay: false, direction: WORK_TIME_DIRECTION.PAST }
95
+ [CONSTRAINT_TYPE.SNET]: {
96
+ startOfDay: true,
97
+ direction: WORK_TIME_DIRECTION.FUTURE
98
+ },
99
+ [CONSTRAINT_TYPE.SNLT]: {
100
+ startOfDay: true,
101
+ direction: WORK_TIME_DIRECTION.PAST
102
+ },
103
+ [CONSTRAINT_TYPE.FNET]: {
104
+ startOfDay: false,
105
+ direction: WORK_TIME_DIRECTION.FUTURE
106
+ },
107
+ [CONSTRAINT_TYPE.FNLT]: {
108
+ startOfDay: false,
109
+ direction: WORK_TIME_DIRECTION.PAST
110
+ },
111
+ [CONSTRAINT_TYPE.MSO]: {
112
+ startOfDay: true,
113
+ direction: WORK_TIME_DIRECTION.FUTURE
114
+ },
115
+ [CONSTRAINT_TYPE.MFO]: {
116
+ startOfDay: false,
117
+ direction: WORK_TIME_DIRECTION.PAST
118
+ }
83
119
  };
84
120
  var startOfUtcDay = (d) => new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
85
121
  var addUtcDays = (d, n) => new Date(d.getTime() + n * 864e5);
@@ -131,7 +167,9 @@ function computeConstraintBounds(activity, adapter) {
131
167
  latestEnd: null
132
168
  };
133
169
  const type = activity.constraintType;
134
- if (!type || type === "asap" || type === "alap") return empty;
170
+ if (!type || type === CONSTRAINT_TYPE.ASAP || type === CONSTRAINT_TYPE.ALAP) {
171
+ return empty;
172
+ }
135
173
  const constraintDate = getEffectiveConstraintDate(activity, adapter);
136
174
  if (!constraintDate) return empty;
137
175
  const endFromStart = (start) => adapter.calculateEndDate({
@@ -145,35 +183,35 @@ function computeConstraintBounds(activity, adapter) {
145
183
  task: activity
146
184
  });
147
185
  switch (type) {
148
- case "snet":
186
+ case CONSTRAINT_TYPE.SNET:
149
187
  return {
150
188
  earliestStart: constraintDate,
151
189
  latestStart: null,
152
190
  earliestEnd: endFromStart(constraintDate),
153
191
  latestEnd: null
154
192
  };
155
- case "snlt":
193
+ case CONSTRAINT_TYPE.SNLT:
156
194
  return {
157
195
  earliestStart: null,
158
196
  latestStart: constraintDate,
159
197
  earliestEnd: null,
160
198
  latestEnd: endFromStart(constraintDate)
161
199
  };
162
- case "fnet":
200
+ case CONSTRAINT_TYPE.FNET:
163
201
  return {
164
202
  earliestStart: startFromEnd(constraintDate),
165
203
  latestStart: null,
166
204
  earliestEnd: constraintDate,
167
205
  latestEnd: null
168
206
  };
169
- case "fnlt":
207
+ case CONSTRAINT_TYPE.FNLT:
170
208
  return {
171
209
  earliestStart: null,
172
210
  latestStart: startFromEnd(constraintDate),
173
211
  earliestEnd: null,
174
212
  latestEnd: constraintDate
175
213
  };
176
- case "mso": {
214
+ case CONSTRAINT_TYPE.MSO: {
177
215
  const end = endFromStart(constraintDate);
178
216
  return {
179
217
  earliestStart: constraintDate,
@@ -182,7 +220,7 @@ function computeConstraintBounds(activity, adapter) {
182
220
  latestEnd: end
183
221
  };
184
222
  }
185
- case "mfo": {
223
+ case CONSTRAINT_TYPE.MFO: {
186
224
  const start = startFromEnd(constraintDate);
187
225
  return {
188
226
  earliestStart: start,
@@ -210,13 +248,17 @@ function clampStartToBounds(candidate, bounds) {
210
248
  return candidate;
211
249
  }
212
250
 
213
- // src/autoscheduler/types.ts
251
+ // src/autoscheduler/links/constants.ts
214
252
  var LINK_TYPE = {
215
253
  FINISH_TO_START: "0",
216
254
  START_TO_START: "1",
217
255
  FINISH_TO_FINISH: "2",
218
256
  START_TO_FINISH: "3"
219
257
  };
258
+ var LINK_TYPES = Object.values(LINK_TYPE);
259
+ function isLinkType(value) {
260
+ return LINK_TYPES.includes(value);
261
+ }
220
262
 
221
263
  // src/constants/columns.ts
222
264
  var EDITABLE = {
@@ -302,6 +344,7 @@ var DISPATCH_ACTION_KIND = {
302
344
  ACTIVITY_INDENT: "activity-indent",
303
345
  ACTIVITY_OUTDENT: "activity-outdent",
304
346
  ACTIVITY_SET_PROGRESS: "activity-set-progress",
347
+ ACTIVITY_LOOKAHEAD_CONVERT: "activity-lookahead-convert",
305
348
  SELECTION_TOGGLE: "selection-toggle",
306
349
  SELECTION_REPLACE: "selection-replace",
307
350
  VISIBILITY_SET: "visibility-set",
@@ -384,14 +427,14 @@ function activityEditToColumnEdit(activityId, edit) {
384
427
  }
385
428
 
386
429
  // src/api/schedule-api.ts
387
- var LINK_TYPES = {
430
+ var LINK_TYPES2 = {
388
431
  [LINK_RELATIONSHIP.FINISH_TO_START]: LINK_TYPE.FINISH_TO_START,
389
432
  [LINK_RELATIONSHIP.START_TO_START]: LINK_TYPE.START_TO_START,
390
433
  [LINK_RELATIONSHIP.FINISH_TO_FINISH]: LINK_TYPE.FINISH_TO_FINISH,
391
434
  [LINK_RELATIONSHIP.START_TO_FINISH]: LINK_TYPE.START_TO_FINISH
392
435
  };
393
436
  function linkType(relationship) {
394
- return LINK_TYPES[relationship];
437
+ return LINK_TYPES2[relationship];
395
438
  }
396
439
  function batchLink(operation) {
397
440
  if (operation.kind === LINK_BATCH_OPERATION_KIND.CREATE) {
@@ -493,6 +536,8 @@ function createActivitiesApi(engine) {
493
536
  { ...input, kind: DISPATCH_ACTION_KIND.ACTIVITY_MOVE },
494
537
  options
495
538
  ),
539
+ planLookaheadConversion: (input) => engine.planLookaheadConversion(input),
540
+ applyLookaheadConversion: (input) => engine.applyLookaheadConversion(input),
496
541
  indent: (activityIds, context = {}) => engine.dispatch({
497
542
  ...context,
498
543
  kind: DISPATCH_ACTION_KIND.ACTIVITY_INDENT,
@@ -671,6 +716,7 @@ function createScheduleNamespaces(engine) {
671
716
  diagnostics: {
672
717
  auditEffectiveGraph: () => engine.auditEffectiveGraph(),
673
718
  revision: () => engine.getScheduleRevision(),
719
+ stateRevision: () => engine.getStateRevision(),
674
720
  canonicalDigest: () => engine.getCanonicalDigest()
675
721
  }
676
722
  };
@@ -822,6 +868,7 @@ var REJECTION_REASON = {
822
868
  OUTDENT_ROOT_LEVEL_NOT_EDITABLE: "outdent_root_level_not_editable",
823
869
  HIERARCHY_CYCLE: "hierarchy_cycle",
824
870
  SANDBOX_PERSISTENCE_FORBIDDEN: "sandbox_persistence_forbidden",
871
+ STALE_STATE_REVISION: "stale-state-revision",
825
872
  INVALID_PROGRESS_VALUE: "invalid_progress_value_must_be_0_or_100"
826
873
  };
827
874
 
@@ -926,11 +973,6 @@ function dispatchVisibilitySet(action, deps) {
926
973
  }
927
974
 
928
975
  // src/autoscheduler/constants.ts
929
- var ACTIVITY_TYPE = {
930
- TASK: "task",
931
- PROJECT: "project",
932
- MILESTONE: "milestone"
933
- };
934
976
  var TIMING = {
935
977
  YIELD_SLICE_MS: 8
936
978
  };
@@ -1973,53 +2015,55 @@ function filterTopoOrder(order, scopedIds) {
1973
2015
  }
1974
2016
 
1975
2017
  // src/activity-types/behavior.ts
2018
+ var PONDERATOR_WEIGHT = {
2019
+ OWN_BASELINE: "own-baseline",
2020
+ RECURSIVE_LEAF_SUM: "recursive-leaf-sum",
2021
+ ZERO: "zero"
2022
+ };
1976
2023
  var ACTIVITY_TYPE_BEHAVIOR = {
1977
- project: {
2024
+ [ACTIVITY_TYPE.PROJECT]: {
1978
2025
  alwaysSummary: true,
1979
2026
  holdsConstraint: false,
1980
2027
  carriesCustomId: false,
1981
2028
  forcedDuration: null,
1982
- ponderatorWeight: "recursive-leaf-sum",
2029
+ ponderatorWeight: PONDERATOR_WEIGHT.RECURSIVE_LEAF_SUM,
1983
2030
  promotesToProjectOnFirstChild: false
1984
2031
  },
1985
- task: {
2032
+ [ACTIVITY_TYPE.TASK]: {
1986
2033
  alwaysSummary: false,
1987
2034
  holdsConstraint: true,
1988
2035
  carriesCustomId: true,
1989
2036
  forcedDuration: null,
1990
- ponderatorWeight: "own-baseline",
2037
+ ponderatorWeight: PONDERATOR_WEIGHT.OWN_BASELINE,
1991
2038
  promotesToProjectOnFirstChild: true
1992
2039
  },
1993
- milestone: {
2040
+ [ACTIVITY_TYPE.MILESTONE]: {
1994
2041
  alwaysSummary: false,
1995
2042
  holdsConstraint: true,
1996
2043
  carriesCustomId: true,
1997
2044
  forcedDuration: 0,
1998
- ponderatorWeight: "zero",
2045
+ ponderatorWeight: PONDERATOR_WEIGHT.ZERO,
1999
2046
  promotesToProjectOnFirstChild: true
2000
2047
  }
2001
2048
  };
2002
2049
 
2003
2050
  // src/activity-types/predicates.ts
2004
- function isActivityType(value) {
2005
- return value === "project" || value === "task" || value === "milestone";
2006
- }
2007
2051
  function isSummary(type, hasChildren) {
2008
2052
  return hasChildren || isActivityType(type) && ACTIVITY_TYPE_BEHAVIOR[type].alwaysSummary;
2009
2053
  }
2010
2054
  function isMilestoneType(type) {
2011
- return type === "milestone";
2055
+ return type === ACTIVITY_TYPE.MILESTONE;
2012
2056
  }
2013
2057
  function isPromotableLeafType(type) {
2014
2058
  return isActivityType(type) && ACTIVITY_TYPE_BEHAVIOR[type].promotesToProjectOnFirstChild;
2015
2059
  }
2016
2060
 
2017
2061
  // src/activity-types/transitions.ts
2018
- var PROMOTION_TARGET_TYPE = "project";
2019
- var DEMOTION_TARGET_TYPE = "task";
2062
+ var PROMOTION_TARGET_TYPE = ACTIVITY_TYPE.PROJECT;
2063
+ var DEMOTION_TARGET_TYPE = ACTIVITY_TYPE.TASK;
2020
2064
  function typeForNewDuration(currentDuration, newDuration) {
2021
- if (newDuration === 0) return "milestone";
2022
- if (currentDuration === 0 && newDuration > 0) return "task";
2065
+ if (newDuration === 0) return ACTIVITY_TYPE.MILESTONE;
2066
+ if (currentDuration === 0 && newDuration > 0) return ACTIVITY_TYPE.TASK;
2023
2067
  return null;
2024
2068
  }
2025
2069
 
@@ -2605,7 +2649,7 @@ function processConstraints(activityIds, adapter, plans) {
2605
2649
  startDate: activity.startDate,
2606
2650
  endDate: activity.endDate,
2607
2651
  drivingLinkId: null,
2608
- kind: "asap",
2652
+ kind: CONSTRAINT_TYPE.ASAP,
2609
2653
  conflict: false,
2610
2654
  earliestStart: bounds.earliestStart,
2611
2655
  latestStart: bounds.latestStart,
@@ -2757,7 +2801,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
2757
2801
  startDate: activity.startDate,
2758
2802
  endDate: activity.endDate,
2759
2803
  drivingLinkId: null,
2760
- kind: "asap",
2804
+ kind: CONSTRAINT_TYPE.ASAP,
2761
2805
  conflict: false
2762
2806
  };
2763
2807
  const hasConstraintBounds = plan.earliestStart || plan.latestStart || plan.earliestEnd || plan.latestEnd;
@@ -2961,13 +3005,13 @@ async function alapPass(reversedIds, links, asapPlans, adapter, _options, isCurr
2961
3005
  startDate: snappedStart,
2962
3006
  endDate: snappedEnd,
2963
3007
  drivingLinkId: null,
2964
- kind: "alap",
3008
+ kind: CONSTRAINT_TYPE.ALAP,
2965
3009
  conflict: false
2966
3010
  };
2967
3011
  plan.startDate = snappedStart;
2968
3012
  plan.endDate = snappedEnd;
2969
3013
  plan.drivingLinkId = null;
2970
- plan.kind = "alap";
3014
+ plan.kind = CONSTRAINT_TYPE.ALAP;
2971
3015
  const predecessorFloor = plan.earliestSchedulingStart ?? null;
2972
3016
  plan.earliestSchedulingStart = null;
2973
3017
  plan.earliestSchedulingEnd = null;
@@ -2995,7 +3039,7 @@ var noopReporter = {
2995
3039
  // src/internal/state/calendar-duration.ts
2996
3040
  var CALENDAR_DAY_MS = 864e5;
2997
3041
  function computeCalendarDuration(activity) {
2998
- if (activity.type === "milestone") return 0;
3042
+ if (activity.type === ACTIVITY_TYPE.MILESTONE) return 0;
2999
3043
  const start = activity.startDate?.getTime();
3000
3044
  const end = activity.endDate?.getTime();
3001
3045
  if (start == null || end == null || Number.isNaN(start) || Number.isNaN(end)) {
@@ -3302,8 +3346,12 @@ var ReparentedPort = class {
3302
3346
 
3303
3347
  // src/internal/dependency-graph/effective-graph-validation.ts
3304
3348
  function validateTopologyCommit(input) {
3305
- const { port, currentLinks, proposedLinks, proposal } = input;
3306
- const proposedEdges = projectEffectiveEdges(port, proposedLinks, proposal);
3349
+ const { port, proposedPort, currentLinks, proposedLinks, proposal } = input;
3350
+ const proposedEdges = projectEffectiveEdges(
3351
+ proposedPort ?? port,
3352
+ proposedLinks,
3353
+ proposal
3354
+ );
3307
3355
  if (!hasDirectedCycle(proposedEdges)) return { ok: true };
3308
3356
  const currentEdges = projectEffectiveEdges(port, currentLinks);
3309
3357
  const corruptBefore = corruptActivityIds(currentEdges);
@@ -3513,19 +3561,25 @@ function defaultNewLinkId() {
3513
3561
  }
3514
3562
 
3515
3563
  // src/autoscheduler/links/link-display.ts
3564
+ var LINK_CODE = {
3565
+ FINISH_TO_START: "fs",
3566
+ START_TO_START: "ss",
3567
+ FINISH_TO_FINISH: "ff",
3568
+ START_TO_FINISH: "sf"
3569
+ };
3516
3570
  var LINK_TYPE_CODE = {
3517
- [LINK_TYPE.FINISH_TO_START]: "fs",
3518
- [LINK_TYPE.START_TO_START]: "ss",
3519
- [LINK_TYPE.FINISH_TO_FINISH]: "ff",
3520
- [LINK_TYPE.START_TO_FINISH]: "sf"
3571
+ [LINK_TYPE.FINISH_TO_START]: LINK_CODE.FINISH_TO_START,
3572
+ [LINK_TYPE.START_TO_START]: LINK_CODE.START_TO_START,
3573
+ [LINK_TYPE.FINISH_TO_FINISH]: LINK_CODE.FINISH_TO_FINISH,
3574
+ [LINK_TYPE.START_TO_FINISH]: LINK_CODE.START_TO_FINISH
3521
3575
  };
3522
3576
  var LINK_CODE_TO_TYPE = {
3523
- fs: LINK_TYPE.FINISH_TO_START,
3524
- ss: LINK_TYPE.START_TO_START,
3525
- ff: LINK_TYPE.FINISH_TO_FINISH,
3526
- sf: LINK_TYPE.START_TO_FINISH
3577
+ [LINK_CODE.FINISH_TO_START]: LINK_TYPE.FINISH_TO_START,
3578
+ [LINK_CODE.START_TO_START]: LINK_TYPE.START_TO_START,
3579
+ [LINK_CODE.FINISH_TO_FINISH]: LINK_TYPE.FINISH_TO_FINISH,
3580
+ [LINK_CODE.START_TO_FINISH]: LINK_TYPE.START_TO_FINISH
3527
3581
  };
3528
- var DEFAULT_LINK_CODE = "fs";
3582
+ var DEFAULT_LINK_CODE = LINK_CODE.FINISH_TO_START;
3529
3583
  function parseLinkTypeCode(raw) {
3530
3584
  if (raw in LINK_CODE_TO_TYPE) {
3531
3585
  return LINK_CODE_TO_TYPE[raw];
@@ -3591,20 +3645,24 @@ function diffLinks(input) {
3591
3645
  const operations = [];
3592
3646
  for (const [key, link] of currentByKey) {
3593
3647
  if (!desired.has(key)) {
3594
- operations.push({ kind: "delete", linkId: link.id });
3648
+ operations.push({ kind: LINK_OPERATION_KIND.DELETE, linkId: link.id });
3595
3649
  }
3596
3650
  }
3597
3651
  for (const [key, spec] of desired) {
3598
3652
  const existing = currentByKey.get(key);
3599
3653
  if (!existing) continue;
3600
3654
  if (existing.lag !== spec.lag) {
3601
- operations.push({ kind: "update", linkId: existing.id, lag: spec.lag });
3655
+ operations.push({
3656
+ kind: LINK_OPERATION_KIND.UPDATE,
3657
+ linkId: existing.id,
3658
+ lag: spec.lag
3659
+ });
3602
3660
  }
3603
3661
  }
3604
3662
  for (const [key, spec] of desired) {
3605
3663
  if (currentByKey.has(key)) continue;
3606
3664
  operations.push({
3607
- kind: "create",
3665
+ kind: LINK_OPERATION_KIND.CREATE,
3608
3666
  source: spec.source,
3609
3667
  target: targetActivityId,
3610
3668
  type: spec.type,
@@ -3638,20 +3696,24 @@ function diffOutgoingLinks(input) {
3638
3696
  const operations = [];
3639
3697
  for (const [key, link] of currentByKey) {
3640
3698
  if (!desired.has(key)) {
3641
- operations.push({ kind: "delete", linkId: link.id });
3699
+ operations.push({ kind: LINK_OPERATION_KIND.DELETE, linkId: link.id });
3642
3700
  }
3643
3701
  }
3644
3702
  for (const [key, spec] of desired) {
3645
3703
  const existing = currentByKey.get(key);
3646
3704
  if (!existing) continue;
3647
3705
  if (existing.lag !== spec.lag) {
3648
- operations.push({ kind: "update", linkId: existing.id, lag: spec.lag });
3706
+ operations.push({
3707
+ kind: LINK_OPERATION_KIND.UPDATE,
3708
+ linkId: existing.id,
3709
+ lag: spec.lag
3710
+ });
3649
3711
  }
3650
3712
  }
3651
3713
  for (const [key, spec] of desired) {
3652
3714
  if (currentByKey.has(key)) continue;
3653
3715
  operations.push({
3654
- kind: "create",
3716
+ kind: LINK_OPERATION_KIND.CREATE,
3655
3717
  source: sourceActivityId,
3656
3718
  target: spec.target,
3657
3719
  type: spec.type,
@@ -3695,13 +3757,13 @@ var currentImpl = {
3695
3757
  // src/autoscheduler/date-math/types.ts
3696
3758
  function pickDatesForLinkType(source, target, linkType2) {
3697
3759
  switch (linkType2) {
3698
- case "0":
3760
+ case LINK_TYPE.FINISH_TO_START:
3699
3761
  return { sourceDate: source.endDate, targetDate: target.startDate };
3700
- case "1":
3762
+ case LINK_TYPE.START_TO_START:
3701
3763
  return { sourceDate: source.startDate, targetDate: target.startDate };
3702
- case "2":
3764
+ case LINK_TYPE.FINISH_TO_FINISH:
3703
3765
  return { sourceDate: source.endDate, targetDate: target.endDate };
3704
- case "3":
3766
+ case LINK_TYPE.START_TO_FINISH:
3705
3767
  return { sourceDate: source.startDate, targetDate: target.endDate };
3706
3768
  }
3707
3769
  }
@@ -3834,7 +3896,7 @@ var AutoScheduler = class {
3834
3896
  };
3835
3897
  } catch (error) {
3836
3898
  this.reporter.error("[AutoScheduler] Error during scheduling", error);
3837
- return emptyResult;
3899
+ throw error;
3838
3900
  }
3839
3901
  }
3840
3902
  };
@@ -3914,7 +3976,7 @@ function adjustLinkLagOnTaskMove(targetId, adapter, preEditTarget) {
3914
3976
  if (!link) continue;
3915
3977
  const source = adapter.getActivity(link.source);
3916
3978
  if (!source) continue;
3917
- if (source.constraintType === "alap") continue;
3979
+ if (source.constraintType === CONSTRAINT_TYPE.ALAP) continue;
3918
3980
  const isEndAnchoredIntoMilestone = isMilestoneType(target.type) && (link.type === LINK_TYPE.START_TO_FINISH || link.type === LINK_TYPE.FINISH_TO_FINISH);
3919
3981
  if (isEndAnchoredIntoMilestone) continue;
3920
3982
  const { sourceDate, targetDate } = pickDatesForLinkType(
@@ -3928,7 +3990,10 @@ function adjustLinkLagOnTaskMove(targetId, adapter, preEditTarget) {
3928
3990
  calendarApi
3929
3991
  );
3930
3992
  if (newLag === link.lag) continue;
3931
- applyLinkUpdate({ linkId: link.id, lag: newLag }, adapter);
3993
+ applyLinkUpdate(
3994
+ { kind: LINK_OPERATION_KIND.UPDATE, linkId: link.id, lag: newLag },
3995
+ adapter
3996
+ );
3932
3997
  }
3933
3998
  }
3934
3999
 
@@ -4040,15 +4105,19 @@ function computeLeafRealWork(workHours, progress) {
4040
4105
  }
4041
4106
 
4042
4107
  // src/propagations/upward/parent-bounds.ts
4108
+ var PARENT_PROGRESS_MODE = {
4109
+ SKIP: "skip",
4110
+ FREEZE_WITHOUT_CONTRIBUTION: "freeze-when-no-contribution"
4111
+ };
4043
4112
  async function updateParentBoundsFromChildren(adapter, dirtyIds, recomputeProgress = true, options = {}) {
4044
4113
  const parents = dirtyIds ? findAncestorsOfDirty(adapter, dirtyIds) : findAllParents(adapter);
4045
- const progressMode = recomputeProgress ? options.progressMode ?? "freeze-when-no-contribution" : "skip";
4114
+ const progressMode = recomputeProgress ? options.progressMode ?? PARENT_PROGRESS_MODE.FREEZE_WITHOUT_CONTRIBUTION : PARENT_PROGRESS_MODE.SKIP;
4046
4115
  await recomputeParentsCooperatively(parents, adapter, progressMode, {
4047
4116
  recomputeRealWork: options.recomputeRealWork ?? false
4048
4117
  });
4049
4118
  }
4050
4119
  function recomputeSingleParentDisplayBounds(parentId, adapter) {
4051
- recomputeParentFromChildren(parentId, adapter, "skip");
4120
+ recomputeParentFromChildren(parentId, adapter, PARENT_PROGRESS_MODE.SKIP);
4052
4121
  }
4053
4122
  async function recomputeParentsCooperatively(parents, adapter, progressMode, options = {
4054
4123
  recomputeRealWork: false
@@ -4134,7 +4203,7 @@ function aggregateChildren(childrenIds, adapter, includeRealWork) {
4134
4203
  }
4135
4204
  return { minStart, maxEnd, realWorkSum, weightedChildren };
4136
4205
  }
4137
- function recomputeParentFromChildren(parentId, adapter, progressMode = "freeze-when-no-contribution", recomputeRealWork = false) {
4206
+ function recomputeParentFromChildren(parentId, adapter, progressMode = PARENT_PROGRESS_MODE.FREEZE_WITHOUT_CONTRIBUTION, recomputeRealWork = false) {
4138
4207
  const parent = adapter.getActivity(parentId);
4139
4208
  if (!parent) return;
4140
4209
  const childrenIds = adapter.getChildren(parentId);
@@ -4149,7 +4218,7 @@ function recomputeParentFromChildren(parentId, adapter, progressMode = "freeze-w
4149
4218
  adapter.setActivityField(parentId, "startDate", newStart);
4150
4219
  adapter.setActivityField(parentId, "endDate", newEnd);
4151
4220
  adapter.setActivityField(parentId, "durationHours", durationHours);
4152
- if (progressMode !== "skip") {
4221
+ if (progressMode !== PARENT_PROGRESS_MODE.SKIP) {
4153
4222
  applyWeightedProgressRollup(parentId, aggregate.weightedChildren, adapter);
4154
4223
  }
4155
4224
  if (recomputeRealWork) {
@@ -4256,6 +4325,21 @@ function fieldChanges(patch, options = {}) {
4256
4325
  };
4257
4326
  }
4258
4327
 
4328
+ // src/columns/shared/tracking-events.ts
4329
+ var COLUMN_TRACK_EVENT = {
4330
+ PROGRESS_ENTRY: "activity_progress_entry",
4331
+ PROGRESS_UPDATE_RADIO_BUTTON: "activity_progress_update_radio_button",
4332
+ DURATION_ENTRY: "activity_duration_entry",
4333
+ START_DATE_ENTRY: "activity_start_date_entry",
4334
+ END_DATE_ENTRY: "activity_end_date_entry",
4335
+ NAME_ENTRY: "activity_name_entry",
4336
+ DESCRIPTION_ENTRY: "activity_description_entry",
4337
+ CALENDAR_ASSIGNMENT: "activity_calendar_assignment",
4338
+ COST_BUDGETED_ENTRY: "activity_cost_budgeted_entry",
4339
+ COST_SPENT_ENTRY: "activity_cost_spent_entry",
4340
+ LABOR_HOURS_BUDGETED_ENTRY: "activity_labor_hours_budgeted_entry"
4341
+ };
4342
+
4259
4343
  // src/columns/text/text-pipeline.ts
4260
4344
  var textPipeline = {
4261
4345
  targetField: "name",
@@ -4275,7 +4359,7 @@ var textPipeline = {
4275
4359
  postProcessors: []
4276
4360
  });
4277
4361
  },
4278
- trackEvent: "activity_name_entry"
4362
+ trackEvent: COLUMN_TRACK_EVENT.NAME_ENTRY
4279
4363
  };
4280
4364
 
4281
4365
  // src/columns/description/description-pipeline.ts
@@ -4297,7 +4381,7 @@ var descriptionPipeline = {
4297
4381
  { autoSchedule: false, postProcessors: [] }
4298
4382
  );
4299
4383
  },
4300
- trackEvent: "activity_description_entry"
4384
+ trackEvent: COLUMN_TRACK_EVENT.DESCRIPTION_ENTRY
4301
4385
  };
4302
4386
 
4303
4387
  // src/columns/shared/activity-predicates.ts
@@ -4329,6 +4413,7 @@ var setEndDate = (value) => ({
4329
4413
  });
4330
4414
 
4331
4415
  // src/columns/shared/date-normalize.ts
4416
+ var UTC_TIME_ZONE = "UTC";
4332
4417
  function truncateToUtcDay(date2, tz) {
4333
4418
  {
4334
4419
  const parts = new Intl.DateTimeFormat("en-CA", {
@@ -4349,11 +4434,11 @@ function endOfLocalDay(date2, tz) {
4349
4434
  }
4350
4435
  }
4351
4436
  function nextWorkingDay(calendar, domainDay) {
4352
- let cursor = truncateToUtcDay(domainDay, "UTC");
4437
+ let cursor = truncateToUtcDay(domainDay, UTC_TIME_ZONE);
4353
4438
  while (!calendar.isWorkTime(cursor, CALENDAR_UNIT.DAY)) {
4354
4439
  cursor = new Date(cursor);
4355
4440
  cursor.setUTCDate(cursor.getUTCDate() + 1);
4356
- cursor = truncateToUtcDay(cursor, "UTC");
4441
+ cursor = truncateToUtcDay(cursor, UTC_TIME_ZONE);
4357
4442
  }
4358
4443
  return cursor;
4359
4444
  }
@@ -4376,22 +4461,22 @@ function shiftEnd(calendar, domainDay) {
4376
4461
  });
4377
4462
  }
4378
4463
  var START_BASED_CONSTRAINTS2 = /* @__PURE__ */ new Set([
4379
- "snet",
4380
- "snlt",
4381
- "mso"
4464
+ CONSTRAINT_TYPE.SNET,
4465
+ CONSTRAINT_TYPE.SNLT,
4466
+ CONSTRAINT_TYPE.MSO
4382
4467
  ]);
4383
4468
  var END_BASED_CONSTRAINTS = /* @__PURE__ */ new Set([
4384
- "fnet",
4385
- "fnlt",
4386
- "mfo"
4469
+ CONSTRAINT_TYPE.FNET,
4470
+ CONSTRAINT_TYPE.FNLT,
4471
+ CONSTRAINT_TYPE.MFO
4387
4472
  ]);
4388
4473
  var DATELESS_CONSTRAINTS = /* @__PURE__ */ new Set([
4389
- "asap",
4390
- "alap"
4474
+ CONSTRAINT_TYPE.ASAP,
4475
+ CONSTRAINT_TYPE.ALAP
4391
4476
  ]);
4392
- var IMPLIED_CONSTRAINT_ON_DATE_EDIT = "snet";
4477
+ var IMPLIED_CONSTRAINT_ON_DATE_EDIT = CONSTRAINT_TYPE.SNET;
4393
4478
  function normalizeConstraintDate(typedDay, calendar, constraintType) {
4394
- const constraintDay = truncateToUtcDay(typedDay, "UTC");
4479
+ const constraintDay = truncateToUtcDay(typedDay, UTC_TIME_ZONE);
4395
4480
  if (!START_BASED_CONSTRAINTS2.has(constraintType) && !END_BASED_CONSTRAINTS.has(constraintType)) {
4396
4481
  return constraintDay;
4397
4482
  }
@@ -4427,6 +4512,9 @@ var POST_PROCESSOR = {
4427
4512
  // src/columns/shared/error-codes.ts
4428
4513
  var VALIDATION_REASON = {
4429
4514
  NEGATIVE_DURATION: "negative_duration"};
4515
+ var EDIT_DENIAL_REASON = {
4516
+ SUMMARY: "summary",
4517
+ HAS_LOOKAHEAD_TASKS: "has_lookahead_tasks"};
4430
4518
 
4431
4519
  // src/columns/shared/constraint-validation.ts
4432
4520
  function checkConstraintViolation2(constraintType, constraintDate, projectedDate) {
@@ -4491,7 +4579,7 @@ var durationPipeline = {
4491
4579
  } : {}
4492
4580
  };
4493
4581
  },
4494
- trackEvent: "activity_duration_entry"
4582
+ trackEvent: COLUMN_TRACK_EVENT.DURATION_ENTRY
4495
4583
  };
4496
4584
  function isNegativeDuration(value) {
4497
4585
  return Math.sign(value) === -1;
@@ -4503,7 +4591,7 @@ function checkDurationAgainstConstraints(activity, newDuration, ctx) {
4503
4591
  const calendar = ctx.calendars.getCalendar(activity.calendarId);
4504
4592
  if (!calendar) return { violated: false };
4505
4593
  const type = activity.constraintType;
4506
- if (type !== "fnet" && type !== "fnlt" && type !== "mfo") {
4594
+ if (type !== CONSTRAINT_TYPE.FNET && type !== CONSTRAINT_TYPE.FNLT && type !== CONSTRAINT_TYPE.MFO) {
4507
4595
  return { violated: false };
4508
4596
  }
4509
4597
  const projectedEnd = calendar.calculateEndDate(
@@ -4596,7 +4684,7 @@ var progressPipeline = {
4596
4684
  trackingEvents
4597
4685
  });
4598
4686
  },
4599
- trackEvent: "activity_progress_entry"
4687
+ trackEvent: COLUMN_TRACK_EVENT.PROGRESS_ENTRY
4600
4688
  };
4601
4689
  function isOutOfRange(value) {
4602
4690
  return value < MIN_PROGRESS || value > MAX_PROGRESS;
@@ -4676,7 +4764,7 @@ function computeWeightedProgress(parentId, overlay, hierarchy) {
4676
4764
  function buildRecursiveTrackingEvents(activity, newValue) {
4677
4765
  return [
4678
4766
  {
4679
- name: "activity_progress_update_radio_button",
4767
+ name: COLUMN_TRACK_EVENT.PROGRESS_UPDATE_RADIO_BUTTON,
4680
4768
  properties: {
4681
4769
  activity_id: activity.id,
4682
4770
  activity_name: activity.name,
@@ -4716,7 +4804,7 @@ var costPipeline = {
4716
4804
  cascadeMutations
4717
4805
  });
4718
4806
  },
4719
- trackEvent: "activity_cost_budgeted_entry"
4807
+ trackEvent: COLUMN_TRACK_EVENT.COST_BUDGETED_ENTRY
4720
4808
  };
4721
4809
  function buildCostAncestorCascade(activity, newCost, hierarchy) {
4722
4810
  const overlay = /* @__PURE__ */ new Map();
@@ -4769,7 +4857,7 @@ var usedCostPipeline = {
4769
4857
  }
4770
4858
  );
4771
4859
  },
4772
- trackEvent: "activity_cost_spent_entry"
4860
+ trackEvent: COLUMN_TRACK_EVENT.COST_SPENT_ENTRY
4773
4861
  };
4774
4862
  function buildUsedCostAncestorCascade(activity, newUsedCost, hierarchy) {
4775
4863
  const overlay = /* @__PURE__ */ new Map();
@@ -4824,7 +4912,7 @@ var hhWorkTimePipeline = {
4824
4912
  }
4825
4913
  );
4826
4914
  },
4827
- trackEvent: "activity_labor_hours_budgeted_entry"
4915
+ trackEvent: COLUMN_TRACK_EVENT.LABOR_HOURS_BUDGETED_ENTRY
4828
4916
  };
4829
4917
  function computeRealWork(hhWorkTime, progress) {
4830
4918
  return computeLeafRealWork(hhWorkTime, progress);
@@ -4917,7 +5005,7 @@ var startDatePipeline = {
4917
5005
  throw new Error("startDatePipeline: no calendar resolved (integrity)");
4918
5006
  }
4919
5007
  const finalStart = shiftStart(calendar, newValue);
4920
- const milestoneActivity = activity.type === "milestone";
5008
+ const milestoneActivity = activity.type === ACTIVITY_TYPE.MILESTONE;
4921
5009
  const finalEnd = milestoneActivity ? finalStart : calendar.calculateEndDate(finalStart, activity.durationHours);
4922
5010
  const constraintDate = finalStart;
4923
5011
  return {
@@ -4937,7 +5025,7 @@ var startDatePipeline = {
4937
5025
  constraintWarning: detectConstraintWarning(activity, finalStart, calendar)
4938
5026
  };
4939
5027
  },
4940
- trackEvent: "activity_start_date_entry"
5028
+ trackEvent: COLUMN_TRACK_EVENT.START_DATE_ENTRY
4941
5029
  };
4942
5030
  function checkParentStartConstraint(activity, newDate, ctx) {
4943
5031
  const parentStartDate = ctx.hierarchy.getParentStartDateIfHasPredecessors(
@@ -5031,7 +5119,7 @@ var endDatePipeline = {
5031
5119
  ...constraintWarning ? { constraintWarning } : {}
5032
5120
  };
5033
5121
  },
5034
- trackEvent: "activity_end_date_entry"
5122
+ trackEvent: COLUMN_TRACK_EVENT.END_DATE_ENTRY
5035
5123
  };
5036
5124
  function isNearlyCompleted(activity) {
5037
5125
  return activity.progress >= NEAR_COMPLETE_THRESHOLD;
@@ -5142,7 +5230,9 @@ function buildConstraintTypeExtraFields(activity, newType, ctx) {
5142
5230
  };
5143
5231
  }
5144
5232
  function normalizeMilestoneConstraintDate(activity, newType, derivedDate, ctx) {
5145
- if (activity.type !== "milestone" || !derivedDate) return derivedDate;
5233
+ if (activity.type !== ACTIVITY_TYPE.MILESTONE || !derivedDate) {
5234
+ return derivedDate;
5235
+ }
5146
5236
  const calendar = ctx.calendars.getCalendar(String(activity.calendarId));
5147
5237
  if (!calendar) return derivedDate;
5148
5238
  return normalizeConstraintDate(derivedDate, calendar, newType);
@@ -5220,7 +5310,7 @@ var calendarIdPipeline = {
5220
5310
  postProcessors: []
5221
5311
  });
5222
5312
  },
5223
- trackEvent: "activity_calendar_assignment"
5313
+ trackEvent: COLUMN_TRACK_EVENT.CALENDAR_ASSIGNMENT
5224
5314
  };
5225
5315
  function isEmpty(value) {
5226
5316
  return value === "";
@@ -5302,8 +5392,7 @@ var customIdPipeline = {
5302
5392
  { customId: newValue },
5303
5393
  { autoSchedule: false, postProcessors: [] }
5304
5394
  );
5305
- },
5306
- trackEvent: "schedule_custom_id_edition"
5395
+ }
5307
5396
  };
5308
5397
 
5309
5398
  // src/columns/subcontract-id/subcontract-id-pipeline.ts
@@ -5442,6 +5531,9 @@ var ACTIVITY_BATCH_MODE = {
5442
5531
  APPEND: "append",
5443
5532
  REPLACE: "replace"
5444
5533
  };
5534
+ var ACTIVITY_PROGRESS_ORIGIN = {
5535
+ ACTION_BUTTON: "action-button"
5536
+ };
5445
5537
  var SCHEDULE_EFFECT_KIND = {
5446
5538
  SIR_AUTO_REJECT: "sir-auto-reject"
5447
5539
  };
@@ -5460,7 +5552,9 @@ var CHANGE_SET_SOURCE_KIND = {
5460
5552
 
5461
5553
  // src/dispatch/shared/constraint-warnings.ts
5462
5554
  function toConstraintWarning(activityId, notification) {
5463
- if (!notification || notification.type !== "constraint") return null;
5555
+ if (!notification || notification.type !== NOTIFICATION_TYPE.CONSTRAINT) {
5556
+ return null;
5557
+ }
5464
5558
  const data = notification.data;
5465
5559
  if (!data?.constraintType || !data.constraintDate) return null;
5466
5560
  return {
@@ -5506,6 +5600,7 @@ var ACTIVITY_PROPERTY = {
5506
5600
  TYPE: "type",
5507
5601
  START_DATE: "startDate",
5508
5602
  END_DATE: "endDate",
5603
+ DURATION_HOURS: "durationHours",
5509
5604
  CONSTRAINT_TYPE: "constraintType",
5510
5605
  CONSTRAINT_DATE: "constraintDate",
5511
5606
  PROGRESS: "progress",
@@ -5638,7 +5733,7 @@ async function buildActivityChanges(adapter, before, touched, correlativeBefore)
5638
5733
  function buildEntryForTouchedId(adapter, before, activityId, correlativeBefore) {
5639
5734
  const afterSnap = adapter.getActivity(activityId);
5640
5735
  if (!afterSnap) {
5641
- return { id: activityId, kind: "deleted", after: null };
5736
+ return { id: activityId, kind: ENTITY_CHANGE_KIND.DELETED, after: null };
5642
5737
  }
5643
5738
  const beforeSnap = before.get(activityId);
5644
5739
  if (!beforeSnap && correlativeBefore?.has(activityId)) {
@@ -5653,7 +5748,7 @@ function buildEntryForTouchedId(adapter, before, activityId, correlativeBefore)
5653
5748
  if (beforeSnap && Object.keys(diff).length === 0) return null;
5654
5749
  return {
5655
5750
  id: activityId,
5656
- kind: beforeSnap ? "updated" : "created",
5751
+ kind: beforeSnap ? ENTITY_CHANGE_KIND.UPDATED : ENTITY_CHANGE_KIND.CREATED,
5657
5752
  fields: diff,
5658
5753
  after: structuredCloneActivity(afterSnap)
5659
5754
  };
@@ -5662,7 +5757,7 @@ function buildCorrelativeOnlyEntry(activityId, correlativeIdBefore, liveActivity
5662
5757
  if (correlativeIdBefore === liveActivity.correlativeId) return null;
5663
5758
  return {
5664
5759
  id: activityId,
5665
- kind: "updated",
5760
+ kind: ENTITY_CHANGE_KIND.UPDATED,
5666
5761
  fields: {
5667
5762
  correlativeId: {
5668
5763
  before: correlativeIdBefore,
@@ -5787,7 +5882,7 @@ function expectedProgressFromBaseline(start, end, now, calendar) {
5787
5882
  }
5788
5883
 
5789
5884
  // src/columns/expected-progress/compute.ts
5790
- var isProject = (activity) => activity.type === "project";
5885
+ var isProject = (activity) => activity.type === ACTIVITY_TYPE.PROJECT;
5791
5886
  var leafExpectedLive = (activity, now, state) => {
5792
5887
  const calendarId = activity.calendarId;
5793
5888
  const calendar = calendarId != null ? state.calendarReader.getCalendar(String(calendarId)) : null;
@@ -5841,7 +5936,7 @@ function applyExpectedProgressLive(state, now) {
5841
5936
  }
5842
5937
 
5843
5938
  // src/columns/expected-progress-base/compute.ts
5844
- var isProject2 = (a) => a.type === "project";
5939
+ var isProject2 = (a) => a.type === ACTIVITY_TYPE.PROJECT;
5845
5940
  var activeBaselineOf = (a) => getActiveBaseline(a);
5846
5941
  var leafExpected = (a, now, adapter, defaultBaseCalendarId) => {
5847
5942
  const base = activeBaselineOf(a);
@@ -6003,15 +6098,44 @@ function getNextWorkingHour(activityParams) {
6003
6098
  return newDate;
6004
6099
  }
6005
6100
 
6101
+ // src/critical-path/legacy/constants/constraints.js
6102
+ var CONSTRAINT_TYPES = CONSTRAINT_TYPE;
6103
+
6104
+ // src/critical-path/legacy/constants/linkTypes.js
6105
+ var LINK_TYPES3 = Object.freeze({
6106
+ FS: LINK_CODE.FINISH_TO_START,
6107
+ SS: LINK_CODE.START_TO_START,
6108
+ FF: LINK_CODE.FINISH_TO_FINISH,
6109
+ SF: LINK_CODE.START_TO_FINISH
6110
+ });
6111
+
6112
+ // src/critical-path/legacy/constants/linkByCode.js
6113
+ function getLinkNameByCode(code) {
6114
+ return LINK_TYPE_CODE[String(Number(code))] ?? LINK_CODE.START_TO_FINISH;
6115
+ }
6116
+
6117
+ // src/critical-path/legacy/constants/calculation.js
6118
+ var CALCULATION_DIRECTION = Object.freeze({
6119
+ FORWARD: "forward",
6120
+ BACKWARD: "backward"
6121
+ });
6122
+ var COMPARISON_DIRECTION = Object.freeze({
6123
+ GREATER: "greater",
6124
+ LESS: "less"
6125
+ });
6126
+ var GANTT_FIELD = Object.freeze({
6127
+ SOURCE: "$source"
6128
+ });
6129
+
6006
6130
  // src/critical-path/legacy/helpers/filters.js
6007
6131
  var byFirstLevel = (activity) => {
6008
6132
  if (!activity) return false;
6009
6133
  return activity["$level"] === 1;
6010
6134
  };
6011
- var filterByParentType = (activity) => activity.type === "project";
6135
+ var filterByParentType = (activity) => activity.type === ACTIVITY_TYPE.PROJECT;
6012
6136
  var avoidSubproject = (activity) => activity["$level"] !== 0;
6013
- var byTaskType = (activity) => activity.type === "task";
6014
- var byTaskTypeAndMilestone = (activity) => activity.type === "task" || activity.type === "milestone";
6137
+ var byTaskType = (activity) => activity.type === ACTIVITY_TYPE.TASK;
6138
+ var byTaskTypeAndMilestone = (activity) => activity.type === ACTIVITY_TYPE.TASK || activity.type === ACTIVITY_TYPE.MILESTONE;
6015
6139
  var filters_default = {
6016
6140
  byFirstLevel,
6017
6141
  filterByParentType,
@@ -6020,37 +6144,6 @@ var filters_default = {
6020
6144
  byTaskTypeAndMilestone
6021
6145
  };
6022
6146
 
6023
- // src/critical-path/legacy/constants/constraints.js
6024
- var CONSTRAINT_TYPES = Object.freeze({
6025
- MFO: "mfo",
6026
- MSO: "mso",
6027
- FNLT: "fnlt",
6028
- FNET: "fnet",
6029
- SNET: "snet",
6030
- SNLT: "snlt",
6031
- ALAP: "alap",
6032
- ASAP: "asap"
6033
- });
6034
-
6035
- // src/critical-path/legacy/constants/linkTypes.js
6036
- var LINK_TYPES2 = Object.freeze({
6037
- FS: "fs",
6038
- SS: "ss",
6039
- FF: "ff",
6040
- SF: "sf"
6041
- });
6042
-
6043
- // src/critical-path/legacy/constants/linkByCode.js
6044
- function getLinkNameByCode(code) {
6045
- const linkMap = {
6046
- 0: "fs",
6047
- 1: "ss",
6048
- 2: "ff",
6049
- 3: "sf"
6050
- };
6051
- return linkMap[Number(code)] || "sf";
6052
- }
6053
-
6054
6147
  // src/critical-path/legacy/base/identifiers/secondLevelActivities.js
6055
6148
  function identifySecondLevelActivities(params) {
6056
6149
  const { gantt, pendingParentsWithNoLinks, calculations, linkProperty } = params;
@@ -6112,7 +6205,7 @@ function filterChildrenThatCanBeCalculated(params) {
6112
6205
  const linkedActivities = getArrayOfLinkedActivities3({
6113
6206
  gantt,
6114
6207
  links,
6115
- linkDirection: linkProperty === "$source" ? "target" : "source"
6208
+ linkDirection: linkProperty === GANTT_FIELD.SOURCE ? "target" : "source"
6116
6209
  });
6117
6210
  const isLinkedWithCalculatedOrSibling = linkedActivities.every(
6118
6211
  (linkedActivityId) => calculations.has(linkedActivityId)
@@ -6141,13 +6234,13 @@ function getArrayOfLinkedActivities(params) {
6141
6234
  function identifyInitialActivities({ gantt, linkProperty, direction }) {
6142
6235
  try {
6143
6236
  const chainStartActivities = getChainStartActivities(gantt, linkProperty);
6144
- if (direction === "forward") {
6237
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
6145
6238
  return {
6146
6239
  chainStartActivities,
6147
6240
  activitiesStartChainButChildrenOfLinkedParents: null
6148
6241
  };
6149
6242
  }
6150
- if (direction === "backward") {
6243
+ if (direction === CALCULATION_DIRECTION.BACKWARD) {
6151
6244
  return processBackwardActivities(
6152
6245
  chainStartActivities,
6153
6246
  gantt,
@@ -6171,7 +6264,7 @@ function processBackwardActivities(chainStartActivities, gantt, linkProperty) {
6171
6264
  if (!parentActivity) return;
6172
6265
  if (parentActivity[linkProperty].length > 0) {
6173
6266
  activitiesStartChainButChildrenOfLinkedParents.add(activity.id);
6174
- } else if (parentActivity.constraint_type !== "fnlt") {
6267
+ } else if (parentActivity.constraint_type !== CONSTRAINT_TYPES.FNLT) {
6175
6268
  withoutLinkedParents.push(activity);
6176
6269
  }
6177
6270
  });
@@ -6192,7 +6285,7 @@ function identifyParentsWithAndWithoutLinks({
6192
6285
  const parentsWithFullProgress = /* @__PURE__ */ new Set();
6193
6286
  const pendingParentsWithNoLinks = /* @__PURE__ */ new Set();
6194
6287
  const pendingParentsWithLinks = /* @__PURE__ */ new Set();
6195
- if (direction === "backward") {
6288
+ if (direction === CALCULATION_DIRECTION.BACKWARD) {
6196
6289
  const parentsWithFullProgressArray = getParentsWithFullProgress(allParentActivities);
6197
6290
  parentsWithFullProgressArray.forEach((activity) => {
6198
6291
  parentsWithFullProgress.add(activity.id);
@@ -6230,9 +6323,9 @@ function getParentsWithNoLinks(activities, direction, linkProperty) {
6230
6323
  }
6231
6324
  const hasLinks = links.length > 0;
6232
6325
  const constraintType = activity.constraint_type || "";
6233
- const isNotFnlt = constraintType !== "fnlt";
6234
- if (direction === "forward") {
6235
- const isNotSnet = constraintType !== "snet";
6326
+ const isNotFnlt = constraintType !== CONSTRAINT_TYPES.FNLT;
6327
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
6328
+ const isNotSnet = constraintType !== CONSTRAINT_TYPES.SNET;
6236
6329
  return !hasLinks && isNotFnlt && isNotSnet;
6237
6330
  } else {
6238
6331
  return !hasLinks && isNotFnlt;
@@ -6288,10 +6381,10 @@ function identifyForbiddenActivities({
6288
6381
  }
6289
6382
  }
6290
6383
  function getLinkProperty(direction) {
6291
- return direction === "forward" ? "$source" : "$target";
6384
+ return direction === CALCULATION_DIRECTION.FORWARD ? GANTT_FIELD.SOURCE : "$target";
6292
6385
  }
6293
6386
  function getLinkDirection(direction) {
6294
- return direction === "forward" ? "target" : "source";
6387
+ return direction === CALCULATION_DIRECTION.FORWARD ? "target" : "source";
6295
6388
  }
6296
6389
  function getArrayOfLinkedActivities2(gantt, links, direction) {
6297
6390
  return links.map((link) => {
@@ -6327,7 +6420,7 @@ function mutateDate({
6327
6420
  activityCalendar,
6328
6421
  activity
6329
6422
  }) {
6330
- if (linkType2 === LINK_TYPES2.FS && lag === 0) {
6423
+ if (linkType2 === LINK_TYPES3.FS && lag === 0) {
6331
6424
  return getNextWorkingHour({
6332
6425
  activityCalendar,
6333
6426
  direction: "future",
@@ -6363,10 +6456,10 @@ function calculateRestrictionSnet({
6363
6456
  return { es, ef };
6364
6457
  }
6365
6458
  function mutateTheDateToFutureOrPastInBaseRestriction(dateBaseToCalculate, restrictionOfLink, activityCalendar, activity) {
6366
- if (![LINK_TYPES2.FS, LINK_TYPES2.SS, LINK_TYPES2.FF].includes(restrictionOfLink)) {
6459
+ if (![LINK_TYPES3.FS, LINK_TYPES3.SS, LINK_TYPES3.FF].includes(restrictionOfLink)) {
6367
6460
  return dateBaseToCalculate;
6368
6461
  }
6369
- let constraintThatGoToNextWorkingHour = [LINK_TYPES2.FS, LINK_TYPES2.SS];
6462
+ let constraintThatGoToNextWorkingHour = [LINK_TYPES3.FS, LINK_TYPES3.SS];
6370
6463
  let direction = constraintThatGoToNextWorkingHour.includes(restrictionOfLink) ? "future" : "past";
6371
6464
  return getNextWorkingHour({
6372
6465
  dateBaseToCalculate,
@@ -6394,10 +6487,10 @@ var CalculateForwardParentsWithLinks = class {
6394
6487
  const calculationsFromLinks = this.calculateLinks();
6395
6488
  const maxEfFromLinks = getMaxEarlyStartSet(calculationsFromLinks);
6396
6489
  const constraintType = this.activity.constraint_type;
6397
- if (constraintType === "snet") {
6490
+ if (constraintType === CONSTRAINT_TYPES.SNET) {
6398
6491
  return this.handleSNETConstraint(maxEfFromLinks);
6399
6492
  }
6400
- if (constraintType === "fnlt") {
6493
+ if (constraintType === CONSTRAINT_TYPES.FNLT) {
6401
6494
  return this.handleFNLTConstraint(maxEfFromLinks);
6402
6495
  }
6403
6496
  return maxEfFromLinks;
@@ -6411,13 +6504,13 @@ var CalculateForwardParentsWithLinks = class {
6411
6504
  const predecessorEs = linkedActivity.es;
6412
6505
  const predecessorEf = linkedActivity.ef;
6413
6506
  let calculation = null;
6414
- if (linkType2 === "ss") {
6507
+ if (linkType2 === LINK_TYPES3.SS) {
6415
6508
  calculation = this.calculateSSLink({ lag, predecessorEs });
6416
- } else if (linkType2 === "ff") {
6509
+ } else if (linkType2 === LINK_TYPES3.FF) {
6417
6510
  calculation = this.calculateFFLink({ lag, predecessorEf });
6418
- } else if (linkType2 === "fs") {
6511
+ } else if (linkType2 === LINK_TYPES3.FS) {
6419
6512
  calculation = this.calculateFSLink({ lag, predecessorEf });
6420
- } else if (linkType2 === "sf") {
6513
+ } else if (linkType2 === LINK_TYPES3.SF) {
6421
6514
  calculation = this.calculateSFLink({
6422
6515
  lag,
6423
6516
  predecessorEs,
@@ -6462,7 +6555,7 @@ var CalculateForwardParentsWithLinks = class {
6462
6555
  }
6463
6556
  calculateSSLink({ lag, predecessorEs }) {
6464
6557
  const esLinked = mutateDate({
6465
- linkType: "ss",
6558
+ linkType: LINK_TYPES3.SS,
6466
6559
  lag,
6467
6560
  predecessorTime: predecessorEs,
6468
6561
  activityCalendar: this.activityCalendar,
@@ -6477,7 +6570,7 @@ var CalculateForwardParentsWithLinks = class {
6477
6570
  if (lag > 0) {
6478
6571
  es = mutateTheDateToFutureOrPastInBaseRestriction(
6479
6572
  es,
6480
- "ss",
6573
+ LINK_TYPES3.SS,
6481
6574
  this.activityCalendar,
6482
6575
  this.activity
6483
6576
  );
@@ -6492,7 +6585,7 @@ var CalculateForwardParentsWithLinks = class {
6492
6585
  }
6493
6586
  calculateFFLink({ lag, predecessorEf }) {
6494
6587
  const efLinked = mutateDate({
6495
- linkType: "ff",
6588
+ linkType: LINK_TYPES3.FF,
6496
6589
  lag,
6497
6590
  predecessorTime: predecessorEf,
6498
6591
  activityCalendar: this.activityCalendar,
@@ -6513,7 +6606,7 @@ var CalculateForwardParentsWithLinks = class {
6513
6606
  if (lag > 0) {
6514
6607
  es = mutateTheDateToFutureOrPastInBaseRestriction(
6515
6608
  es,
6516
- "ff",
6609
+ LINK_TYPES3.FF,
6517
6610
  this.activityCalendar,
6518
6611
  this.activity
6519
6612
  );
@@ -6560,7 +6653,7 @@ var CalculateForwardParentsWithLinks = class {
6560
6653
  if (lag > 0) {
6561
6654
  es = mutateTheDateToFutureOrPastInBaseRestriction(
6562
6655
  es,
6563
- "sf",
6656
+ LINK_TYPES3.SF,
6564
6657
  this.activityCalendar,
6565
6658
  this.activity
6566
6659
  );
@@ -6587,16 +6680,16 @@ var CalculateBackwardParentsLinks = class {
6587
6680
  const calculationsFromLinks = [];
6588
6681
  for (let linkedActivity of this.linkedActivitiesData) {
6589
6682
  const linkType2 = getLinkNameByCode(linkedActivity.linkType);
6590
- if (linkedActivity.type === "task" && Number(linkedActivity.progress) > 0) {
6683
+ if (linkedActivity.type === ACTIVITY_TYPE.TASK && Number(linkedActivity.progress) > 0) {
6591
6684
  continue;
6592
6685
  }
6593
- if (linkedActivity.type === "project" && Number(linkedActivity.progress) === 100) {
6686
+ if (linkedActivity.type === ACTIVITY_TYPE.PROJECT && Number(linkedActivity.progress) === 100) {
6594
6687
  continue;
6595
6688
  }
6596
6689
  const lag = linkedActivity.linkLag;
6597
6690
  let sucessorLs = linkedActivity.ls;
6598
6691
  let sucessorLf = linkedActivity.lf;
6599
- if (linkType2 === "ss") {
6692
+ if (linkType2 === LINK_TYPES3.SS) {
6600
6693
  const valuesToDoCalculation = {
6601
6694
  lag,
6602
6695
  workTime: sucessorLs,
@@ -6606,7 +6699,7 @@ var CalculateBackwardParentsLinks = class {
6606
6699
  let { ls, lf } = this.calculateSSLink(valuesToDoCalculation);
6607
6700
  calculationsFromLinks.push({ ls, lf });
6608
6701
  }
6609
- if (linkType2 === "ff") {
6702
+ if (linkType2 === LINK_TYPES3.FF) {
6610
6703
  const valuesToDoCalculation = {
6611
6704
  lag,
6612
6705
  workTime: sucessorLf,
@@ -6616,7 +6709,7 @@ var CalculateBackwardParentsLinks = class {
6616
6709
  let { ls, lf } = this.calculateFFLink(valuesToDoCalculation);
6617
6710
  calculationsFromLinks.push({ ls, lf });
6618
6711
  }
6619
- if (linkType2 === "fs") {
6712
+ if (linkType2 === LINK_TYPES3.FS) {
6620
6713
  const valuesToDoCalculation = {
6621
6714
  lag,
6622
6715
  workTime: sucessorLs,
@@ -6626,7 +6719,7 @@ var CalculateBackwardParentsLinks = class {
6626
6719
  let { ls, lf } = this.calculateFsLink(valuesToDoCalculation);
6627
6720
  calculationsFromLinks.push({ ls, lf });
6628
6721
  }
6629
- if (linkType2 === "sf") {
6722
+ if (linkType2 === LINK_TYPES3.SF) {
6630
6723
  const valuesToDoCalculation = {
6631
6724
  lag,
6632
6725
  workTime: sucessorLf,
@@ -6637,7 +6730,7 @@ var CalculateBackwardParentsLinks = class {
6637
6730
  calculationsFromLinks.push({ ls, lf });
6638
6731
  }
6639
6732
  }
6640
- if (this.activity.constraint_type === "fnlt") {
6733
+ if (this.activity.constraint_type === CONSTRAINT_TYPES.FNLT) {
6641
6734
  const maxLfFromLinks = this.getMinLfFromLinks(calculationsFromLinks);
6642
6735
  let restriction = this.calculateSfRestrictionDates();
6643
6736
  if (!maxLfFromLinks) {
@@ -6684,7 +6777,7 @@ var CalculateBackwardParentsLinks = class {
6684
6777
  lfSucessor = this.getLastWorkingHour(
6685
6778
  lfSucessor,
6686
6779
  this.activityCalendar,
6687
- "past"
6780
+ WORK_TIME_DIRECTION.PAST
6688
6781
  );
6689
6782
  }
6690
6783
  lfPred = addDurationToDate(
@@ -6714,7 +6807,7 @@ var CalculateBackwardParentsLinks = class {
6714
6807
  const lsSucessor2 = this.getLastWorkingHour(
6715
6808
  workTime,
6716
6809
  this.activityCalendar,
6717
- "past"
6810
+ WORK_TIME_DIRECTION.PAST
6718
6811
  );
6719
6812
  lfPred = addDurationToDate(
6720
6813
  this.activityCalendar,
@@ -6722,7 +6815,7 @@ var CalculateBackwardParentsLinks = class {
6722
6815
  lfDataCalculation,
6723
6816
  this.activity
6724
6817
  );
6725
- lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, "past");
6818
+ lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, WORK_TIME_DIRECTION.PAST);
6726
6819
  lsPred = addDurationToDate(
6727
6820
  this.activityCalendar,
6728
6821
  lfPred,
@@ -6748,7 +6841,7 @@ var CalculateBackwardParentsLinks = class {
6748
6841
  this.activity
6749
6842
  );
6750
6843
  if (!isMilestone) {
6751
- lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, "past");
6844
+ lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, WORK_TIME_DIRECTION.PAST);
6752
6845
  }
6753
6846
  return { ls: lsPred, lf: lfPred };
6754
6847
  }
@@ -6835,10 +6928,10 @@ var CalculateBackwardParentsLinks = class {
6835
6928
  );
6836
6929
  return { ls: lsRestriction, lf: lfRestriction };
6837
6930
  }
6838
- getLastWorkingHour(date2, activityCalendar, dir = "past") {
6931
+ getLastWorkingHour(date2, activityCalendar, dir = WORK_TIME_DIRECTION.PAST) {
6839
6932
  const normalizedDate = date2 instanceof Date ? date2 : new Date(date2);
6840
6933
  let resetedDate = moment_default(normalizedDate).clone();
6841
- if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === "past") {
6934
+ if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === WORK_TIME_DIRECTION.PAST) {
6842
6935
  resetedDate = resetedDate.hours(0).minutes(0).seconds(0).milliseconds(0);
6843
6936
  }
6844
6937
  let newDate = getNextWorkingHour({
@@ -6884,7 +6977,7 @@ function parentWithLinks(params) {
6884
6977
  const linksArray = parent[linkProperty];
6885
6978
  const parentData = extractParentData(parent);
6886
6979
  let calculation = null;
6887
- if (direction === "forward") {
6980
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
6888
6981
  const linksWithActivityData = getLinksWithActivityDataForward(
6889
6982
  linksArray,
6890
6983
  linkDirection,
@@ -7002,7 +7095,7 @@ function getCalculatedChildren(childrenIds, calculations) {
7002
7095
  return childrenIds.filter((childId) => calculations.has(childId)).map((childId) => calculations.get(childId));
7003
7096
  }
7004
7097
  function computeParentCalculation(childrenCalculations, direction) {
7005
- if (direction === "forward") {
7098
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
7006
7099
  const earliestStart = calculateEarliestDate(childrenCalculations, "es");
7007
7100
  const latestFinish = calculateLatestDate(childrenCalculations, "ef");
7008
7101
  return { es: earliestStart, ef: latestFinish };
@@ -7034,8 +7127,8 @@ var CalculationOfParent = class {
7034
7127
  constructor(params) {
7035
7128
  this.activity = params.activity;
7036
7129
  this.direction = params.direction;
7037
- this.linkProperty = params.direction === "forward" ? "$target" : "$source";
7038
- this.linkDirection = params.direction === "forward" ? "source" : "target";
7130
+ this.linkProperty = params.direction === CALCULATION_DIRECTION.FORWARD ? "$target" : GANTT_FIELD.SOURCE;
7131
+ this.linkDirection = params.direction === CALCULATION_DIRECTION.FORWARD ? "source" : "target";
7039
7132
  this.calculationsOfParentThatImpactChildrens = params.calculationsOfParentThatImpactChildrens;
7040
7133
  this.calculations = params.calculations;
7041
7134
  this.calculationOfParentsFromLinks = params.calculationOfParentsFromLinks;
@@ -7049,7 +7142,7 @@ var CalculationOfParent = class {
7049
7142
  const allLinkedTasks = this.getArrayOfIdOfLinkedActivities(
7050
7143
  this.activity[this.linkProperty]
7051
7144
  );
7052
- if (this.direction === "backward") {
7145
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
7053
7146
  const restrictions = [CONSTRAINT_TYPES.FNLT];
7054
7147
  if (this.shouldCalculateParentWithLinksBackward(restrictions)) {
7055
7148
  this.calculateAndStoreParentWithLinks(this.activity);
@@ -7062,10 +7155,10 @@ var CalculationOfParent = class {
7062
7155
  }
7063
7156
  const areAllLinksCalculated = this.areAllLinksCalculated(allLinkedTasks);
7064
7157
  if (areAllLinksCalculated && this.calculationsOfParentThatImpactChildrens.has(this.activity.id)) {
7065
- if (this.direction === "forward") {
7158
+ if (this.direction === CALCULATION_DIRECTION.FORWARD) {
7066
7159
  this.setDatesToParentsWithLinks();
7067
7160
  }
7068
- if (this.direction === "backward") {
7161
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
7069
7162
  this.setDatesToParentsWithLinksBackward();
7070
7163
  }
7071
7164
  return;
@@ -7266,7 +7359,7 @@ var ThirdLevelActivityIdentifier = class {
7266
7359
  this.addActivityToLevel(activity, activitiesByLevel);
7267
7360
  }
7268
7361
  isProjectActivity(activity) {
7269
- return activity.type === "project";
7362
+ return activity.type === ACTIVITY_TYPE.PROJECT;
7270
7363
  }
7271
7364
  hasLink(activity) {
7272
7365
  return Boolean(activity[this.linkProperty]?.length);
@@ -7335,8 +7428,8 @@ var CriticalPathHelpers = class {
7335
7428
  constructor(ganttInstace, direction) {
7336
7429
  this.direction = direction;
7337
7430
  this.gantt = ganttInstace;
7338
- this.linkProperty = this.direction === "forward" ? "$target" : "$source";
7339
- this.linkDirection = this.direction === "forward" ? "source" : "target";
7431
+ this.linkProperty = this.direction === CALCULATION_DIRECTION.FORWARD ? "$target" : GANTT_FIELD.SOURCE;
7432
+ this.linkDirection = this.direction === CALCULATION_DIRECTION.FORWARD ? "source" : "target";
7340
7433
  this.projectDates = ganttInstace.getSubtaskDates();
7341
7434
  }
7342
7435
  tryToCalculateLastLevelChildrens() {
@@ -7428,7 +7521,7 @@ var CriticalPathHelpers = class {
7428
7521
  function(activity) {
7429
7522
  const parentId = Number(activity.parent);
7430
7523
  allTasks.add(activity.id);
7431
- if (activity.type === "project") {
7524
+ if (activity.type === ACTIVITY_TYPE.PROJECT) {
7432
7525
  const parentInfo = {
7433
7526
  level: activity["$level"],
7434
7527
  hasLink: Boolean(activity[this.linkProperty].length),
@@ -7449,7 +7542,7 @@ var CriticalPathHelpers = class {
7449
7542
  }
7450
7543
  level.get(Number(activity.parent)).push({
7451
7544
  id: activity.id,
7452
- isParent: activity.type === "project",
7545
+ isParent: activity.type === ACTIVITY_TYPE.PROJECT,
7453
7546
  calculated: false
7454
7547
  });
7455
7548
  }.bind(this),
@@ -7499,7 +7592,7 @@ var CriticalPathHelpers = class {
7499
7592
  }
7500
7593
  calculateSecondLevelActivities() {
7501
7594
  try {
7502
- if (this.direction === "forward") {
7595
+ if (this.direction === CALCULATION_DIRECTION.FORWARD) {
7503
7596
  this.recursiveCalculateEfAndEs(
7504
7597
  Array.from(this.secondLevelActivities),
7505
7598
  0,
@@ -7517,12 +7610,12 @@ var CriticalPathHelpers = class {
7517
7610
  this.chainStartActivities.forEach((activity) => {
7518
7611
  if (!activity) return;
7519
7612
  if (activity.progress > 100) return;
7520
- if (activity.type === "project") return;
7613
+ if (activity.type === ACTIVITY_TYPE.PROJECT) return;
7521
7614
  const dates = this.calculateStartAndFinishOfChainOrigin(
7522
7615
  activity,
7523
7616
  this.direction
7524
7617
  );
7525
- if (this.direction === "forward") {
7618
+ if (this.direction === CALCULATION_DIRECTION.FORWARD) {
7526
7619
  let { es, ef } = dates;
7527
7620
  this.calculations.set(activity.id, { es, ef, text: activity.text });
7528
7621
  this.activitiesWaitingForCalculation.delete(activity.id);
@@ -7603,7 +7696,7 @@ var CriticalPathHelpers = class {
7603
7696
  );
7604
7697
  }
7605
7698
  let direction = customDirection || this.direction;
7606
- if (direction === "forward") {
7699
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
7607
7700
  let es = activity.start_date;
7608
7701
  let ef = activity.end_date;
7609
7702
  return {
@@ -7714,14 +7807,14 @@ var CriticalPathHelpers = class {
7714
7807
  }
7715
7808
  );
7716
7809
  arrayOfActivitiesObject.forEach((activity) => {
7717
- const isAParent = activity.type === "project";
7810
+ const isAParent = activity.type === ACTIVITY_TYPE.PROJECT;
7718
7811
  this.setDatesForActivityWithFullProgress(activity);
7719
7812
  this.activitiesWaitingForCalculation.delete(activity.id);
7720
7813
  if (isAParent && this.pendingParentsWithLinks.has(activity.id)) {
7721
7814
  this.parentCalculationFromChildren.add(activity.id);
7722
7815
  this.calculationsOfParentThatImpactChildrens.set(activity.id, {
7723
- [this.direction === "forward" ? "es" : "ls"]: activity.start_date,
7724
- [this.direction === "forward" ? "ef" : "lf"]: activity.end_date
7816
+ [this.direction === CALCULATION_DIRECTION.FORWARD ? "es" : "ls"]: activity.start_date,
7817
+ [this.direction === CALCULATION_DIRECTION.FORWARD ? "ef" : "lf"]: activity.end_date
7725
7818
  });
7726
7819
  this.calculationOfParentsFromLinks.add(activity.id);
7727
7820
  }
@@ -7816,7 +7909,7 @@ var LinksRulesCalculationsMethods = class {
7816
7909
  }
7817
7910
  return this.calculatedActivities.get(Number(activity));
7818
7911
  }
7819
- calculateSucessorTimes(predecessorTime, esDataCalculation, efDataCalculation = 0, lag, restrictionOfLink = LINK_TYPES2.FS) {
7912
+ calculateSucessorTimes(predecessorTime, esDataCalculation, efDataCalculation = 0, lag, restrictionOfLink = LINK_TYPES3.FS) {
7820
7913
  const activityCalendar = this.gantt.getCalendar(
7821
7914
  this.referenceActivity.calendar_id
7822
7915
  );
@@ -7828,9 +7921,9 @@ var LinksRulesCalculationsMethods = class {
7828
7921
  let dateBaseToCalculate = predecessorTime;
7829
7922
  let es = null;
7830
7923
  let ef = null;
7831
- const isAMilestone = this.referenceActivity.type === "milestone";
7924
+ const isAMilestone = this.referenceActivity.type === ACTIVITY_TYPE.MILESTONE;
7832
7925
  if (!isAMilestone) {
7833
- if (restrictionOfLink === LINK_TYPES2.FS && lag === 0) {
7926
+ if (restrictionOfLink === LINK_TYPES3.FS && lag === 0) {
7834
7927
  dateBaseToCalculate = getNextWorkingHour({
7835
7928
  dateBaseToCalculate,
7836
7929
  activityCalendar,
@@ -7845,7 +7938,7 @@ var LinksRulesCalculationsMethods = class {
7845
7938
  );
7846
7939
  }
7847
7940
  }
7848
- if ([LINK_TYPES2.FF, LINK_TYPES2.SF].includes(restrictionOfLink)) {
7941
+ if ([LINK_TYPES3.FF, LINK_TYPES3.SF].includes(restrictionOfLink)) {
7849
7942
  ef = addDurationToDate(
7850
7943
  activityCalendar,
7851
7944
  dateBaseToCalculate,
@@ -7899,7 +7992,7 @@ var LinksRulesCalculationsMethods = class {
7899
7992
  esDataCalculation,
7900
7993
  efDataCalculation,
7901
7994
  lag,
7902
- LINK_TYPES2.SS
7995
+ LINK_TYPES3.SS
7903
7996
  );
7904
7997
  }
7905
7998
  calculateFF(link) {
@@ -7913,7 +8006,7 @@ var LinksRulesCalculationsMethods = class {
7913
8006
  esDataCalculation,
7914
8007
  efDataCalculation,
7915
8008
  lag,
7916
- LINK_TYPES2.FF
8009
+ LINK_TYPES3.FF
7917
8010
  );
7918
8011
  }
7919
8012
  calculateFS(link) {
@@ -7927,7 +8020,7 @@ var LinksRulesCalculationsMethods = class {
7927
8020
  esDataCalculation,
7928
8021
  efDataCalculation,
7929
8022
  lag,
7930
- LINK_TYPES2.FS
8023
+ LINK_TYPES3.FS
7931
8024
  );
7932
8025
  }
7933
8026
  calculateSF(link) {
@@ -7941,17 +8034,17 @@ var LinksRulesCalculationsMethods = class {
7941
8034
  esDataCalculation,
7942
8035
  efDataCalculation,
7943
8036
  lag,
7944
- LINK_TYPES2.SF
8037
+ LINK_TYPES3.SF
7945
8038
  );
7946
8039
  }
7947
8040
  mutateTheDateToFutureOrPastInBaseRestriction(dateBaseToCalculate, restrictionOfLink, activityCalendar) {
7948
- if (![LINK_TYPES2.FS, LINK_TYPES2.SS, LINK_TYPES2.FF].includes(restrictionOfLink)) {
8041
+ if (![LINK_TYPES3.FS, LINK_TYPES3.SS, LINK_TYPES3.FF].includes(restrictionOfLink)) {
7949
8042
  return dateBaseToCalculate;
7950
8043
  }
7951
- const constraintThatGoToNextWorkingHour = [LINK_TYPES2.FS, LINK_TYPES2.SS];
8044
+ const constraintThatGoToNextWorkingHour = [LINK_TYPES3.FS, LINK_TYPES3.SS];
7952
8045
  const direction = constraintThatGoToNextWorkingHour.includes(
7953
8046
  restrictionOfLink
7954
- ) ? "future" : "past";
8047
+ ) ? "future" : WORK_TIME_DIRECTION.PAST;
7955
8048
  return getNextWorkingHour({
7956
8049
  dateBaseToCalculate,
7957
8050
  activityCalendar,
@@ -8032,7 +8125,7 @@ var ActivityCalculator = class {
8032
8125
  const pendingActivities = new Set(pendingToCalculate);
8033
8126
  for (const activityId of pendingToCalculate) {
8034
8127
  const activityData = this.gantt.getTask(activityId);
8035
- if (activityData.type === "project") {
8128
+ if (activityData.type === ACTIVITY_TYPE.PROJECT) {
8036
8129
  this.handleProjectActivity(
8037
8130
  activityId,
8038
8131
  activityData,
@@ -8096,7 +8189,7 @@ var ActivityCalculator = class {
8096
8189
  canCalculateParentActivity(activityData) {
8097
8190
  const hasNoLinks = (activityData[this.linkProperty] || []).length === 0;
8098
8191
  const constraintType = activityData.constraint_type;
8099
- const isSpecialConstraintType = this.direction === "forward" ? constraintType === "fnlt" || constraintType === "snlt" : constraintType === "fnlt";
8192
+ const isSpecialConstraintType = this.direction === CALCULATION_DIRECTION.FORWARD ? constraintType === CONSTRAINT_TYPES.FNLT || constraintType === CONSTRAINT_TYPES.SNLT : constraintType === CONSTRAINT_TYPES.FNLT;
8100
8193
  if (isSpecialConstraintType && hasNoLinks) {
8101
8194
  return true;
8102
8195
  }
@@ -8114,13 +8207,13 @@ var ActivityCalculator = class {
8114
8207
  if (isParentPendingWithLinks && !hasParentCalculationFromLinks) {
8115
8208
  return;
8116
8209
  }
8117
- if (this.direction === "backward") {
8210
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
8118
8211
  const isStartChainChildOfLinkedParent = this.activitiesStartChainButChildrenOfLinkedParents.has(activityId);
8119
8212
  if (isStartChainChildOfLinkedParent && !hasParentCalculationFromLinks) {
8120
8213
  return;
8121
8214
  }
8122
8215
  }
8123
- if (activityData["$target"].length === 0 && activityData["$source"].length === 0) {
8216
+ if (activityData["$target"].length === 0 && activityData[GANTT_FIELD.SOURCE].length === 0) {
8124
8217
  activitiesThatCanBeCalculated.add(activityId);
8125
8218
  pendingActivities.delete(activityId);
8126
8219
  return;
@@ -8131,7 +8224,7 @@ var ActivityCalculator = class {
8131
8224
  const arePredecessorsCalculated = linkedActivities.every(
8132
8225
  (act) => this.calculations.has(act.id)
8133
8226
  );
8134
- if (this.direction === "backward") {
8227
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
8135
8228
  const hasNoLinkedActivities = linkedActivities.length === 0;
8136
8229
  if ((hasNoLinkedActivities || arePredecessorsCalculated) && hasParentCalculationFromLinks) {
8137
8230
  activitiesThatCanBeCalculated.add(activityId);
@@ -8183,7 +8276,7 @@ var get_activities_to_calculate_default = ActivityCalculator;
8183
8276
  var createIsCurrent2 = (calculationId, getCurrentId) => () => getCurrentId() === calculationId;
8184
8277
 
8185
8278
  // src/critical-path/legacy/utils/validation.js
8186
- var shouldAbortCalculation = (gantt) => !gantt?.fullyParsed || typeof window !== "undefined" && window.to_use_react_gantt?.conversionMode?.isActive;
8279
+ var shouldAbortCalculation = (gantt) => !gantt?.fullyParsed;
8187
8280
 
8188
8281
  // src/critical-path/legacy/utils/timing.js
8189
8282
  var TIME_BUDGET_MS = 16;
@@ -8234,7 +8327,7 @@ var iterativeCalculate = async ({
8234
8327
  // src/critical-path/legacy/forward-path/index.js
8235
8328
  var ForwardPath = class extends generic_calculations_default {
8236
8329
  constructor(gantt) {
8237
- super(gantt, "forward");
8330
+ super(gantt, CALCULATION_DIRECTION.FORWARD);
8238
8331
  this.gantt = gantt;
8239
8332
  this.chainStartActivities = /* @__PURE__ */ new Set();
8240
8333
  this.secondLevelActivities = /* @__PURE__ */ new Set();
@@ -8299,7 +8392,7 @@ var ForwardPath = class extends generic_calculations_default {
8299
8392
  calculateStartAndFinishTimes(activitiesToCalculate) {
8300
8393
  activitiesToCalculate.forEach((activity) => {
8301
8394
  const activityReference = this.gantt.getTask(activity);
8302
- if (activityReference.type === "project") {
8395
+ if (activityReference.type === ACTIVITY_TYPE.PROJECT) {
8303
8396
  return this.doCalculationForParentType(activityReference);
8304
8397
  }
8305
8398
  if (!activityReference) {
@@ -8418,11 +8511,11 @@ var ForwardPath = class extends generic_calculations_default {
8418
8511
  this.activitiesWaitingForCalculation.delete(activity);
8419
8512
  });
8420
8513
  }
8421
- getTheGreatesDateBetweenRestrictionAndEsEf(restriction, linkCalculation, comparisonType = "greater") {
8422
- if (comparisonType === "greater") {
8514
+ getTheGreatesDateBetweenRestrictionAndEsEf(restriction, linkCalculation, comparisonType = COMPARISON_DIRECTION.GREATER) {
8515
+ if (comparisonType === COMPARISON_DIRECTION.GREATER) {
8423
8516
  return linkCalculation.ef > restriction.ef ? linkCalculation : restriction;
8424
8517
  }
8425
- if (comparisonType === "less") {
8518
+ if (comparisonType === COMPARISON_DIRECTION.LESS) {
8426
8519
  return linkCalculation.ef < restriction.ef ? linkCalculation : restriction;
8427
8520
  }
8428
8521
  }
@@ -8442,7 +8535,7 @@ var ForwardPath = class extends generic_calculations_default {
8442
8535
  const comparisontype = [
8443
8536
  CONSTRAINT_TYPES.SNET,
8444
8537
  CONSTRAINT_TYPES.FNET
8445
- ].includes(constraintType) ? "greater" : "less";
8538
+ ].includes(constraintType) ? COMPARISON_DIRECTION.GREATER : COMPARISON_DIRECTION.LESS;
8446
8539
  const { es, ef } = this.getTheGreatesDateBetweenRestrictionAndEsEf(
8447
8540
  calculatedRestriction,
8448
8541
  calculatedEsEf,
@@ -8458,9 +8551,9 @@ var ForwardPath = class extends generic_calculations_default {
8458
8551
  }
8459
8552
  const sourceId = ganttActivityLink.source;
8460
8553
  const targetId = ganttActivityLink.target;
8461
- if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === "project")
8554
+ if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === ACTIVITY_TYPE.PROJECT)
8462
8555
  return;
8463
- if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === "project")
8556
+ if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === ACTIVITY_TYPE.PROJECT)
8464
8557
  return;
8465
8558
  return link;
8466
8559
  }).filter(Boolean);
@@ -8483,7 +8576,7 @@ var CalculationsGenericMethods = class {
8483
8576
  }
8484
8577
  return this.calculatedActivities.get(activity);
8485
8578
  }
8486
- calculateSuccessorTimes(sucessorTime, lsDataCalculation, lfDataCalculation = 0, lag, type = LINK_TYPES2.FS) {
8579
+ calculateSuccessorTimes(sucessorTime, lsDataCalculation, lfDataCalculation = 0, lag, type = LINK_TYPES3.FS) {
8487
8580
  let activityCalendar = this.gantt.getCalendar(this.activity.calendar_id);
8488
8581
  if (!activityCalendar) {
8489
8582
  throw new Error(
@@ -8491,7 +8584,7 @@ var CalculationsGenericMethods = class {
8491
8584
  );
8492
8585
  }
8493
8586
  const workTime = sucessorTime;
8494
- let isMilestone = this.activity.type === "milestone";
8587
+ let isMilestone = this.activity.type === ACTIVITY_TYPE.MILESTONE;
8495
8588
  if (isMilestone && lag === 0) {
8496
8589
  let lsPred = addDurationToDate(
8497
8590
  activityCalendar,
@@ -8515,19 +8608,19 @@ var CalculationsGenericMethods = class {
8515
8608
  lfDataCalculation,
8516
8609
  isMilestone
8517
8610
  };
8518
- if (type === LINK_TYPES2.FS) {
8611
+ if (type === LINK_TYPES3.FS) {
8519
8612
  let { ls, lf } = this.calculateFsLink(valuesToDoCalculation);
8520
8613
  return { ls, lf };
8521
8614
  }
8522
- if (type === LINK_TYPES2.FF) {
8615
+ if (type === LINK_TYPES3.FF) {
8523
8616
  let { ls, lf } = this.calculateFFLink(valuesToDoCalculation);
8524
8617
  return { ls, lf };
8525
8618
  }
8526
- if (type === LINK_TYPES2.SS) {
8619
+ if (type === LINK_TYPES3.SS) {
8527
8620
  let { ls, lf } = this.calculateSSlink(valuesToDoCalculation);
8528
8621
  return { ls, lf };
8529
8622
  }
8530
- if (type === LINK_TYPES2.SF) {
8623
+ if (type === LINK_TYPES3.SF) {
8531
8624
  let { ls, lf } = this.calculateSFLink(valuesToDoCalculation);
8532
8625
  return { ls, lf };
8533
8626
  }
@@ -8542,7 +8635,7 @@ var CalculationsGenericMethods = class {
8542
8635
  lsDataForCalculation,
8543
8636
  lfDataForCalculation,
8544
8637
  lag,
8545
- LINK_TYPES2.SS
8638
+ LINK_TYPES3.SS
8546
8639
  );
8547
8640
  }
8548
8641
  calculateFF(link, constraint) {
@@ -8559,7 +8652,7 @@ var CalculationsGenericMethods = class {
8559
8652
  lsDataForCalculation,
8560
8653
  lfDataForCalculation,
8561
8654
  lag,
8562
- LINK_TYPES2.FF
8655
+ LINK_TYPES3.FF
8563
8656
  );
8564
8657
  }
8565
8658
  calculateFS(link, constraint) {
@@ -8577,7 +8670,7 @@ var CalculationsGenericMethods = class {
8577
8670
  lsDataForCalculation,
8578
8671
  lfDataForCalculation,
8579
8672
  lag,
8580
- LINK_TYPES2.FS
8673
+ LINK_TYPES3.FS
8581
8674
  );
8582
8675
  }
8583
8676
  calculateSF(link, getFromForward = false) {
@@ -8590,7 +8683,7 @@ var CalculationsGenericMethods = class {
8590
8683
  lsDataForCalculation,
8591
8684
  lfDataForCalculation,
8592
8685
  lag,
8593
- LINK_TYPES2.SF
8686
+ LINK_TYPES3.SF
8594
8687
  );
8595
8688
  }
8596
8689
  getEarlyStartFromForwardPath(link) {
@@ -8613,10 +8706,10 @@ var CalculationsGenericMethods = class {
8613
8706
  this.activity
8614
8707
  );
8615
8708
  }
8616
- getLastWorkingHour(date2, activityCalendar, dir = "past") {
8709
+ getLastWorkingHour(date2, activityCalendar, dir = WORK_TIME_DIRECTION.PAST) {
8617
8710
  const normalizedDate = date2 instanceof Date ? date2 : new Date(date2);
8618
8711
  let resetedDate = moment_default(normalizedDate).clone();
8619
- if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === "past") {
8712
+ if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === WORK_TIME_DIRECTION.PAST) {
8620
8713
  resetedDate = resetedDate.hours(0).minutes(0).seconds(0).milliseconds(0);
8621
8714
  }
8622
8715
  let newDate = getNextWorkingHour({
@@ -8659,7 +8752,7 @@ var CalculationsGenericMethods = class {
8659
8752
  const lsSucessor2 = this.getLastWorkingHour(
8660
8753
  workTime,
8661
8754
  activityCalendar,
8662
- "past"
8755
+ WORK_TIME_DIRECTION.PAST
8663
8756
  );
8664
8757
  lfPred = addDurationToDate(
8665
8758
  activityCalendar,
@@ -8667,7 +8760,7 @@ var CalculationsGenericMethods = class {
8667
8760
  lfDataCalculation,
8668
8761
  this.activity
8669
8762
  );
8670
- lfPred = this.getLastWorkingHour(lfPred, activityCalendar, "past");
8763
+ lfPred = this.getLastWorkingHour(lfPred, activityCalendar, WORK_TIME_DIRECTION.PAST);
8671
8764
  lsPred = addDurationToDate(
8672
8765
  activityCalendar,
8673
8766
  lfPred,
@@ -8693,7 +8786,7 @@ var CalculationsGenericMethods = class {
8693
8786
  this.activity
8694
8787
  );
8695
8788
  if (!isMilestone) {
8696
- lfPred = this.getLastWorkingHour(lfPred, activityCalendar, "past", true);
8789
+ lfPred = this.getLastWorkingHour(lfPred, activityCalendar, WORK_TIME_DIRECTION.PAST, true);
8697
8790
  }
8698
8791
  return { ls: lsPred, lf: lfPred };
8699
8792
  }
@@ -8726,7 +8819,7 @@ var CalculationsGenericMethods = class {
8726
8819
  lfSucessor = this.getLastWorkingHour(
8727
8820
  lfSucessor,
8728
8821
  activityCalendar,
8729
- "past"
8822
+ WORK_TIME_DIRECTION.PAST
8730
8823
  );
8731
8824
  }
8732
8825
  lfPred = addDurationToDate(
@@ -8840,7 +8933,7 @@ var LinksConstraintCalculator2 = class extends CalculationsGenericMethods_defaul
8840
8933
  if (this.links.length === 0) {
8841
8934
  return new generic_calculations_default(
8842
8935
  this.gantt,
8843
- "backward"
8936
+ CALCULATION_DIRECTION.BACKWARD
8844
8937
  ).calculateStartAndFinishOfChainOrigin(this.activity);
8845
8938
  }
8846
8939
  let activityProgressMajorThanZeroButLessThanOneHundred = this.activity.progress > 0 && this.activity.progress < 100;
@@ -8952,7 +9045,7 @@ var LinksConstraintCalculator2 = class extends CalculationsGenericMethods_defaul
8952
9045
  if (!activityFromLink) {
8953
9046
  return;
8954
9047
  }
8955
- if (activityFromLink.progress > 0 && activityFromLink.type !== "project") {
9048
+ if (activityFromLink.progress > 0 && activityFromLink.type !== ACTIVITY_TYPE.PROJECT) {
8956
9049
  return;
8957
9050
  }
8958
9051
  const specialParamForFS = this.getSpecialCalculationParamForConstraintLink();
@@ -9085,7 +9178,7 @@ var restrictionCalculation_default2 = calculateRestriction3;
9085
9178
  // src/critical-path/legacy/backward-path/index.js
9086
9179
  var BackwardPath = class extends generic_calculations_default {
9087
9180
  constructor(ganttInstance, forwardPathCalculations, forwardConstraintsMap) {
9088
- super(ganttInstance, "backward");
9181
+ super(ganttInstance, CALCULATION_DIRECTION.BACKWARD);
9089
9182
  this.gantt = ganttInstance;
9090
9183
  this.chainStartActivities = /* @__PURE__ */ new Set();
9091
9184
  this.secondLevelActivities = /* @__PURE__ */ new Set();
@@ -9204,7 +9297,7 @@ var BackwardPath = class extends generic_calculations_default {
9204
9297
  activityReference
9205
9298
  );
9206
9299
  }
9207
- if (activityReference.type === "project") {
9300
+ if (activityReference.type === ACTIVITY_TYPE.PROJECT) {
9208
9301
  return this.doCalculationForParentType(activityReference);
9209
9302
  }
9210
9303
  if (progress === 100) {
@@ -9285,7 +9378,7 @@ var BackwardPath = class extends generic_calculations_default {
9285
9378
  if (!activityData) {
9286
9379
  continue;
9287
9380
  }
9288
- if (activityData.type === "project") {
9381
+ if (activityData.type === ACTIVITY_TYPE.PROJECT) {
9289
9382
  allLinkedHasProgress = false;
9290
9383
  }
9291
9384
  if (activityData.progress === 0) {
@@ -9304,7 +9397,7 @@ var BackwardPath = class extends generic_calculations_default {
9304
9397
  const parent = Number(activity.parent);
9305
9398
  let { ls, lf } = this.calculateStartAndFinishOfChainOrigin(
9306
9399
  activity,
9307
- "backward"
9400
+ CALCULATION_DIRECTION.BACKWARD
9308
9401
  );
9309
9402
  if (this.calculationsOfParentThatImpactChildrens.has(parent)) {
9310
9403
  ls = activity.start_date;
@@ -9373,9 +9466,9 @@ var BackwardPath = class extends generic_calculations_default {
9373
9466
  return links.map((link) => {
9374
9467
  let sourceId = this.gantt.getLink(link).source;
9375
9468
  let targetId = this.gantt.getLink(link).target;
9376
- if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === "project")
9469
+ if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === ACTIVITY_TYPE.PROJECT)
9377
9470
  return;
9378
- if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === "project")
9471
+ if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === ACTIVITY_TYPE.PROJECT)
9379
9472
  return;
9380
9473
  return link;
9381
9474
  }).filter(Boolean);
@@ -10077,7 +10170,7 @@ var CriticalPath = class {
10077
10170
  var legacy_default = CriticalPath;
10078
10171
 
10079
10172
  // src/critical-path/gantt-adapter.ts
10080
- var isFinishConstraint = (type) => type === "fnet" || type === "fnlt" || type === "mfo";
10173
+ var isFinishConstraint = (type) => type === CONSTRAINT_TYPE.FNET || type === CONSTRAINT_TYPE.FNLT || type === CONSTRAINT_TYPE.MFO;
10081
10174
  var startOfUtcDay3 = (date2) => new Date(
10082
10175
  Date.UTC(date2.getUTCFullYear(), date2.getUTCMonth(), date2.getUTCDate())
10083
10176
  );
@@ -10559,38 +10652,38 @@ var NON_SCHEDULING_INLINE_COLUMNS = /* @__PURE__ */ new Set([
10559
10652
  COLUMN.TAGS
10560
10653
  ]);
10561
10654
  var NON_SCHEDULING_KINDS = /* @__PURE__ */ new Set([
10562
- "activity-clipboard-clear",
10563
- "activity-copy",
10564
- "selection-toggle",
10565
- "selection-replace",
10566
- "visibility-set",
10567
- "filter-set",
10568
- "sort-set",
10569
- "sir-sync",
10570
- "activity-lookahead-sync",
10571
- "persistence-acknowledge",
10572
- "baseline-apply",
10573
- "ponderator-criterion-set",
10574
- "status-criteria-set"
10655
+ DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR,
10656
+ DISPATCH_ACTION_KIND.ACTIVITY_COPY,
10657
+ DISPATCH_ACTION_KIND.SELECTION_TOGGLE,
10658
+ DISPATCH_ACTION_KIND.SELECTION_REPLACE,
10659
+ DISPATCH_ACTION_KIND.VISIBILITY_SET,
10660
+ DISPATCH_ACTION_KIND.FILTER_SET,
10661
+ DISPATCH_ACTION_KIND.SORT_SET,
10662
+ DISPATCH_ACTION_KIND.SIR_SYNC,
10663
+ DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC,
10664
+ DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE,
10665
+ DISPATCH_ACTION_KIND.BASELINE_APPLY,
10666
+ DISPATCH_ACTION_KIND.PONDERATOR_CRITERION_SET,
10667
+ DISPATCH_ACTION_KIND.STATUS_CRITERIA_SET
10575
10668
  ]);
10576
10669
  var PURE_VIEW_STATE_KINDS = /* @__PURE__ */ new Set([
10577
- "activity-clipboard-clear",
10578
- "activity-copy",
10579
- "selection-toggle",
10580
- "selection-replace",
10581
- "visibility-set",
10582
- "filter-set",
10583
- "sort-set"
10670
+ DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR,
10671
+ DISPATCH_ACTION_KIND.ACTIVITY_COPY,
10672
+ DISPATCH_ACTION_KIND.SELECTION_TOGGLE,
10673
+ DISPATCH_ACTION_KIND.SELECTION_REPLACE,
10674
+ DISPATCH_ACTION_KIND.VISIBILITY_SET,
10675
+ DISPATCH_ACTION_KIND.FILTER_SET,
10676
+ DISPATCH_ACTION_KIND.SORT_SET
10584
10677
  ]);
10585
10678
  function reappliesViewState(action) {
10586
10679
  return !PURE_VIEW_STATE_KINDS.has(action.kind);
10587
10680
  }
10588
10681
  var NO_STRUCTURAL_EXEMPTIONS = /* @__PURE__ */ new Set();
10589
10682
  function editsOnlyNonSchedulingColumns(action) {
10590
- if (action.kind === "inline-edit") {
10683
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT) {
10591
10684
  return NON_SCHEDULING_INLINE_COLUMNS.has(action.column);
10592
10685
  }
10593
- if (action.kind === "bulk-edit") {
10686
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
10594
10687
  return action.edits.every(
10595
10688
  (edit) => NON_SCHEDULING_INLINE_COLUMNS.has(edit.column)
10596
10689
  );
@@ -10604,13 +10697,13 @@ function isSchedulingDispatch(action, structuralStaleKinds) {
10604
10697
  return true;
10605
10698
  }
10606
10699
  function dispatchChangesSchedulingState(action) {
10607
- if (action.kind === "activity-lookahead-sync") {
10700
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC) {
10608
10701
  return action.persistedProgress !== void 0;
10609
10702
  }
10610
10703
  return isSchedulingDispatch(action, NO_STRUCTURAL_EXEMPTIONS);
10611
10704
  }
10612
10705
  function resolveRunCriticalPath(action) {
10613
- if (action.kind === "activity-lookahead-sync") {
10706
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC) {
10614
10707
  return action.persistedProgress !== void 0;
10615
10708
  }
10616
10709
  return isSchedulingDispatch(
@@ -10625,9 +10718,11 @@ function resolveRunExpectedProgress(action) {
10625
10718
  );
10626
10719
  }
10627
10720
  function dispatchChangesProgress(action) {
10628
- if (action.kind === "activity-set-progress") return true;
10629
- if (action.kind === "inline-edit") return action.column === COLUMN.PROGRESS;
10630
- if (action.kind === "bulk-edit") {
10721
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_SET_PROGRESS) return true;
10722
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT) {
10723
+ return action.column === COLUMN.PROGRESS;
10724
+ }
10725
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
10631
10726
  return action.edits.some((edit) => edit.column === COLUMN.PROGRESS);
10632
10727
  }
10633
10728
  return false;
@@ -10644,11 +10739,11 @@ var PROGRESS_AFFECTING_COLUMNS = /* @__PURE__ */ new Set([
10644
10739
  COLUMN.REAL_COST
10645
10740
  ]);
10646
10741
  function shouldRecomputeParentProgress(action) {
10647
- if (action.kind === "activity-set-progress") return true;
10648
- if (action.kind === "inline-edit") {
10742
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_SET_PROGRESS) return true;
10743
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT) {
10649
10744
  return PROGRESS_AFFECTING_COLUMNS.has(action.column);
10650
10745
  }
10651
- if (action.kind === "bulk-edit") {
10746
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
10652
10747
  return action.edits.some(
10653
10748
  (edit) => PROGRESS_AFFECTING_COLUMNS.has(edit.column)
10654
10749
  );
@@ -10684,7 +10779,103 @@ function resolveDerivedPasses(action, autoSchedule, options) {
10684
10779
  return passes;
10685
10780
  }
10686
10781
 
10782
+ // src/internal/state/write-capture.ts
10783
+ var WRITE_OPERATION_KIND = {
10784
+ INSERT: "insert",
10785
+ REMOVE: "remove",
10786
+ LINK_ADD: "link-add",
10787
+ LINK_REMOVE: "link-remove",
10788
+ LINK_FIELD: "link-field"
10789
+ };
10790
+ var WriteCapture = class {
10791
+ _journal = null;
10792
+ begin() {
10793
+ this._journal = {
10794
+ dirty: /* @__PURE__ */ new Set(),
10795
+ before: /* @__PURE__ */ new Map(),
10796
+ ops: [],
10797
+ linkFieldCaptured: /* @__PURE__ */ new Set(),
10798
+ correlativeBefore: /* @__PURE__ */ new Map(),
10799
+ scheduledBefore: /* @__PURE__ */ new Map(),
10800
+ progressFallbackBefore: /* @__PURE__ */ new Map()
10801
+ };
10802
+ }
10803
+ peek() {
10804
+ return this._journal;
10805
+ }
10806
+ end() {
10807
+ this._journal = null;
10808
+ }
10809
+ note(key, current) {
10810
+ const journal = this._journal;
10811
+ if (!journal) return;
10812
+ if (!journal.before.has(key))
10813
+ journal.before.set(key, cloneCoreActivity(current));
10814
+ journal.dirty.add(key);
10815
+ }
10816
+ noteInsert(activityId) {
10817
+ this._journal?.ops.push({ kind: WRITE_OPERATION_KIND.INSERT, activityId });
10818
+ }
10819
+ noteRemove(activityId, current) {
10820
+ this._journal?.ops.push({
10821
+ kind: WRITE_OPERATION_KIND.REMOVE,
10822
+ activityId,
10823
+ before: cloneCoreActivity(current)
10824
+ });
10825
+ }
10826
+ noteLinkAdd(linkId) {
10827
+ this._journal?.ops.push({ kind: WRITE_OPERATION_KIND.LINK_ADD, linkId });
10828
+ }
10829
+ noteLinkRemove(linkId, current) {
10830
+ this._journal?.ops.push({
10831
+ kind: WRITE_OPERATION_KIND.LINK_REMOVE,
10832
+ linkId,
10833
+ before: cloneLink(current)
10834
+ });
10835
+ }
10836
+ noteCorrelativeBefore(activityId, before) {
10837
+ const journal = this._journal;
10838
+ if (!journal || journal.correlativeBefore.has(activityId)) return;
10839
+ const capturedBefore = journal.before.get(activityId)?.correlativeId;
10840
+ journal.correlativeBefore.set(
10841
+ activityId,
10842
+ typeof capturedBefore === "number" ? capturedBefore : before
10843
+ );
10844
+ }
10845
+ noteScheduledBefore(activityId, current) {
10846
+ const journal = this._journal;
10847
+ if (!journal) return;
10848
+ const beforeImage = cloneCoreActivity(current);
10849
+ if (!journal.scheduledBefore.has(activityId)) {
10850
+ journal.scheduledBefore.set(activityId, beforeImage);
10851
+ }
10852
+ if (!journal.before.has(activityId)) {
10853
+ journal.before.set(activityId, beforeImage);
10854
+ }
10855
+ journal.dirty.add(activityId);
10856
+ }
10857
+ noteLinkField(linkId, current) {
10858
+ const journal = this._journal;
10859
+ if (!journal || journal.linkFieldCaptured.has(linkId)) return;
10860
+ journal.linkFieldCaptured.add(linkId);
10861
+ journal.ops.push({
10862
+ kind: WRITE_OPERATION_KIND.LINK_FIELD,
10863
+ linkId,
10864
+ before: cloneLink(current)
10865
+ });
10866
+ }
10867
+ noteProgressFallback(activityId, current) {
10868
+ const journal = this._journal;
10869
+ if (!journal || journal.progressFallbackBefore.has(activityId)) return;
10870
+ journal.progressFallbackBefore.set(activityId, current);
10871
+ }
10872
+ };
10873
+ function cloneLink(link) {
10874
+ return { ...link };
10875
+ }
10876
+
10687
10877
  // src/dispatch/shared/post-mutation.ts
10878
+ var AUTOSCHEDULE_SCOPE = { ROOTS: "roots" };
10688
10879
  async function runPostMutation(deps, args) {
10689
10880
  const progressInvalidation = resolveProgressInvalidation(deps.adapter);
10690
10881
  const passes = resolvePasses(args, progressInvalidation);
@@ -10740,10 +10931,10 @@ function resolveProgressInvalidation(adapter) {
10740
10931
  }
10741
10932
  function collectStructuralProgressInvalidations(adapter, operations, affectParent) {
10742
10933
  for (const operation of operations) {
10743
- if (operation.kind === "insert") {
10934
+ if (operation.kind === WRITE_OPERATION_KIND.INSERT) {
10744
10935
  const inserted = adapter.getActivity(operation.activityId);
10745
10936
  if (inserted) affectParent(inserted.parentId);
10746
- } else if (operation.kind === "remove") {
10937
+ } else if (operation.kind === WRITE_OPERATION_KIND.REMOVE) {
10747
10938
  affectParent(operation.before.parentId);
10748
10939
  }
10749
10940
  }
@@ -10767,7 +10958,7 @@ function collectFieldProgressInvalidations(adapter, beforeById, dirtySeeds, affe
10767
10958
  }
10768
10959
  }
10769
10960
  async function runAutoschedule(deps, autoscheduleFrom, preventSummaryTargetPullback = false) {
10770
- const options = autoscheduleFrom === "roots" ? {} : { triggerId: autoscheduleFrom };
10961
+ const options = autoscheduleFrom === AUTOSCHEDULE_SCOPE.ROOTS ? {} : { triggerId: autoscheduleFrom };
10771
10962
  if (preventSummaryTargetPullback) {
10772
10963
  options.preventSummaryTargetPullback = true;
10773
10964
  }
@@ -10858,7 +11049,10 @@ var CONSTRAINT_EDIT_COLUMNS = /* @__PURE__ */ new Set([
10858
11049
  COLUMN.CONSTRAINT_TYPE,
10859
11050
  COLUMN.CONSTRAINT_DATE
10860
11051
  ]);
10861
- var MUST_CONSTRAINTS = /* @__PURE__ */ new Set(["mso", "mfo"]);
11052
+ var MUST_CONSTRAINTS = /* @__PURE__ */ new Set([
11053
+ CONSTRAINT_TYPE.MSO,
11054
+ CONSTRAINT_TYPE.MFO
11055
+ ]);
10862
11056
  function isConstraintEditColumn(column) {
10863
11057
  return CONSTRAINT_EDIT_COLUMNS.has(column);
10864
11058
  }
@@ -10989,6 +11183,10 @@ function snapshotToLink(l) {
10989
11183
  }
10990
11184
 
10991
11185
  // src/dispatch/shared/change-set.ts
11186
+ var SIR_DETECTION_PHASE = {
11187
+ BEFORE_DIFF: "before-diff",
11188
+ AFTER_DIFF: "after-diff"
11189
+ };
10992
11190
  async function assembleChangeSet(adapter, args) {
10993
11191
  const allTouched = collectChangeSetIds(adapter, args);
10994
11192
  const before = new Map(args.beforeSnap);
@@ -10998,7 +11196,7 @@ async function assembleChangeSet(adapter, args) {
10998
11196
  mergeDirtyBeforeImages(adapter, captured, insertedIds, before, allTouched);
10999
11197
  }
11000
11198
  const sirDetection = args.sirDetection;
11001
- const beforeDiffEffects = sirDetection === "before-diff" ? detectSirAutoReject(before, adapter, allTouched) : [];
11199
+ const beforeDiffEffects = sirDetection === SIR_DETECTION_PHASE.BEFORE_DIFF ? detectSirAutoReject(before, adapter, allTouched) : [];
11002
11200
  const correlativeBefore = buildCorrelativeBeforeMap(
11003
11201
  args.correlativeShifts,
11004
11202
  allTouched
@@ -11009,7 +11207,7 @@ async function assembleChangeSet(adapter, args) {
11009
11207
  allTouched,
11010
11208
  correlativeBefore
11011
11209
  );
11012
- const effects = sirDetection === "after-diff" ? detectSirAutoReject(before, adapter, allTouched) : beforeDiffEffects;
11210
+ const effects = sirDetection === SIR_DETECTION_PHASE.AFTER_DIFF ? detectSirAutoReject(before, adapter, allTouched) : beforeDiffEffects;
11013
11211
  const warnings = args.warnings ?? [];
11014
11212
  const linkChanges = mergeLinkChanges(
11015
11213
  args.links ?? [],
@@ -11028,7 +11226,7 @@ async function assembleChangeSet(adapter, args) {
11028
11226
  function buildCapturedCriticalPathLinkChanges(adapter, captured) {
11029
11227
  const changes = [];
11030
11228
  for (const operation of captured.ops) {
11031
- if (operation.kind !== "link-field") continue;
11229
+ if (operation.kind !== WRITE_OPERATION_KIND.LINK_FIELD) continue;
11032
11230
  const after = adapter.getLink(operation.linkId);
11033
11231
  if (!after) continue;
11034
11232
  const fields = {};
@@ -11043,7 +11241,7 @@ function buildCapturedCriticalPathLinkChanges(adapter, captured) {
11043
11241
  if (Object.keys(fields).length === 0) continue;
11044
11242
  changes.push({
11045
11243
  id: operation.linkId,
11046
- kind: "updated",
11244
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11047
11245
  fields,
11048
11246
  after: snapshotToLink(after)
11049
11247
  });
@@ -11061,7 +11259,7 @@ function mergeLinkChanges(explicit, captured) {
11061
11259
  continue;
11062
11260
  }
11063
11261
  const current = merged[index];
11064
- if ((current.kind === "updated" || current.kind === "created") && change.kind === "updated") {
11262
+ if ((current.kind === ENTITY_CHANGE_KIND.UPDATED || current.kind === ENTITY_CHANGE_KIND.CREATED) && change.kind === ENTITY_CHANGE_KIND.UPDATED) {
11065
11263
  merged[index] = {
11066
11264
  ...current,
11067
11265
  fields: { ...current.fields, ...change.fields },
@@ -11079,8 +11277,8 @@ function mergeLinkChanges(explicit, captured) {
11079
11277
  continue;
11080
11278
  }
11081
11279
  const current = merged[index];
11082
- if (current.kind === "deleted") continue;
11083
- const capturedFields = current.kind === "created" ? Object.fromEntries(
11280
+ if (current.kind === ENTITY_CHANGE_KIND.DELETED) continue;
11281
+ const capturedFields = current.kind === ENTITY_CHANGE_KIND.CREATED ? Object.fromEntries(
11084
11282
  Object.entries(change.fields ?? {}).map(([field, value]) => [
11085
11283
  field,
11086
11284
  { before: void 0, after: value.after }
@@ -11125,7 +11323,7 @@ function mergeDirtyBeforeImages(adapter, captured, insertedIds, before, touched)
11125
11323
  }
11126
11324
  function collectInsertedIds(captured) {
11127
11325
  return new Set(
11128
- captured.ops.filter((operation) => operation.kind === "insert").map((operation) => operation.activityId)
11326
+ captured.ops.filter((operation) => operation.kind === WRITE_OPERATION_KIND.INSERT).map((operation) => operation.activityId)
11129
11327
  );
11130
11328
  }
11131
11329
 
@@ -11134,7 +11332,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11134
11332
  const out = [];
11135
11333
  for (const { op, finalLinkId, rejected } of applied) {
11136
11334
  if (rejected !== null) continue;
11137
- if (op.kind === "create") {
11335
+ if (op.kind === LINK_OPERATION_KIND.CREATE) {
11138
11336
  if (!finalLinkId) continue;
11139
11337
  const after = adapter.getLink(finalLinkId);
11140
11338
  if (!after) continue;
@@ -11165,7 +11363,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11165
11363
  if (Object.keys(fields2).length > 0) {
11166
11364
  out.push({
11167
11365
  id: String(finalLinkId),
11168
- kind: "updated",
11366
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11169
11367
  fields: fields2,
11170
11368
  after: snapshotToLink(after)
11171
11369
  });
@@ -11174,7 +11372,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11174
11372
  }
11175
11373
  out.push({
11176
11374
  id: String(finalLinkId),
11177
- kind: "created",
11375
+ kind: ENTITY_CHANGE_KIND.CREATED,
11178
11376
  fields: {
11179
11377
  source: { before: void 0, after: String(after.source) },
11180
11378
  target: { before: void 0, after: String(after.target) },
@@ -11185,12 +11383,12 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11185
11383
  });
11186
11384
  continue;
11187
11385
  }
11188
- if (op.kind === "delete") {
11386
+ if (op.kind === LINK_OPERATION_KIND.DELETE) {
11189
11387
  if (adapter.getLink(op.linkId)) continue;
11190
11388
  const beforeLink2 = beforeLinks.get(op.linkId);
11191
11389
  out.push({
11192
11390
  id: String(op.linkId),
11193
- kind: "deleted",
11391
+ kind: ENTITY_CHANGE_KIND.DELETED,
11194
11392
  fields: beforeLink2 ? {
11195
11393
  source: { before: String(beforeLink2.source), after: void 0 },
11196
11394
  target: { before: String(beforeLink2.target), after: void 0 },
@@ -11216,7 +11414,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11216
11414
  }
11217
11415
  out.push({
11218
11416
  id: String(op.linkId),
11219
- kind: "updated",
11417
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11220
11418
  fields,
11221
11419
  after: snapshotToLink(afterLink)
11222
11420
  });
@@ -11242,7 +11440,7 @@ function diffIncomingLinkLagChanges(beforeLags, adapter, activityId) {
11242
11440
  if (before === void 0 || before === Number(link.lag)) continue;
11243
11441
  out.push({
11244
11442
  id: String(link.id),
11245
- kind: "updated",
11443
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11246
11444
  fields: {
11247
11445
  lag: {
11248
11446
  before,
@@ -11384,6 +11582,16 @@ async function dispatchInlineEdit(action, options, deps) {
11384
11582
  name: e.name,
11385
11583
  properties: e.properties ?? {}
11386
11584
  }));
11585
+ if (pipeline.trackEvent && !(action.column === COLUMN.PROGRESS && Number(parsed2.value) <= 0)) {
11586
+ trackingEvents.unshift({
11587
+ name: pipeline.trackEvent,
11588
+ properties: {
11589
+ activity_name: activitySnap.name,
11590
+ activity_id: activitySnap.id,
11591
+ activity_index: activitySnap.correlativeId
11592
+ }
11593
+ });
11594
+ }
11387
11595
  const constraintWarning = toConstraintWarning(
11388
11596
  action.activityId,
11389
11597
  changes.constraintWarning
@@ -11395,7 +11603,7 @@ async function dispatchInlineEdit(action, options, deps) {
11395
11603
  beforeSnap,
11396
11604
  touchedIds,
11397
11605
  scheduledIds,
11398
- sirDetection: "before-diff",
11606
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
11399
11607
  links: linkChanges,
11400
11608
  trackingEvents,
11401
11609
  ...constraintWarning ? { warnings: [constraintWarning] } : {},
@@ -11405,9 +11613,8 @@ async function dispatchInlineEdit(action, options, deps) {
11405
11613
  }
11406
11614
 
11407
11615
  // src/dispatch/handlers/link.ts
11408
- var LINK_TYPE_VALUES = new Set(Object.values(LINK_TYPE));
11409
11616
  function isValidLinkType(value) {
11410
- return typeof value === "string" && LINK_TYPE_VALUES.has(value);
11617
+ return isLinkType(value);
11411
11618
  }
11412
11619
  function hasOwn(value, property) {
11413
11620
  return Object.hasOwn(value, property);
@@ -11620,7 +11827,7 @@ function pickAutoscheduleTrigger(applied, beforeLinks, adapter) {
11620
11827
  if (operation.rejected !== null) continue;
11621
11828
  const target = autoscheduleTarget(operation.op, beforeLinks, adapter);
11622
11829
  if (target !== null)
11623
- return adapter.hasChildren(target) ? "roots" : String(target);
11830
+ return adapter.hasChildren(target) ? AUTOSCHEDULE_SCOPE.ROOTS : String(target);
11624
11831
  }
11625
11832
  return null;
11626
11833
  }
@@ -11898,9 +12105,9 @@ function readNumber3(activity, key) {
11898
12105
  var NEW_ACTIVITY_DEFAULTS = Object.freeze({
11899
12106
  proplannerId: null,
11900
12107
  description: "",
11901
- type: "task",
12108
+ type: ACTIVITY_TYPE.TASK,
11902
12109
  progress: 0,
11903
- constraintType: "asap",
12110
+ constraintType: CONSTRAINT_TYPE.ASAP,
11904
12111
  constraintDate: null,
11905
12112
  autoScheduling: true,
11906
12113
  assignedDefaultCalendar: false,
@@ -12053,9 +12260,15 @@ function resolveStartDate(parent, fallback, override) {
12053
12260
  }
12054
12261
 
12055
12262
  // src/creation/parent-mutation-pipeline.ts
12263
+ var PARENT_MUTATION_SOURCE = {
12264
+ CREATE: "create",
12265
+ REPARENT: "reparent"
12266
+ };
12056
12267
  function snapshotOf(parent) {
12057
12268
  const type = parent.type;
12058
- if (type !== "task" && type !== "milestone") return null;
12269
+ if (type !== ACTIVITY_TYPE.TASK && type !== ACTIVITY_TYPE.MILESTONE) {
12270
+ return null;
12271
+ }
12059
12272
  const startDate = parent.startDate;
12060
12273
  const endDate = parent.endDate;
12061
12274
  if (!(startDate instanceof Date) || !(endDate instanceof Date)) return null;
@@ -12088,7 +12301,7 @@ function buildParentMutations(input) {
12088
12301
  }
12089
12302
  if (wasPromotableLeaf) {
12090
12303
  fields.type = PROMOTION_TARGET_TYPE;
12091
- if ((input.promotionSource ?? "create") === "create") {
12304
+ if ((input.promotionSource ?? PARENT_MUTATION_SOURCE.CREATE) === PARENT_MUTATION_SOURCE.CREATE) {
12092
12305
  fields.constraintType = CONSTRAINT_TYPE.ASAP;
12093
12306
  fields.constraintDate = null;
12094
12307
  }
@@ -12189,7 +12402,9 @@ function computeFractionalCidAtIndex(adapter, parentKey, targetIndex, excludeId)
12189
12402
 
12190
12403
  // src/dispatch/creation-overrides.ts
12191
12404
  var PUBLIC_CREATION_OVERRIDE_FIELDS = /* @__PURE__ */ new Set([
12192
- ...[...CREATION_OVERRIDE_FIELDS].filter((field) => field !== "durationHours"),
12405
+ ...[...CREATION_OVERRIDE_FIELDS].filter(
12406
+ (field) => field !== ACTIVITY_PROPERTY.DURATION_HOURS
12407
+ ),
12193
12408
  "durationDays"
12194
12409
  ]);
12195
12410
  function normalizeActivityCreationOverrides(raw, hoursPerDay) {
@@ -12211,7 +12426,7 @@ function normalizeActivityCreationOverrides(raw, hoursPerDay) {
12211
12426
  ok: true,
12212
12427
  value: {
12213
12428
  ...rest,
12214
- ...durationDays === 0 && (rest.type === void 0 || rest.type === "task") ? { type: "milestone" } : {},
12429
+ ...durationDays === 0 && (rest.type === void 0 || rest.type === ACTIVITY_TYPE.TASK) ? { type: ACTIVITY_TYPE.MILESTONE } : {},
12215
12430
  ...durationDays === void 0 ? {} : { durationHours: durationToHours(durationDays, hoursPerDay) }
12216
12431
  }
12217
12432
  };
@@ -12542,7 +12757,7 @@ function buildParentDemotionMutations(input) {
12542
12757
  durationHours: canonicalDuration,
12543
12758
  progress: 0,
12544
12759
  autoScheduling: true,
12545
- constraintType: "asap",
12760
+ constraintType: CONSTRAINT_TYPE.ASAP,
12546
12761
  constraintDate: null,
12547
12762
  hasNewActivities: false,
12548
12763
  ...canonicalEndDateField(
@@ -12694,7 +12909,7 @@ async function dispatchActivityDelete(action, options, deps) {
12694
12909
  },
12695
12910
  {
12696
12911
  action,
12697
- autoscheduleFrom: "roots",
12912
+ autoscheduleFrom: AUTOSCHEDULE_SCOPE.ROOTS,
12698
12913
  recomputeParentsFrom: parentsToCheck,
12699
12914
  now: deps.now,
12700
12915
  options
@@ -12722,7 +12937,7 @@ async function dispatchActivityDelete(action, options, deps) {
12722
12937
  beforeSnap,
12723
12938
  touchedIds,
12724
12939
  scheduledIds,
12725
- sirDetection: "after-diff",
12940
+ sirDetection: SIR_DETECTION_PHASE.AFTER_DIFF,
12726
12941
  links: buildLinkDeletions(beforeLinks),
12727
12942
  trackingEvents: [trackingEvent],
12728
12943
  hoursPerDay: sector.hoursPerDay,
@@ -12761,7 +12976,7 @@ function buildLinkDeletions(beforeLinks) {
12761
12976
  for (const [id, before] of beforeLinks.entries()) {
12762
12977
  out.push({
12763
12978
  id,
12764
- kind: "deleted",
12979
+ kind: ENTITY_CHANGE_KIND.DELETED,
12765
12980
  fields: {
12766
12981
  source: { before: String(before.source), after: void 0 },
12767
12982
  target: { before: String(before.target), after: void 0 },
@@ -12869,7 +13084,7 @@ async function dispatchActivityBatch(action, options, deps) {
12869
13084
  },
12870
13085
  {
12871
13086
  action,
12872
- autoscheduleFrom: action.items.length > 0 || action.links.length > 0 ? "roots" : null,
13087
+ autoscheduleFrom: action.items.length > 0 || action.links.length > 0 ? AUTOSCHEDULE_SCOPE.ROOTS : null,
12873
13088
  recomputeParentsFrom: createdIds,
12874
13089
  now: deps.now,
12875
13090
  options
@@ -12883,7 +13098,7 @@ async function dispatchActivityBatch(action, options, deps) {
12883
13098
  links: buildLinkChangesForBatch(appliedLinks, beforeLinks, deps.adapter),
12884
13099
  hoursPerDay: deps.sector.hoursPerDay,
12885
13100
  correlativeShifts: existingCorrelativeShifts,
12886
- ...action.mode === ACTIVITY_BATCH_MODE.REPLACE ? { sirDetection: "after-diff" } : {}
13101
+ ...action.mode === ACTIVITY_BATCH_MODE.REPLACE ? { sirDetection: SIR_DETECTION_PHASE.AFTER_DIFF } : {}
12887
13102
  });
12888
13103
  return {
12889
13104
  ok: true,
@@ -13242,7 +13457,7 @@ function dispatchSirSync(action, deps) {
13242
13457
  }
13243
13458
  const change = {
13244
13459
  id,
13245
- kind: "updated",
13460
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13246
13461
  fields: { pendingRequestIds: { before, after } },
13247
13462
  after: structuredCloneActivity(updated)
13248
13463
  };
@@ -13418,7 +13633,7 @@ async function dispatchPersistenceAcknowledge(action, deps) {
13418
13633
  );
13419
13634
  activityChanges.push({
13420
13635
  id: assignment.id,
13421
- kind: "updated",
13636
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13422
13637
  fields: {
13423
13638
  proplannerId: {
13424
13639
  before: previousProplannerId,
@@ -13435,7 +13650,7 @@ async function dispatchPersistenceAcknowledge(action, deps) {
13435
13650
  deps.adapter.setLinkProplannerId(assignment.id, assignment.proplannerId);
13436
13651
  linkChanges.push({
13437
13652
  id: assignment.id,
13438
- kind: "updated",
13653
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13439
13654
  fields: {
13440
13655
  proplannerId: {
13441
13656
  before: previousProplannerId,
@@ -13498,7 +13713,7 @@ async function dispatchActivityLookaheadSync(action, options, deps) {
13498
13713
  if (Object.keys(fields).length === 0) continue;
13499
13714
  activities.push({
13500
13715
  id,
13501
- kind: "updated",
13716
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13502
13717
  fields,
13503
13718
  after: {
13504
13719
  ...snapshot,
@@ -13556,6 +13771,285 @@ function hasInvalidPersistedProgress(action) {
13556
13771
  return progress !== void 0 && (action.activityIds.length !== 1 || !Number.isFinite(progress) || progress < 0 || progress > 100);
13557
13772
  }
13558
13773
 
13774
+ // src/dispatch/handlers/activity-lookahead-convert.ts
13775
+ function buildLookaheadConversionPlan(input, deps) {
13776
+ const { adapter } = deps;
13777
+ const requested = new Set(
13778
+ input.conversionRootIds.map((id) => String(id))
13779
+ );
13780
+ if (requested.size === 0) {
13781
+ throw new Error("Conversion requires at least one root");
13782
+ }
13783
+ for (const rootId of requested) validateRequestedRoot(rootId, adapter);
13784
+ const conversionRootIds = adapter.getVisualOrderIds().filter(
13785
+ (activityId) => requested.has(activityId) && !hasAncestorInSet(activityId, requested, adapter)
13786
+ );
13787
+ const branches = conversionRootIds.map(
13788
+ (rootId) => planConversionBranch(rootId, adapter)
13789
+ );
13790
+ const conversionGroups = branches.map(
13791
+ ({ conversionRootId, convertedActivities }) => ({
13792
+ conversionRootId,
13793
+ convertedActivities
13794
+ })
13795
+ );
13796
+ const milestoneMoves = branches.flatMap((branch) => branch.milestoneMoves);
13797
+ const activityIdsToDelete = branches.flatMap(
13798
+ (branch) => branch.activityIdsToDelete
13799
+ );
13800
+ const formerParents = branches.map((branch) => branch.formerParent);
13801
+ const idsToDelete = new Set(activityIdsToDelete);
13802
+ const linkIdsToDelete = collectIncidentLinkIds(idsToDelete, adapter);
13803
+ return {
13804
+ sourceStateRevision: deps.stateRevision,
13805
+ conversionRootIds,
13806
+ conversionGroups,
13807
+ milestoneMoves,
13808
+ activityIdsToDelete,
13809
+ linkIdsToDelete,
13810
+ formerParents
13811
+ };
13812
+ }
13813
+ async function dispatchActivityLookaheadConvert(action, options, deps) {
13814
+ if (action.expectedStateRevision !== deps.stateRevision) {
13815
+ return { ok: false, reason: REJECTION_REASON.STALE_STATE_REVISION };
13816
+ }
13817
+ const plan = buildLookaheadConversionPlan(action, deps);
13818
+ if (!conversionTopologyIsValid(plan, deps.adapter)) {
13819
+ return { ok: false, reason: REJECTION_REASON.HIERARCHY_CYCLE };
13820
+ }
13821
+ const { adapter, scheduler } = deps;
13822
+ scheduler.invalidateAllCaches();
13823
+ const context = await captureConversionMutationContext(plan, adapter);
13824
+ releaseDeletedCustomIds(plan, deps);
13825
+ applyConversionStructure(plan, adapter);
13826
+ applyFormerParentState(plan, context.deletedIds, adapter);
13827
+ const correlativeShifts = recomputeConversionRollups(plan, adapter);
13828
+ foldCorrelativeShifts(
13829
+ adapter,
13830
+ correlativeShifts,
13831
+ context.deletedIds,
13832
+ context.beforeSnap,
13833
+ context.touchedIds
13834
+ );
13835
+ const { scheduledIds } = await runPostMutation(
13836
+ {
13837
+ adapter,
13838
+ scheduler,
13839
+ sector: deps.sector,
13840
+ defaultBaseCalendarId: deps.defaultBaseCalendarId
13841
+ },
13842
+ {
13843
+ action,
13844
+ autoscheduleFrom: "roots",
13845
+ recomputeParentsFrom: context.touchedIds,
13846
+ now: deps.now,
13847
+ options,
13848
+ recomputeParentProgress: true
13849
+ }
13850
+ );
13851
+ const changes = await assembleChangeSet(adapter, {
13852
+ source: action,
13853
+ beforeSnap: context.beforeSnap,
13854
+ touchedIds: context.touchedIds,
13855
+ scheduledIds,
13856
+ sirDetection: "after-diff",
13857
+ links: buildLinkDeletions(context.beforeLinks),
13858
+ hoursPerDay: deps.sector.hoursPerDay,
13859
+ correlativeShifts
13860
+ });
13861
+ return buildConversionResult(plan, context, changes);
13862
+ }
13863
+ function planConversionBranch(rootId, adapter) {
13864
+ const root = requiredActivity(rootId, adapter);
13865
+ const branch = collectDescendantIds([rootId], adapter);
13866
+ branch.delete(rootId);
13867
+ if (branch.size === 0) {
13868
+ throw new Error(`Conversion root ${rootId} has no descendants`);
13869
+ }
13870
+ const descendants = adapter.getVisualOrderIds().filter((activityId) => branch.has(activityId)).map((activityId) => requiredActivity(activityId, adapter));
13871
+ validateFiniteActivity(root);
13872
+ for (const descendant of descendants) validateFiniteActivity(descendant);
13873
+ const convertible = descendants.filter(
13874
+ (activity) => activity.type !== ACTIVITY_TYPE.MILESTONE
13875
+ );
13876
+ const milestones = descendants.filter(
13877
+ (activity) => activity.type === ACTIVITY_TYPE.MILESTONE
13878
+ );
13879
+ const persistedIds = collectPersistedIds(root, convertible);
13880
+ return {
13881
+ conversionRootId: rootId,
13882
+ convertedActivities: convertible.map(
13883
+ (activity) => buildConvertedSnapshot(activity, persistedIds)
13884
+ ),
13885
+ milestoneMoves: buildMilestoneMoves(root, milestones),
13886
+ activityIdsToDelete: convertible.map((activity) => activity.id),
13887
+ formerParent: {
13888
+ activity: structuredCloneActivity(root),
13889
+ hasConvertedActivities: convertible.length > 0
13890
+ }
13891
+ };
13892
+ }
13893
+ function collectPersistedIds(root, converted) {
13894
+ const persistedIds = /* @__PURE__ */ new Map();
13895
+ if (converted.length > 0) persistedIds.set(root.id, persistedIdOf(root));
13896
+ for (const activity of converted) {
13897
+ persistedIds.set(activity.id, persistedIdOf(activity));
13898
+ }
13899
+ return persistedIds;
13900
+ }
13901
+ function buildConvertedSnapshot(activity, persistedIds) {
13902
+ const snapshot = structuredCloneActivity(activity);
13903
+ const parentKey = normalizeParentKey(activity.parentId);
13904
+ const persistedParentId = persistedIds.get(parentKey);
13905
+ snapshot.parentId = persistedParentId === void 0 ? null : String(persistedParentId);
13906
+ return snapshot;
13907
+ }
13908
+ function buildMilestoneMoves(root, milestones) {
13909
+ const moves = [];
13910
+ const parentId = normalizeParentKey(root.parentId);
13911
+ let afterSiblingId = root.id;
13912
+ for (const milestone of milestones) {
13913
+ moves.push({ activityId: milestone.id, parentId, afterSiblingId });
13914
+ afterSiblingId = milestone.id;
13915
+ }
13916
+ return moves;
13917
+ }
13918
+ async function captureConversionMutationContext(plan, adapter) {
13919
+ const deletedIds = new Set(plan.activityIdsToDelete);
13920
+ const touchedIds = /* @__PURE__ */ new Set([
13921
+ ...plan.conversionRootIds,
13922
+ ...plan.activityIdsToDelete,
13923
+ ...plan.milestoneMoves.map(({ activityId }) => activityId),
13924
+ ...plan.milestoneMoves.map(({ parentId }) => parentId).filter((parentId) => parentId !== ROOT_PARENT_ID)
13925
+ ]);
13926
+ return {
13927
+ deletedIds,
13928
+ touchedIds,
13929
+ beforeSnap: await snapshotActivities(adapter, touchedIds),
13930
+ beforeLinks: snapshotLinks(plan.linkIdsToDelete, adapter),
13931
+ viewStateChanges: captureDeletedViewState(adapter, deletedIds)
13932
+ };
13933
+ }
13934
+ function releaseDeletedCustomIds(plan, deps) {
13935
+ for (const activityId of plan.activityIdsToDelete) {
13936
+ const customId = deps.adapter.getActivity(activityId)?.customId;
13937
+ if (customId) deps.customIdTracker.releaseCustomId(customId);
13938
+ }
13939
+ }
13940
+ function applyConversionStructure(plan, adapter) {
13941
+ for (const move of plan.milestoneMoves) {
13942
+ adapter.setActivityFields(move.activityId, {
13943
+ parentId: move.parentId,
13944
+ correlativeId: computeInsertionCorrelativeId(
13945
+ adapter,
13946
+ move.parentId,
13947
+ move.afterSiblingId,
13948
+ void 0
13949
+ )
13950
+ });
13951
+ }
13952
+ for (const linkId of plan.linkIdsToDelete) adapter.removeLink(linkId);
13953
+ for (const activityId of [...plan.activityIdsToDelete].reverse()) {
13954
+ adapter.removeActivity(activityId);
13955
+ }
13956
+ for (const { activity } of plan.formerParents) {
13957
+ adapter.setActivityField(
13958
+ activity.id,
13959
+ ACTIVITY_PROPERTY.TYPE,
13960
+ ACTIVITY_TYPE.TASK
13961
+ );
13962
+ }
13963
+ }
13964
+ function applyFormerParentState(plan, deletedIds, adapter) {
13965
+ for (const { activity, hasConvertedActivities } of plan.formerParents) {
13966
+ const live = requiredActivity(activity.id, adapter);
13967
+ const cleanup = buildParentNewActivitiesCleanup({
13968
+ parent: live,
13969
+ idsRemoved: deletedIds
13970
+ });
13971
+ adapter.setActivityFields(activity.id, {
13972
+ isLookahead: activity.isLookahead || hasConvertedActivities,
13973
+ hasLookaheadTasks: activity.hasLookaheadTasks || hasConvertedActivities,
13974
+ ...cleanup?.fields ?? {}
13975
+ });
13976
+ }
13977
+ }
13978
+ function recomputeConversionRollups(plan, adapter) {
13979
+ for (const { activity } of plan.formerParents) {
13980
+ recomputeRollupCascadesForParent(activity.parentId, adapter);
13981
+ }
13982
+ return recomputeCorrelativeIds(adapter);
13983
+ }
13984
+ function buildConversionResult(plan, context, changes) {
13985
+ const deletedSnapshots = /* @__PURE__ */ new Map();
13986
+ for (const activityId of context.deletedIds) {
13987
+ const snapshot = context.beforeSnap.get(activityId);
13988
+ if (snapshot) deletedSnapshots.set(activityId, snapshot);
13989
+ }
13990
+ return {
13991
+ ok: true,
13992
+ changes: context.viewStateChanges.length === 0 ? changes : { ...changes, viewState: context.viewStateChanges },
13993
+ conversionGroups: plan.conversionGroups.map(
13994
+ ({ conversionRootId, convertedActivities }) => ({
13995
+ conversionRootId,
13996
+ convertedActivities: convertedActivities.map(
13997
+ (activity) => structuredCloneActivity(activity)
13998
+ )
13999
+ })
14000
+ ),
14001
+ __beforeSnap: deletedSnapshots,
14002
+ __beforeLinks: context.beforeLinks
14003
+ };
14004
+ }
14005
+ function validateRequestedRoot(rootId, adapter) {
14006
+ const activity = adapter.getActivity(rootId);
14007
+ if (!activity) throw new Error(`Conversion root ${rootId} was not found`);
14008
+ if (activity.type === ACTIVITY_TYPE.PROJECT && activity.correlativeId === ROOT_PROJECT_CORRELATIVE_ID) {
14009
+ throw new Error(`Conversion root ${rootId} is the visual project root`);
14010
+ }
14011
+ }
14012
+ function requiredActivity(activityId, adapter) {
14013
+ const activity = adapter.getActivity(activityId);
14014
+ if (!activity)
14015
+ throw new Error(`Conversion activity ${activityId} is missing`);
14016
+ return activity;
14017
+ }
14018
+ function persistedIdOf(activity) {
14019
+ if (activity.proplannerId == null) {
14020
+ throw new Error(
14021
+ `Conversion activity ${activity.id} has no persisted identifier`
14022
+ );
14023
+ }
14024
+ return activity.proplannerId;
14025
+ }
14026
+ function validateFiniteActivity(activity) {
14027
+ if (!Number.isFinite(activity.startDate.getTime())) {
14028
+ throw new Error(`Conversion activity ${activity.id} has invalid startDate`);
14029
+ }
14030
+ if (!Number.isFinite(activity.endDate.getTime())) {
14031
+ throw new Error(`Conversion activity ${activity.id} has invalid endDate`);
14032
+ }
14033
+ }
14034
+ function conversionTopologyIsValid(plan, adapter) {
14035
+ const proposedPort = adapter.fork();
14036
+ applyConversionStructure(plan, proposedPort);
14037
+ return validateTopologyCommit({
14038
+ port: adapter,
14039
+ proposedPort,
14040
+ currentLinks: adapter.getAllLinks(),
14041
+ proposedLinks: proposedPort.getAllLinks()
14042
+ }).ok;
14043
+ }
14044
+ function snapshotLinks(linkIds, adapter) {
14045
+ const snapshots = /* @__PURE__ */ new Map();
14046
+ for (const linkId of linkIds) {
14047
+ const link = adapter.getLink(linkId);
14048
+ if (link) snapshots.set(linkId, { ...link });
14049
+ }
14050
+ return snapshots;
14051
+ }
14052
+
13559
14053
  // src/internal/hierarchy/invalid-links.ts
13560
14054
  function collectInvalidLinkIdsForCycle(movedActivityIds, adapter) {
13561
14055
  const moved = /* @__PURE__ */ new Set();
@@ -13708,7 +14202,7 @@ async function dispatchActivityMove(action, options, deps) {
13708
14202
  newChildId: action.activityId,
13709
14203
  getParent: (id) => adapter.getActivity(id) ?? null,
13710
14204
  isCurrentlyLeaf: wasLeaf,
13711
- promotionSource: "reparent"
14205
+ promotionSource: PARENT_MUTATION_SOURCE.REPARENT
13712
14206
  });
13713
14207
  if (promotion) {
13714
14208
  for (const [key, value] of Object.entries(promotion.fields)) {
@@ -13821,7 +14315,7 @@ async function dispatchActivityMove(action, options, deps) {
13821
14315
  beforeSnap,
13822
14316
  touchedIds: touched,
13823
14317
  scheduledIds,
13824
- sirDetection: "before-diff",
14318
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
13825
14319
  trackingEvents: [trackingEvent],
13826
14320
  hoursPerDay: sector.hoursPerDay
13827
14321
  })
@@ -13929,7 +14423,7 @@ async function dispatchActivityIndent(action, options, deps) {
13929
14423
  newChildId: activityId,
13930
14424
  getParent: (id) => adapter.getActivity(id) ?? null,
13931
14425
  isCurrentlyLeaf: wasLeaf,
13932
- promotionSource: "reparent"
14426
+ promotionSource: PARENT_MUTATION_SOURCE.REPARENT
13933
14427
  });
13934
14428
  if (promotion) {
13935
14429
  for (const [key, value] of Object.entries(promotion.fields)) {
@@ -13957,7 +14451,7 @@ async function dispatchActivityIndent(action, options, deps) {
13957
14451
  adapter.setActivityField(
13958
14452
  newParentId,
13959
14453
  ACTIVITY_PROPERTY.CONSTRAINT_TYPE,
13960
- "asap"
14454
+ CONSTRAINT_TYPE.ASAP
13961
14455
  );
13962
14456
  adapter.setActivityField(
13963
14457
  newParentId,
@@ -14233,7 +14727,7 @@ async function dispatchActivityOutdent(action, options, deps) {
14233
14727
  },
14234
14728
  {
14235
14729
  action,
14236
- autoscheduleFrom: succeededIds.length > 0 ? "roots" : null,
14730
+ autoscheduleFrom: succeededIds.length > 0 ? AUTOSCHEDULE_SCOPE.ROOTS : null,
14237
14731
  recomputeParentsFrom: succeededIds,
14238
14732
  now: deps.now,
14239
14733
  options
@@ -14296,7 +14790,7 @@ async function dispatchActivitySetProgress(action, options, deps) {
14296
14790
  }
14297
14791
  const editGate = pipeline.canEdit(activitySnap, ctx.hierarchy);
14298
14792
  if (!editGate.allowed) {
14299
- const declaredButtonOverride = action.origin === "action-button" && (editGate.reason === "has_lookahead_tasks" || editGate.reason === "summary");
14793
+ const declaredButtonOverride = action.origin === ACTIVITY_PROGRESS_ORIGIN.ACTION_BUTTON && (editGate.reason === EDIT_DENIAL_REASON.HAS_LOOKAHEAD_TASKS || editGate.reason === EDIT_DENIAL_REASON.SUMMARY);
14300
14794
  if (!declaredButtonOverride) {
14301
14795
  return {
14302
14796
  ok: false,
@@ -14417,7 +14911,7 @@ async function dispatchDatesBatch(action, options, deps) {
14417
14911
  },
14418
14912
  {
14419
14913
  action,
14420
- autoscheduleFrom: needsAutoSchedule ? "roots" : null,
14914
+ autoscheduleFrom: needsAutoSchedule ? AUTOSCHEDULE_SCOPE.ROOTS : null,
14421
14915
  recomputeParentsFrom: touchedIds,
14422
14916
  now: deps.now,
14423
14917
  options
@@ -14431,7 +14925,7 @@ async function dispatchDatesBatch(action, options, deps) {
14431
14925
  beforeSnap,
14432
14926
  touchedIds,
14433
14927
  scheduledIds,
14434
- sirDetection: "before-diff",
14928
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
14435
14929
  links: linkChanges,
14436
14930
  trackingEvents,
14437
14931
  warnings,
@@ -14578,7 +15072,7 @@ async function dispatchBulkEdit(action, options, deps) {
14578
15072
  }
14579
15073
  const postMutationArgs = {
14580
15074
  action,
14581
- autoscheduleFrom: needsAutoSchedule ? "roots" : null,
15075
+ autoscheduleFrom: needsAutoSchedule ? AUTOSCHEDULE_SCOPE.ROOTS : null,
14582
15076
  recomputeParentsFrom: touchedIds,
14583
15077
  now: deps.now,
14584
15078
  options
@@ -14623,7 +15117,7 @@ async function dispatchBulkEdit(action, options, deps) {
14623
15117
  beforeSnap,
14624
15118
  touchedIds,
14625
15119
  scheduledIds,
14626
- sirDetection: "before-diff",
15120
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
14627
15121
  links: linkChanges,
14628
15122
  trackingEvents,
14629
15123
  warnings,
@@ -14760,6 +15254,51 @@ function mergeBeforeSnapshots2(beforeSnap, ids, deps) {
14760
15254
  }
14761
15255
  }
14762
15256
 
15257
+ // src/shared/load-diagnostics.ts
15258
+ var LOAD_DIAGNOSTIC_SAMPLE_LIMIT = 10;
15259
+ var LOAD_DIAGNOSTIC_CODE = {
15260
+ INVALID_BASELINE_POINT: "invalid_baseline_point",
15261
+ UNKNOWN_CONSTRAINT: "unknown_constraint",
15262
+ ORPHAN_ACTIVITY: "orphan_activity",
15263
+ INVALID_LINK: "invalid_link",
15264
+ DUPLICATE_LINK: "duplicate_link"
15265
+ };
15266
+ var LOAD_DIAGNOSTIC_CODE_ORDER = [
15267
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15268
+ LOAD_DIAGNOSTIC_CODE.UNKNOWN_CONSTRAINT,
15269
+ LOAD_DIAGNOSTIC_CODE.ORPHAN_ACTIVITY,
15270
+ LOAD_DIAGNOSTIC_CODE.INVALID_LINK,
15271
+ LOAD_DIAGNOSTIC_CODE.DUPLICATE_LINK
15272
+ ];
15273
+ var noopLoadDiagnosticRecorder = () => {
15274
+ };
15275
+ function createLoadDiagnosticsCollector() {
15276
+ const counts = /* @__PURE__ */ new Map();
15277
+ const samples = /* @__PURE__ */ new Map();
15278
+ const record = (code, sampleId) => {
15279
+ counts.set(code, (counts.get(code) ?? 0) + 1);
15280
+ const codeSamples = samples.get(code) ?? [];
15281
+ if (codeSamples.length < LOAD_DIAGNOSTIC_SAMPLE_LIMIT && !codeSamples.includes(sampleId)) {
15282
+ codeSamples.push(sampleId);
15283
+ samples.set(code, codeSamples);
15284
+ }
15285
+ };
15286
+ const snapshot = () => Object.freeze(
15287
+ LOAD_DIAGNOSTIC_CODE_ORDER.flatMap((code) => {
15288
+ const count = counts.get(code);
15289
+ if (count === void 0) return [];
15290
+ return [
15291
+ Object.freeze({
15292
+ code,
15293
+ count,
15294
+ sampleIds: Object.freeze([...samples.get(code) ?? []])
15295
+ })
15296
+ ];
15297
+ })
15298
+ );
15299
+ return { record, snapshot };
15300
+ }
15301
+
14763
15302
  // src/baselines/normalize-baseline-point.ts
14764
15303
  function parseBaselineDate(value) {
14765
15304
  return typeof value === "string" && value.length > 0 ? parseBackendDate(value) : value instanceof Date ? value : null;
@@ -14769,11 +15308,17 @@ function parseFiniteNonNegative(value) {
14769
15308
  if (!Number.isFinite(numeric) || numeric < 0) return null;
14770
15309
  return numeric;
14771
15310
  }
14772
- function normalizeBaselinePoint(point, reporter) {
15311
+ function normalizeBaselinePoint(point, reporter, diagnostic) {
14773
15312
  const durationDays = parseFiniteNonNegative(point.duration);
14774
15313
  const cost = parseFiniteNonNegative(point.cost);
14775
15314
  const workHours = parseFiniteNonNegative(point.hh_work);
14776
15315
  if (durationDays === null || cost === null || workHours === null) {
15316
+ if (diagnostic) {
15317
+ diagnostic.record(
15318
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15319
+ diagnostic.sampleId
15320
+ );
15321
+ }
14777
15322
  reporter.warn(
14778
15323
  `[baseline] dropping point with non-finite/negative magnitude \u2014 duration=${JSON.stringify(point.duration)}, cost=${JSON.stringify(point.cost)}, hh_work=${JSON.stringify(point.hh_work)}`
14779
15324
  );
@@ -14795,7 +15340,7 @@ function normalizeBaselinePoint(point, reporter) {
14795
15340
  }
14796
15341
 
14797
15342
  // src/baselines/apply-baseline-points.ts
14798
- function applyBaselinePoints(adapter, points, reporter) {
15343
+ function applyBaselinePoints(adapter, points, reporter, recordDiagnostic = noopLoadDiagnosticRecorder) {
14799
15344
  const idByProplanner = /* @__PURE__ */ new Map();
14800
15345
  adapter.forEachActivity((a, id) => {
14801
15346
  const pid = a.proplannerId;
@@ -14804,9 +15349,21 @@ function applyBaselinePoints(adapter, points, reporter) {
14804
15349
  const grouped = /* @__PURE__ */ new Map();
14805
15350
  for (const p of points) {
14806
15351
  const activityId = p.activityId;
14807
- if (typeof activityId !== "number") continue;
15352
+ if (typeof activityId !== "number") {
15353
+ recordDiagnostic(
15354
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15355
+ String(activityId ?? "unknown")
15356
+ );
15357
+ continue;
15358
+ }
14808
15359
  const coreId = idByProplanner.get(activityId);
14809
- if (coreId === void 0) continue;
15360
+ if (coreId === void 0) {
15361
+ recordDiagnostic(
15362
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15363
+ String(activityId)
15364
+ );
15365
+ continue;
15366
+ }
14810
15367
  const arr = grouped.get(coreId);
14811
15368
  if (arr) arr.push(p);
14812
15369
  else grouped.set(coreId, [p]);
@@ -14816,7 +15373,12 @@ function applyBaselinePoints(adapter, points, reporter) {
14816
15373
  adapter.setActivityField(
14817
15374
  coreId,
14818
15375
  "baselinePoints",
14819
- group.map((point) => normalizeBaselinePoint(point, reporter)).filter((point) => point !== null)
15376
+ group.map(
15377
+ (point) => normalizeBaselinePoint(point, reporter, {
15378
+ record: recordDiagnostic,
15379
+ sampleId: coreId
15380
+ })
15381
+ ).filter((point) => point !== null)
14820
15382
  );
14821
15383
  changed.push(coreId);
14822
15384
  }
@@ -14861,12 +15423,13 @@ function emitBaselineSnapshotColumns(state) {
14861
15423
  }
14862
15424
 
14863
15425
  // src/baselines/apply-baseline-overlay.ts
14864
- function applyBaselineOverlay(state, points, now, reporter, defaultBaseCalendarId = null) {
15426
+ function applyBaselineOverlay(state, points, now, reporter, defaultBaseCalendarId = null, recordDiagnostic = noopLoadDiagnosticRecorder) {
14865
15427
  const changed = /* @__PURE__ */ new Set();
14866
15428
  for (const id of applyBaselinePoints(
14867
15429
  state,
14868
15430
  points,
14869
- reporter
15431
+ reporter,
15432
+ recordDiagnostic
14870
15433
  )) {
14871
15434
  changed.add(id);
14872
15435
  }
@@ -15105,7 +15668,7 @@ async function dispatchCalendarReconcile(action, options, deps) {
15105
15668
  },
15106
15669
  {
15107
15670
  action,
15108
- autoscheduleFrom: "roots",
15671
+ autoscheduleFrom: AUTOSCHEDULE_SCOPE.ROOTS,
15109
15672
  recomputeParentsFrom: touchedIds,
15110
15673
  now: deps.now,
15111
15674
  options
@@ -15176,7 +15739,7 @@ function dispatchActivityCopy(action, deps) {
15176
15739
  throw new Error(`Selected activity ${id} is missing`);
15177
15740
  return {
15178
15741
  originalId: id,
15179
- originalParentId: activity.parentId ?? "0",
15742
+ originalParentId: activity.parentId ?? ROOT_PARENT_ID,
15180
15743
  overrides: copyOverrides(activity)
15181
15744
  };
15182
15745
  }),
@@ -15185,7 +15748,7 @@ function dispatchActivityCopy(action, deps) {
15185
15748
  ).map((link) => cloneDomainValue(link))
15186
15749
  };
15187
15750
  const selection = dispatchSelectionReplace(
15188
- { kind: "selection-replace", activityIds: [] },
15751
+ { kind: DISPATCH_ACTION_KIND.SELECTION_REPLACE, activityIds: [] },
15189
15752
  { adapter: deps.adapter }
15190
15753
  );
15191
15754
  if (!selection.ok) return selection;
@@ -15247,6 +15810,7 @@ async function dispatchActivityPasteCopied(action, options, deps) {
15247
15810
  const afterSiblingId = mappedParent === void 0 ? previousRootId ?? destination.afterSiblingId : void 0;
15248
15811
  const created = await createActivityCore(
15249
15812
  {
15813
+ kind: DISPATCH_ACTION_KIND.ACTIVITY_CREATE,
15250
15814
  parentId: mappedParent ?? destination.parentId,
15251
15815
  ...afterSiblingId === void 0 ? {} : { afterSiblingId },
15252
15816
  overrides: cloneDomainValue(copied.overrides),
@@ -15280,7 +15844,7 @@ async function dispatchActivityPasteCopied(action, options, deps) {
15280
15844
  const target = originalToNew.get(copiedLink.target);
15281
15845
  if (source === void 0 || target === void 0) return invariantFailure();
15282
15846
  const operation = {
15283
- kind: "create",
15847
+ kind: LINK_OPERATION_KIND.CREATE,
15284
15848
  source,
15285
15849
  target,
15286
15850
  type: copiedLink.type,
@@ -15332,94 +15896,97 @@ async function dispatchActivityPasteCopied(action, options, deps) {
15332
15896
 
15333
15897
  // src/dispatch/dispatch.ts
15334
15898
  async function performDispatch(action, options, deps) {
15335
- if (action.kind === "activity-copy") {
15899
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_COPY) {
15336
15900
  return dispatchActivityCopy(action, {
15337
15901
  adapter: deps.adapter,
15338
15902
  clipboard: deps.activityClipboard
15339
15903
  });
15340
15904
  }
15341
- if (action.kind === "calendar-reconcile") {
15905
+ if (action.kind === DISPATCH_ACTION_KIND.CALENDAR_RECONCILE) {
15342
15906
  return dispatchCalendarReconcile(action, options, deps);
15343
15907
  }
15344
- if (action.kind === "activity-clipboard-clear") {
15908
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR) {
15345
15909
  return dispatchActivityClipboardClear(action, deps.activityClipboard);
15346
15910
  }
15347
- if (action.kind === "activity-paste-copied") {
15911
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_PASTE_COPIED) {
15348
15912
  return dispatchActivityPasteCopied(action, options, deps);
15349
15913
  }
15350
- if (action.kind === "activity-batch") {
15914
+ if (action.kind === ACTIVITY_BATCH_ACTION_KIND) {
15351
15915
  return dispatchActivityBatch(action, options, deps);
15352
15916
  }
15353
- if (action.kind === "persistence-acknowledge") {
15917
+ if (action.kind === DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
15354
15918
  return dispatchPersistenceAcknowledge(action, deps);
15355
15919
  }
15356
- if (action.kind === "baseline-apply") {
15920
+ if (action.kind === DISPATCH_ACTION_KIND.BASELINE_APPLY) {
15357
15921
  return dispatchBaselineApply(action, deps);
15358
15922
  }
15359
- if (action.kind === "ponderator-criterion-set") {
15923
+ if (action.kind === DISPATCH_ACTION_KIND.PONDERATOR_CRITERION_SET) {
15360
15924
  return dispatchPonderatorCriterionSet(action, deps);
15361
15925
  }
15362
- if (action.kind === "status-criteria-set") {
15926
+ if (action.kind === DISPATCH_ACTION_KIND.STATUS_CRITERIA_SET) {
15363
15927
  return dispatchStatusCriteriaSet(action, deps);
15364
15928
  }
15365
- if (action.kind === "link-create" || action.kind === "link-update" || action.kind === "link-delete") {
15929
+ if (action.kind === DISPATCH_ACTION_KIND.LINK_CREATE || action.kind === DISPATCH_ACTION_KIND.LINK_UPDATE || action.kind === DISPATCH_ACTION_KIND.LINK_DELETE) {
15366
15930
  return dispatchLink(action, options, deps);
15367
15931
  }
15368
- if (action.kind === "links-batch") {
15932
+ if (action.kind === DISPATCH_ACTION_KIND.LINKS_BATCH) {
15369
15933
  return dispatchLinksBatch(action, options, deps);
15370
15934
  }
15371
- if (action.kind === "activity-create") {
15935
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_CREATE) {
15372
15936
  return dispatchActivityCreate(action, options, deps);
15373
15937
  }
15374
- if (action.kind === "activity-delete") {
15938
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_DELETE) {
15375
15939
  return dispatchActivityDelete(action, options, deps);
15376
15940
  }
15377
- if (action.kind === "activity-move") {
15941
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_MOVE) {
15378
15942
  return dispatchActivityMove(action, options, deps);
15379
15943
  }
15380
- if (action.kind === "activity-indent") {
15944
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_INDENT) {
15381
15945
  return dispatchActivityIndent(action, options, deps);
15382
15946
  }
15383
- if (action.kind === "activity-outdent") {
15947
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_OUTDENT) {
15384
15948
  return dispatchActivityOutdent(action, options, deps);
15385
15949
  }
15386
- if (action.kind === "activity-set-progress") {
15950
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_SET_PROGRESS) {
15387
15951
  return dispatchActivitySetProgress(action, options, deps);
15388
15952
  }
15389
- if (action.kind === "dates-batch") {
15953
+ if (action.kind === DISPATCH_ACTION_KIND.DATES_BATCH) {
15390
15954
  return dispatchDatesBatch(action, options, deps);
15391
15955
  }
15392
- if (action.kind === "bulk-edit") {
15956
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
15393
15957
  return dispatchBulkEdit(action, options, deps);
15394
15958
  }
15395
- if (action.kind === "selection-toggle") {
15959
+ if (action.kind === DISPATCH_ACTION_KIND.SELECTION_TOGGLE) {
15396
15960
  return dispatchSelectionToggle(action, selectionDeps(deps));
15397
15961
  }
15398
- if (action.kind === "selection-replace") {
15962
+ if (action.kind === DISPATCH_ACTION_KIND.SELECTION_REPLACE) {
15399
15963
  return dispatchSelectionReplace(action, selectionDeps(deps));
15400
15964
  }
15401
- if (action.kind === "visibility-set") {
15965
+ if (action.kind === DISPATCH_ACTION_KIND.VISIBILITY_SET) {
15402
15966
  return dispatchVisibilitySet(action, selectionDeps(deps));
15403
15967
  }
15404
- if (action.kind === "filter-set") {
15968
+ if (action.kind === DISPATCH_ACTION_KIND.FILTER_SET) {
15405
15969
  return dispatchFilterSet(action, {
15406
15970
  adapter: deps.adapter,
15407
15971
  hoursPerDay: deps.sector.hoursPerDay
15408
15972
  });
15409
15973
  }
15410
- if (action.kind === "sort-set") {
15974
+ if (action.kind === DISPATCH_ACTION_KIND.SORT_SET) {
15411
15975
  return dispatchSortSet(action, { adapter: deps.adapter });
15412
15976
  }
15413
- if (action.kind === "sir-sync") {
15977
+ if (action.kind === DISPATCH_ACTION_KIND.SIR_SYNC) {
15414
15978
  return dispatchSirSync(action, deps);
15415
15979
  }
15416
- if (action.kind === "activity-lookahead-sync") {
15980
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC) {
15417
15981
  return dispatchActivityLookaheadSync(action, options, deps);
15418
15982
  }
15419
- if (action.kind === "inline-edit" && (action.column === COLUMN.CUSTOM_PREDECESSORS || action.column === COLUMN.CUSTOM_SUCESSORS)) {
15983
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_CONVERT) {
15984
+ return dispatchActivityLookaheadConvert(action, options, deps);
15985
+ }
15986
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT && (action.column === COLUMN.CUSTOM_PREDECESSORS || action.column === COLUMN.CUSTOM_SUCESSORS)) {
15420
15987
  return dispatchInlineEditLinks(action, options, deps);
15421
15988
  }
15422
- if (action.kind !== "inline-edit") {
15989
+ if (action.kind !== DISPATCH_ACTION_KIND.INLINE_EDIT) {
15423
15990
  return assertNever(
15424
15991
  action,
15425
15992
  `[ScheduleCore] dispatch kind "${action.kind}" not supported yet`
@@ -15446,7 +16013,7 @@ function coerceActivityFieldValue(field, value) {
15446
16013
 
15447
16014
  // src/calendar/adapter.ts
15448
16015
  function createWorkCalendarAdapter(instance, options = {}) {
15449
- const defaultUnit = options.defaultUnit ?? "hour";
16016
+ const defaultUnit = options.defaultUnit ?? CALENDAR_UNIT.HOUR;
15450
16017
  return {
15451
16018
  getCalendar(calendarId) {
15452
16019
  const calendar = instance.getCalendar(String(calendarId));
@@ -18250,90 +18817,6 @@ function collectDescendantIdsBFS(adapter, rootId) {
18250
18817
  return result;
18251
18818
  }
18252
18819
 
18253
- // src/internal/state/write-capture.ts
18254
- var WriteCapture = class {
18255
- _journal = null;
18256
- begin() {
18257
- this._journal = {
18258
- dirty: /* @__PURE__ */ new Set(),
18259
- before: /* @__PURE__ */ new Map(),
18260
- ops: [],
18261
- linkFieldCaptured: /* @__PURE__ */ new Set(),
18262
- correlativeBefore: /* @__PURE__ */ new Map(),
18263
- scheduledBefore: /* @__PURE__ */ new Map(),
18264
- progressFallbackBefore: /* @__PURE__ */ new Map()
18265
- };
18266
- }
18267
- peek() {
18268
- return this._journal;
18269
- }
18270
- end() {
18271
- this._journal = null;
18272
- }
18273
- note(key, current) {
18274
- const journal = this._journal;
18275
- if (!journal) return;
18276
- if (!journal.before.has(key))
18277
- journal.before.set(key, cloneCoreActivity(current));
18278
- journal.dirty.add(key);
18279
- }
18280
- noteInsert(activityId) {
18281
- this._journal?.ops.push({ kind: "insert", activityId });
18282
- }
18283
- noteRemove(activityId, current) {
18284
- this._journal?.ops.push({
18285
- kind: "remove",
18286
- activityId,
18287
- before: cloneCoreActivity(current)
18288
- });
18289
- }
18290
- noteLinkAdd(linkId) {
18291
- this._journal?.ops.push({ kind: "link-add", linkId });
18292
- }
18293
- noteLinkRemove(linkId, current) {
18294
- this._journal?.ops.push({
18295
- kind: "link-remove",
18296
- linkId,
18297
- before: cloneLink(current)
18298
- });
18299
- }
18300
- noteCorrelativeBefore(activityId, before) {
18301
- const journal = this._journal;
18302
- if (!journal || journal.correlativeBefore.has(activityId)) return;
18303
- journal.correlativeBefore.set(activityId, before);
18304
- }
18305
- noteScheduledBefore(activityId, current) {
18306
- const journal = this._journal;
18307
- if (!journal) return;
18308
- const beforeImage = cloneCoreActivity(current);
18309
- if (!journal.scheduledBefore.has(activityId)) {
18310
- journal.scheduledBefore.set(activityId, beforeImage);
18311
- }
18312
- if (!journal.before.has(activityId)) {
18313
- journal.before.set(activityId, beforeImage);
18314
- }
18315
- journal.dirty.add(activityId);
18316
- }
18317
- noteLinkField(linkId, current) {
18318
- const journal = this._journal;
18319
- if (!journal || journal.linkFieldCaptured.has(linkId)) return;
18320
- journal.linkFieldCaptured.add(linkId);
18321
- journal.ops.push({
18322
- kind: "link-field",
18323
- linkId,
18324
- before: cloneLink(current)
18325
- });
18326
- }
18327
- noteProgressFallback(activityId, current) {
18328
- const journal = this._journal;
18329
- if (!journal || journal.progressFallbackBefore.has(activityId)) return;
18330
- journal.progressFallbackBefore.set(activityId, current);
18331
- }
18332
- };
18333
- function cloneLink(link) {
18334
- return { ...link };
18335
- }
18336
-
18337
18820
  // src/internal/state/calendar-calculator.ts
18338
18821
  var CalendarCalculator = class {
18339
18822
  _cache = {
@@ -18987,9 +19470,9 @@ var ScheduleState = class _ScheduleState {
18987
19470
  this._reInsertRemovedActivities(ops);
18988
19471
  this._reAddRemovedLinks(ops);
18989
19472
  this._restoreLinkFields(ops);
18990
- this._restoreCorrelatives(correlativeBefore);
18991
19473
  this._restoreActivityFields(scheduledBefore);
18992
19474
  this._restoreActivityFields(before);
19475
+ this._restoreCorrelatives(correlativeBefore);
18993
19476
  this._restoreProgressFallbacks(progressFallbackBefore);
18994
19477
  if (this._viewStateBefore !== null) {
18995
19478
  this._viewState.restore(this._viewStateBefore);
@@ -19020,24 +19503,33 @@ var ScheduleState = class _ScheduleState {
19020
19503
  }
19021
19504
  _undoLinkAdds(ops) {
19022
19505
  for (const op of ops)
19023
- if (op.kind === "link-add") this._detachLink(op.linkId);
19506
+ if (op.kind === WRITE_OPERATION_KIND.LINK_ADD) {
19507
+ this._detachLink(op.linkId);
19508
+ }
19024
19509
  }
19025
19510
  _undoInserts(ops) {
19026
19511
  for (const op of ops)
19027
- if (op.kind === "insert") this._activities.delete(op.activityId);
19512
+ if (op.kind === WRITE_OPERATION_KIND.INSERT) {
19513
+ this._activities.delete(op.activityId);
19514
+ }
19028
19515
  }
19029
19516
  _reInsertRemovedActivities(ops) {
19030
19517
  for (const op of ops)
19031
- if (op.kind === "remove") this._activities.set(op.activityId, op.before);
19518
+ if (op.kind === WRITE_OPERATION_KIND.REMOVE) {
19519
+ this._activities.set(op.activityId, op.before);
19520
+ }
19032
19521
  }
19033
19522
  _reAddRemovedLinks(ops) {
19034
19523
  for (const op of ops)
19035
- if (op.kind === "link-remove") this._attachLink(op.before);
19524
+ if (op.kind === WRITE_OPERATION_KIND.LINK_REMOVE) {
19525
+ this._attachLink(op.before);
19526
+ }
19036
19527
  }
19037
19528
  _restoreLinkFields(ops) {
19038
19529
  for (const op of ops)
19039
- if (op.kind === "link-field" && this._links.has(op.linkId))
19530
+ if (op.kind === WRITE_OPERATION_KIND.LINK_FIELD && this._links.has(op.linkId)) {
19040
19531
  this._links.set(op.linkId, op.before);
19532
+ }
19041
19533
  }
19042
19534
  _restoreActivityFields(before) {
19043
19535
  for (const [id, snapshot] of before) {
@@ -19204,7 +19696,8 @@ function withoutDerivedFields(entry, derivedFields) {
19204
19696
  ([field]) => !derivedFields.has(field)
19205
19697
  )
19206
19698
  );
19207
- if (entry.kind === "updated" && Object.keys(fields).length === 0) return null;
19699
+ if (entry.kind === ENTITY_CHANGE_KIND.UPDATED && Object.keys(fields).length === 0)
19700
+ return null;
19208
19701
  return {
19209
19702
  ...entry,
19210
19703
  ...entry.fields === void 0 ? {} : { fields },
@@ -19217,7 +19710,7 @@ function buildHistoryChangeSet(changes) {
19217
19710
  after: null
19218
19711
  }));
19219
19712
  const linksWithoutAfter = changes.links.map((entry) => withoutDerivedFields(entry, DERIVED_LINK_FIELDS)).filter((entry) => entry !== null);
19220
- const source = changes.source.kind === "activity-batch" ? { ...changes.source, items: [], links: [] } : changes.source;
19713
+ const source = changes.source.kind === ACTIVITY_BATCH_ACTION_KIND ? { ...changes.source, items: [], links: [] } : changes.source;
19221
19714
  return cloneDomainValue({
19222
19715
  ...changes,
19223
19716
  source,
@@ -19249,12 +19742,12 @@ function captureCreatedSnapshots(state, changeSet) {
19249
19742
  const afterSnap = /* @__PURE__ */ new Map();
19250
19743
  const afterLinks = /* @__PURE__ */ new Map();
19251
19744
  for (const ch of changeSet.activities) {
19252
- if (ch.kind !== "created") continue;
19745
+ if (ch.kind !== ENTITY_CHANGE_KIND.CREATED) continue;
19253
19746
  const live = state.getActivity(String(ch.id));
19254
19747
  if (live) afterSnap.set(String(ch.id), structuredCloneActivity(live));
19255
19748
  }
19256
19749
  for (const ch of changeSet.links) {
19257
- if (ch.kind === "deleted") continue;
19750
+ if (ch.kind === ENTITY_CHANGE_KIND.DELETED) continue;
19258
19751
  const live = state.getLink(String(ch.id));
19259
19752
  if (live) afterLinks.set(String(ch.id), { ...live });
19260
19753
  }
@@ -19266,7 +19759,7 @@ function computeCoalesceKey(action) {
19266
19759
  return `inline-edit:${String(action.activityId)}:${action.column}`;
19267
19760
  }
19268
19761
  function isSimpleInlineEntry(e) {
19269
- return e.changeSet.activities.length === 1 && e.changeSet.activities[0]?.kind === "updated" && e.changeSet.links.length === 0 && !e.beforeSnap?.size && !e.afterSnap?.size;
19762
+ return e.changeSet.activities.length === 1 && e.changeSet.activities[0]?.kind === ENTITY_CHANGE_KIND.UPDATED && e.changeSet.links.length === 0 && !e.beforeSnap?.size && !e.afterSnap?.size;
19270
19763
  }
19271
19764
  function canCoalesce(top, next) {
19272
19765
  if (!isSimpleInlineEntry(top) || !isSimpleInlineEntry(next)) return false;
@@ -19295,19 +19788,29 @@ function mergeCoalesced(top, next) {
19295
19788
  };
19296
19789
  return buildUndoEntry(changeSet);
19297
19790
  }
19791
+ var DISPATCH_HISTORY_POLICY = {
19792
+ RECORD: "record",
19793
+ SKIP: "skip",
19794
+ CHECKPOINT_ON_SUCCESS: "checkpoint-on-success"
19795
+ };
19796
+ var CHANGE_SET_SIDE = {
19797
+ BEFORE: "before",
19798
+ AFTER: "after"
19799
+ };
19298
19800
  function getDispatchHistoryPolicy(action) {
19299
19801
  if (action.kind === DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
19300
- return "checkpoint-on-success";
19802
+ return DISPATCH_HISTORY_POLICY.CHECKPOINT_ON_SUCCESS;
19301
19803
  }
19302
19804
  if (action.kind === DISPATCH_ACTION_KIND.SIR_SYNC || action.kind === DISPATCH_ACTION_KIND.CALENDAR_RECONCILE || action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC || action.kind === DISPATCH_ACTION_KIND.BASELINE_APPLY || action.kind === DISPATCH_ACTION_KIND.PONDERATOR_CRITERION_SET || action.kind === DISPATCH_ACTION_KIND.STATUS_CRITERIA_SET || action.kind === DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR || action.kind === DISPATCH_ACTION_KIND.ACTIVITY_COPY || action.kind === DISPATCH_ACTION_KIND.SELECTION_TOGGLE || action.kind === DISPATCH_ACTION_KIND.SELECTION_REPLACE || action.kind === DISPATCH_ACTION_KIND.VISIBILITY_SET || action.kind === DISPATCH_ACTION_KIND.FILTER_SET || action.kind === DISPATCH_ACTION_KIND.SORT_SET) {
19303
- return "skip";
19805
+ return DISPATCH_HISTORY_POLICY.SKIP;
19304
19806
  }
19305
- return "record";
19807
+ return DISPATCH_HISTORY_POLICY.RECORD;
19306
19808
  }
19307
19809
  function needsResync(entry) {
19308
19810
  for (const change of entry.changeSet.activities) {
19309
- if (change.kind === "created" || change.kind === "deleted") return true;
19310
- if (change.kind === "updated" && change.fields && COLUMN.CUSTOM_ID in change.fields)
19811
+ if (change.kind === ENTITY_CHANGE_KIND.CREATED || change.kind === ENTITY_CHANGE_KIND.DELETED)
19812
+ return true;
19813
+ if (change.kind === ENTITY_CHANGE_KIND.UPDATED && change.fields && COLUMN.CUSTOM_ID in change.fields)
19311
19814
  return true;
19312
19815
  }
19313
19816
  return false;
@@ -19317,33 +19820,41 @@ function buildInverseChangeSet(state, entry, side) {
19317
19820
  const links = [];
19318
19821
  for (const change of entry.changeSet.activities) {
19319
19822
  const activityId = String(change.id);
19320
- if (change.kind === "updated") {
19823
+ if (change.kind === ENTITY_CHANGE_KIND.UPDATED) {
19321
19824
  const snapshot = state.getActivity(activityId);
19322
19825
  activities.push({
19323
19826
  id: activityId,
19324
- kind: "updated",
19827
+ kind: ENTITY_CHANGE_KIND.UPDATED,
19325
19828
  fields: historyFields(change.fields, side),
19326
19829
  after: snapshot ? structuredCloneActivity(snapshot) : null
19327
19830
  });
19328
- } else if (change.kind === "deleted") {
19329
- if (side === "before") {
19831
+ } else if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
19832
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19330
19833
  const snapshot = state.getActivity(activityId);
19331
19834
  activities.push({
19332
19835
  id: activityId,
19333
- kind: "created",
19836
+ kind: ENTITY_CHANGE_KIND.CREATED,
19334
19837
  after: snapshot ? structuredCloneActivity(snapshot) : null
19335
19838
  });
19336
19839
  } else {
19337
- activities.push({ id: activityId, kind: "deleted", after: null });
19840
+ activities.push({
19841
+ id: activityId,
19842
+ kind: ENTITY_CHANGE_KIND.DELETED,
19843
+ after: null
19844
+ });
19338
19845
  }
19339
19846
  } else {
19340
- if (side === "before") {
19341
- activities.push({ id: activityId, kind: "deleted", after: null });
19847
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19848
+ activities.push({
19849
+ id: activityId,
19850
+ kind: ENTITY_CHANGE_KIND.DELETED,
19851
+ after: null
19852
+ });
19342
19853
  } else {
19343
19854
  const snapshot = state.getActivity(activityId);
19344
19855
  activities.push({
19345
19856
  id: activityId,
19346
- kind: "created",
19857
+ kind: ENTITY_CHANGE_KIND.CREATED,
19347
19858
  after: snapshot ? structuredCloneActivity(snapshot) : null
19348
19859
  });
19349
19860
  }
@@ -19351,44 +19862,52 @@ function buildInverseChangeSet(state, entry, side) {
19351
19862
  }
19352
19863
  for (const change of entry.changeSet.links) {
19353
19864
  const linkId = String(change.id);
19354
- if (change.kind === "updated") {
19865
+ if (change.kind === ENTITY_CHANGE_KIND.UPDATED) {
19355
19866
  const lk = state.getLink(linkId);
19356
19867
  links.push({
19357
19868
  id: linkId,
19358
- kind: "updated",
19869
+ kind: ENTITY_CHANGE_KIND.UPDATED,
19359
19870
  fields: historyFields(change.fields, side),
19360
19871
  after: lk ? snapshotToLink(lk) : null
19361
19872
  });
19362
- } else if (change.kind === "deleted") {
19363
- if (side === "before") {
19873
+ } else if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
19874
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19364
19875
  const lk = state.getLink(linkId);
19365
19876
  links.push({
19366
19877
  id: linkId,
19367
- kind: "created",
19878
+ kind: ENTITY_CHANGE_KIND.CREATED,
19368
19879
  after: lk ? snapshotToLink(lk) : null
19369
19880
  });
19370
19881
  } else {
19371
- links.push({ id: linkId, kind: "deleted", after: null });
19882
+ links.push({
19883
+ id: linkId,
19884
+ kind: ENTITY_CHANGE_KIND.DELETED,
19885
+ after: null
19886
+ });
19372
19887
  }
19373
19888
  } else {
19374
- if (side === "before") {
19375
- links.push({ id: linkId, kind: "deleted", after: null });
19889
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19890
+ links.push({
19891
+ id: linkId,
19892
+ kind: ENTITY_CHANGE_KIND.DELETED,
19893
+ after: null
19894
+ });
19376
19895
  } else {
19377
19896
  const lk = state.getLink(linkId);
19378
19897
  links.push({
19379
19898
  id: linkId,
19380
- kind: "created",
19899
+ kind: ENTITY_CHANGE_KIND.CREATED,
19381
19900
  after: lk ? snapshotToLink(lk) : null
19382
19901
  });
19383
19902
  }
19384
19903
  }
19385
19904
  }
19386
19905
  const viewState = (entry.changeSet.viewState ?? []).map(
19387
- (change) => side === "before" ? invertViewStateChange(change) : change
19906
+ (change) => side === CHANGE_SET_SIDE.BEFORE ? invertViewStateChange(change) : change
19388
19907
  );
19389
19908
  return {
19390
19909
  source: {
19391
- kind: side === "before" ? CHANGE_SET_SOURCE_KIND.UNDO : CHANGE_SET_SOURCE_KIND.REDO
19910
+ kind: side === CHANGE_SET_SIDE.BEFORE ? CHANGE_SET_SOURCE_KIND.UNDO : CHANGE_SET_SOURCE_KIND.REDO
19392
19911
  },
19393
19912
  activities,
19394
19913
  links,
@@ -19403,7 +19922,7 @@ function historyFields(fields, side) {
19403
19922
  return Object.fromEntries(
19404
19923
  Object.entries(fields).map(([field, values]) => [
19405
19924
  field,
19406
- side === "before" ? {
19925
+ side === CHANGE_SET_SIDE.BEFORE ? {
19407
19926
  before: cloneDomainValue(values.after),
19408
19927
  after: cloneDomainValue(values.before)
19409
19928
  } : {
@@ -19434,26 +19953,26 @@ function changeSetIsSubstantive(cs) {
19434
19953
  return cs.activities.length > 0 || cs.links.length > 0 || (cs.viewState?.length ?? 0) > 0 || (cs.effects?.length ?? 0) > 0;
19435
19954
  }
19436
19955
  function applyUndo(state, entry) {
19437
- applyChangeSetSide(state, entry, "before");
19956
+ applyChangeSetSide(state, entry, CHANGE_SET_SIDE.BEFORE);
19438
19957
  }
19439
19958
  function applyRedo(state, entry) {
19440
- applyChangeSetSide(state, entry, "after");
19959
+ applyChangeSetSide(state, entry, CHANGE_SET_SIDE.AFTER);
19441
19960
  }
19442
19961
  function applyChangeSetSide(state, entry, side) {
19443
19962
  const cs = entry.changeSet;
19444
19963
  for (const ch of cs.activities) {
19445
- if (ch.kind === "updated") {
19964
+ if (ch.kind === ENTITY_CHANGE_KIND.UPDATED) {
19446
19965
  if (!ch.fields) continue;
19447
19966
  for (const [field, fieldValue] of Object.entries(ch.fields)) {
19448
19967
  setActivityFieldDynamic(
19449
19968
  state,
19450
19969
  ch.id,
19451
19970
  field,
19452
- side === "before" ? fieldValue.before : fieldValue.after
19971
+ side === CHANGE_SET_SIDE.BEFORE ? fieldValue.before : fieldValue.after
19453
19972
  );
19454
19973
  }
19455
- } else if (ch.kind === "deleted") {
19456
- if (side === "before") {
19974
+ } else if (ch.kind === ENTITY_CHANGE_KIND.DELETED) {
19975
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19457
19976
  const snap = entry.beforeSnap?.get(String(ch.id));
19458
19977
  if (!snap) {
19459
19978
  throw new Error(
@@ -19465,7 +19984,7 @@ function applyChangeSetSide(state, entry, side) {
19465
19984
  state.removeActivity(String(ch.id));
19466
19985
  }
19467
19986
  } else {
19468
- if (side === "before") {
19987
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19469
19988
  state.removeActivity(String(ch.id));
19470
19989
  } else {
19471
19990
  const snap = entry.afterSnap?.get(String(ch.id));
@@ -19479,13 +19998,13 @@ function applyChangeSetSide(state, entry, side) {
19479
19998
  }
19480
19999
  }
19481
20000
  for (const ch of cs.links) {
19482
- if (ch.kind === "updated") {
20001
+ if (ch.kind === ENTITY_CHANGE_KIND.UPDATED) {
19483
20002
  if (!ch.fields) continue;
19484
20003
  if (Object.hasOwn(ch.fields, "source") || Object.hasOwn(ch.fields, "target")) {
19485
- const snapshot = side === "before" ? entry.beforeLinks?.get(String(ch.id)) : entry.afterLinks?.get(String(ch.id));
20004
+ const snapshot = side === CHANGE_SET_SIDE.BEFORE ? entry.beforeLinks?.get(String(ch.id)) : entry.afterLinks?.get(String(ch.id));
19486
20005
  if (!snapshot) {
19487
20006
  throw new Error(
19488
- `${side === "before" ? "undo" : "redo"}: missing link snapshot for ${ch.id}`
20007
+ `${side === CHANGE_SET_SIDE.BEFORE ? "undo" : "redo"}: missing link snapshot for ${ch.id}`
19489
20008
  );
19490
20009
  }
19491
20010
  state.removeLink(String(ch.id));
@@ -19497,11 +20016,11 @@ function applyChangeSetSide(state, entry, side) {
19497
20016
  state,
19498
20017
  String(ch.id),
19499
20018
  field,
19500
- side === "before" ? fv.before : fv.after
20019
+ side === CHANGE_SET_SIDE.BEFORE ? fv.before : fv.after
19501
20020
  );
19502
20021
  }
19503
- } else if (ch.kind === "deleted") {
19504
- if (side === "before") {
20022
+ } else if (ch.kind === ENTITY_CHANGE_KIND.DELETED) {
20023
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19505
20024
  const lk = entry.beforeLinks?.get(String(ch.id));
19506
20025
  if (!lk) {
19507
20026
  throw new Error(
@@ -19513,7 +20032,7 @@ function applyChangeSetSide(state, entry, side) {
19513
20032
  state.removeLink(String(ch.id));
19514
20033
  }
19515
20034
  } else {
19516
- if (side === "before") {
20035
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19517
20036
  state.removeLink(String(ch.id));
19518
20037
  } else {
19519
20038
  const lk = entry.afterLinks?.get(String(ch.id));
@@ -19530,17 +20049,17 @@ function applyChangeSetSide(state, entry, side) {
19530
20049
  if (change.checked) {
19531
20050
  state.setChecked(
19532
20051
  change.activityId,
19533
- side === "before" ? change.checked.before : change.checked.after
20052
+ side === CHANGE_SET_SIDE.BEFORE ? change.checked.before : change.checked.after
19534
20053
  );
19535
20054
  }
19536
20055
  if (change.visible) {
19537
20056
  state.setVisible(
19538
20057
  change.activityId,
19539
- side === "before" ? change.visible.before : change.visible.after
20058
+ side === CHANGE_SET_SIDE.BEFORE ? change.visible.before : change.visible.after
19540
20059
  );
19541
20060
  }
19542
20061
  }
19543
- const progressFallbacks = side === "before" ? entry.progressFallbackBefore : entry.progressFallbackAfter;
20062
+ const progressFallbacks = side === CHANGE_SET_SIDE.BEFORE ? entry.progressFallbackBefore : entry.progressFallbackAfter;
19544
20063
  for (const [activityId, value] of progressFallbacks ?? []) {
19545
20064
  state.setProgressFallback(activityId, value);
19546
20065
  }
@@ -19677,11 +20196,11 @@ function collectResequencedParents(changes, parentOf) {
19677
20196
  };
19678
20197
  for (const change of changes.activities) {
19679
20198
  const activityId = String(change.id);
19680
- if (change.kind === "created") {
20199
+ if (change.kind === ENTITY_CHANGE_KIND.CREATED) {
19681
20200
  addParentOf(activityId);
19682
20201
  continue;
19683
20202
  }
19684
- if (change.kind === "deleted") {
20203
+ if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
19685
20204
  const deletedFields = change.fields;
19686
20205
  if (deletedFields && "parentId" in deletedFields) {
19687
20206
  touched.add(parentKeyOf2(deletedFields.parentId?.before));
@@ -19744,56 +20263,62 @@ function buildStateSnapshot(activities, links, calendars, baseCalendars = []) {
19744
20263
  };
19745
20264
  }
19746
20265
 
20266
+ // src/boundary/save/field-policy.ts
20267
+ var SAVE_FIELD_POLICY = {
20268
+ TRACKED: "tracked",
20269
+ IGNORED: "ignored"
20270
+ };
20271
+
19747
20272
  // src/boundary/save/activity-changes.ts
19748
20273
  var ACTIVITY_SAVE_FIELD_POLICY = {
19749
- id: "ignored",
19750
- proplannerId: "ignored",
19751
- parentId: "tracked",
19752
- name: "tracked",
19753
- description: "tracked",
19754
- type: "tracked",
19755
- startDate: "tracked",
19756
- endDate: "tracked",
19757
- durationHours: "tracked",
19758
- constraintType: "tracked",
19759
- constraintDate: "tracked",
19760
- autoScheduling: "tracked",
19761
- calendarId: "tracked",
19762
- assignedDefaultCalendar: "ignored",
19763
- dateOrigin: "tracked",
19764
- progress: "tracked",
19765
- cost: "tracked",
19766
- usedCost: "tracked",
19767
- realCost: "tracked",
19768
- workHours: "tracked",
19769
- realWorkHours: "tracked",
19770
- ponderator: "tracked",
19771
- hasCustomPonderator: "tracked",
19772
- correlativeId: "tracked",
19773
- uniqueCorrelativeId: "tracked",
19774
- customId: "tracked",
19775
- subcontractId: "tracked",
19776
- isLookahead: "tracked",
19777
- hasLookaheadTasks: "ignored",
19778
- newActivityIds: "tracked",
19779
- hasNewActivities: "tracked",
19780
- isNewActivity: "ignored",
19781
- pendingRequestIds: "ignored",
19782
- responsableIds: "tracked",
19783
- tagIds: "tracked",
19784
- baselinePoints: "ignored",
19785
- baselineSnapshot: "ignored",
19786
- recursiveDurationHours: "ignored",
19787
- isCritical: "ignored",
19788
- freeSlackHours: "ignored",
19789
- calendarDuration: "ignored",
19790
- expectedProgress: "ignored",
19791
- expectedProgressBaseline: "ignored",
19792
- status: "ignored",
19793
- criticalPath: "ignored"
20274
+ id: SAVE_FIELD_POLICY.IGNORED,
20275
+ proplannerId: SAVE_FIELD_POLICY.IGNORED,
20276
+ parentId: SAVE_FIELD_POLICY.TRACKED,
20277
+ name: SAVE_FIELD_POLICY.TRACKED,
20278
+ description: SAVE_FIELD_POLICY.TRACKED,
20279
+ type: SAVE_FIELD_POLICY.TRACKED,
20280
+ startDate: SAVE_FIELD_POLICY.TRACKED,
20281
+ endDate: SAVE_FIELD_POLICY.TRACKED,
20282
+ durationHours: SAVE_FIELD_POLICY.TRACKED,
20283
+ constraintType: SAVE_FIELD_POLICY.TRACKED,
20284
+ constraintDate: SAVE_FIELD_POLICY.TRACKED,
20285
+ autoScheduling: SAVE_FIELD_POLICY.TRACKED,
20286
+ calendarId: SAVE_FIELD_POLICY.TRACKED,
20287
+ assignedDefaultCalendar: SAVE_FIELD_POLICY.IGNORED,
20288
+ dateOrigin: SAVE_FIELD_POLICY.TRACKED,
20289
+ progress: SAVE_FIELD_POLICY.TRACKED,
20290
+ cost: SAVE_FIELD_POLICY.TRACKED,
20291
+ usedCost: SAVE_FIELD_POLICY.TRACKED,
20292
+ realCost: SAVE_FIELD_POLICY.TRACKED,
20293
+ workHours: SAVE_FIELD_POLICY.TRACKED,
20294
+ realWorkHours: SAVE_FIELD_POLICY.TRACKED,
20295
+ ponderator: SAVE_FIELD_POLICY.TRACKED,
20296
+ hasCustomPonderator: SAVE_FIELD_POLICY.TRACKED,
20297
+ correlativeId: SAVE_FIELD_POLICY.TRACKED,
20298
+ uniqueCorrelativeId: SAVE_FIELD_POLICY.TRACKED,
20299
+ customId: SAVE_FIELD_POLICY.TRACKED,
20300
+ subcontractId: SAVE_FIELD_POLICY.TRACKED,
20301
+ isLookahead: SAVE_FIELD_POLICY.TRACKED,
20302
+ hasLookaheadTasks: SAVE_FIELD_POLICY.IGNORED,
20303
+ newActivityIds: SAVE_FIELD_POLICY.TRACKED,
20304
+ hasNewActivities: SAVE_FIELD_POLICY.TRACKED,
20305
+ isNewActivity: SAVE_FIELD_POLICY.IGNORED,
20306
+ pendingRequestIds: SAVE_FIELD_POLICY.IGNORED,
20307
+ responsableIds: SAVE_FIELD_POLICY.TRACKED,
20308
+ tagIds: SAVE_FIELD_POLICY.TRACKED,
20309
+ baselinePoints: SAVE_FIELD_POLICY.IGNORED,
20310
+ baselineSnapshot: SAVE_FIELD_POLICY.IGNORED,
20311
+ recursiveDurationHours: SAVE_FIELD_POLICY.IGNORED,
20312
+ isCritical: SAVE_FIELD_POLICY.IGNORED,
20313
+ freeSlackHours: SAVE_FIELD_POLICY.IGNORED,
20314
+ calendarDuration: SAVE_FIELD_POLICY.IGNORED,
20315
+ expectedProgress: SAVE_FIELD_POLICY.IGNORED,
20316
+ expectedProgressBaseline: SAVE_FIELD_POLICY.IGNORED,
20317
+ status: SAVE_FIELD_POLICY.IGNORED,
20318
+ criticalPath: SAVE_FIELD_POLICY.IGNORED
19794
20319
  };
19795
20320
  var PERSISTABLE_ACTIVITY_FIELDS = Object.keys(ACTIVITY_SAVE_FIELD_POLICY).filter((field) => {
19796
- return ACTIVITY_SAVE_FIELD_POLICY[field] === "tracked";
20321
+ return ACTIVITY_SAVE_FIELD_POLICY[field] === SAVE_FIELD_POLICY.TRACKED;
19797
20322
  });
19798
20323
  var DATE_FIELDS2 = /* @__PURE__ */ new Set([
19799
20324
  "startDate",
@@ -19852,19 +20377,19 @@ function idArrayEquals(current, saved) {
19852
20377
 
19853
20378
  // src/boundary/save/link-changes.ts
19854
20379
  var LINK_SAVE_FIELD_POLICY = {
19855
- id: "ignored",
19856
- source: "tracked",
19857
- target: "tracked",
19858
- type: "tracked",
19859
- lag: "tracked",
19860
- freeSlackHours: "ignored",
19861
- isCritical: "ignored",
19862
- ganttId: "ignored",
19863
- sectorId: "ignored",
19864
- proplannerId: "ignored"
20380
+ id: SAVE_FIELD_POLICY.IGNORED,
20381
+ source: SAVE_FIELD_POLICY.TRACKED,
20382
+ target: SAVE_FIELD_POLICY.TRACKED,
20383
+ type: SAVE_FIELD_POLICY.TRACKED,
20384
+ lag: SAVE_FIELD_POLICY.TRACKED,
20385
+ freeSlackHours: SAVE_FIELD_POLICY.IGNORED,
20386
+ isCritical: SAVE_FIELD_POLICY.IGNORED,
20387
+ ganttId: SAVE_FIELD_POLICY.IGNORED,
20388
+ sectorId: SAVE_FIELD_POLICY.IGNORED,
20389
+ proplannerId: SAVE_FIELD_POLICY.IGNORED
19865
20390
  };
19866
20391
  var TRACKED_LINK_FIELDS = Object.keys(LINK_SAVE_FIELD_POLICY).filter((field) => {
19867
- return LINK_SAVE_FIELD_POLICY[field] === "tracked";
20392
+ return LINK_SAVE_FIELD_POLICY[field] === SAVE_FIELD_POLICY.TRACKED;
19868
20393
  });
19869
20394
  function linkChangedSince(baseline, current) {
19870
20395
  return TRACKED_LINK_FIELDS.some(
@@ -20225,24 +20750,24 @@ var WORKING_DAY_TRUE_VALUES = /* @__PURE__ */ new Set([
20225
20750
  "true"
20226
20751
  ]);
20227
20752
  var DEFAULT_ACTIVITY_CRETER = ACTIVITY_PONDERATOR_CRITERION.DURATION;
20228
- var DEFAULT_CONSTRAINT_TYPE = "asap";
20753
+ var DEFAULT_CONSTRAINT_TYPE = CONSTRAINT_TYPE.ASAP;
20229
20754
  var CONSTRAINT_LABEL_MAP = {
20230
- ASAP: "asap",
20231
- ALAP: "alap",
20232
- SNET: "snet",
20233
- SNLT: "snlt",
20234
- FNET: "fnet",
20235
- FNLT: "fnlt",
20236
- MSO: "mso",
20237
- MFO: "mfo",
20238
- "AS SOON AS POSSIBLE": "asap",
20239
- "AS LATE AS POSSIBLE": "alap",
20240
- "START NO EARLIER THAN": "snet",
20241
- "START NO LATER THAN": "snlt",
20242
- "FINISH NO EARLIER THAN": "fnet",
20243
- "FINISH NO LATER THAN": "fnlt",
20244
- "MUST START ON": "mso",
20245
- "MUST FINISH ON": "mfo"
20755
+ ASAP: CONSTRAINT_TYPE.ASAP,
20756
+ ALAP: CONSTRAINT_TYPE.ALAP,
20757
+ SNET: CONSTRAINT_TYPE.SNET,
20758
+ SNLT: CONSTRAINT_TYPE.SNLT,
20759
+ FNET: CONSTRAINT_TYPE.FNET,
20760
+ FNLT: CONSTRAINT_TYPE.FNLT,
20761
+ MSO: CONSTRAINT_TYPE.MSO,
20762
+ MFO: CONSTRAINT_TYPE.MFO,
20763
+ "AS SOON AS POSSIBLE": CONSTRAINT_TYPE.ASAP,
20764
+ "AS LATE AS POSSIBLE": CONSTRAINT_TYPE.ALAP,
20765
+ "START NO EARLIER THAN": CONSTRAINT_TYPE.SNET,
20766
+ "START NO LATER THAN": CONSTRAINT_TYPE.SNLT,
20767
+ "FINISH NO EARLIER THAN": CONSTRAINT_TYPE.FNET,
20768
+ "FINISH NO LATER THAN": CONSTRAINT_TYPE.FNLT,
20769
+ "MUST START ON": CONSTRAINT_TYPE.MSO,
20770
+ "MUST FINISH ON": CONSTRAINT_TYPE.MFO
20246
20771
  };
20247
20772
 
20248
20773
  // src/boundary/backend/normalize-activity.ts
@@ -20255,13 +20780,19 @@ function normalizeActivities(rawActivities, context) {
20255
20780
  });
20256
20781
  forceRootProjectToRoot(activities);
20257
20782
  const activityIds = new Set(activities.map((activity) => activity.id));
20258
- reparentOrphansToRoot(activities, activityIds, context.reporter);
20783
+ reparentOrphansToRoot(
20784
+ activities,
20785
+ activityIds,
20786
+ context.reporter,
20787
+ context.recordDiagnostic
20788
+ );
20259
20789
  return { activities, activityIds, hiddenIds };
20260
20790
  }
20261
- function parseConstraintLabel(label, reporter) {
20791
+ function parseConstraintLabel(label, reporter, recordDiagnostic, activityId) {
20262
20792
  if (!label) return null;
20263
20793
  const normalized2 = CONSTRAINT_LABEL_MAP[label.toUpperCase()];
20264
20794
  if (normalized2 === void 0) {
20795
+ recordDiagnostic(LOAD_DIAGNOSTIC_CODE.UNKNOWN_CONSTRAINT, activityId);
20265
20796
  reporter.warn(
20266
20797
  `[parseFromBackend] unknown constraint label "${label}" \u2014 defaulting to "asap"`
20267
20798
  );
@@ -20269,9 +20800,14 @@ function parseConstraintLabel(label, reporter) {
20269
20800
  }
20270
20801
  return normalized2;
20271
20802
  }
20272
- function resolveConstraint(raw, reporter) {
20273
- const constraintType = parseConstraintLabel(raw.constraint, reporter);
20274
- const constraintTakesDate = constraintType !== "asap" && constraintType !== "alap";
20803
+ function resolveConstraint(raw, reporter, recordDiagnostic) {
20804
+ const constraintType = parseConstraintLabel(
20805
+ raw.constraint,
20806
+ reporter,
20807
+ recordDiagnostic,
20808
+ String(raw.unique_id)
20809
+ );
20810
+ const constraintTakesDate = constraintType !== CONSTRAINT_TYPE.ASAP && constraintType !== CONSTRAINT_TYPE.ALAP;
20275
20811
  const constraintDate = constraintTakesDate && raw.constraint_date ? parseBackendDate(raw.constraint_date) : null;
20276
20812
  return { constraintType, constraintDate };
20277
20813
  }
@@ -20326,9 +20862,14 @@ function parseCriticality(raw, reporter) {
20326
20862
  );
20327
20863
  return false;
20328
20864
  }
20329
- function parseBaselinePoints(raw, reporter) {
20865
+ function parseBaselinePoints(raw, reporter, recordDiagnostic, activityId) {
20330
20866
  if (!Array.isArray(raw)) return [];
20331
- return raw.map((point) => normalizeBaselinePoint(point, reporter)).filter((point) => point !== null);
20867
+ return raw.map(
20868
+ (point) => normalizeBaselinePoint(point, reporter, {
20869
+ record: recordDiagnostic,
20870
+ sampleId: activityId
20871
+ })
20872
+ ).filter((point) => point !== null);
20332
20873
  }
20333
20874
  function parseActivity(raw, context) {
20334
20875
  const calendarId = resolveCalendarId2(
@@ -20340,9 +20881,10 @@ function parseActivity(raw, context) {
20340
20881
  const progress = Number(raw.progress);
20341
20882
  const { constraintType, constraintDate } = resolveConstraint(
20342
20883
  raw,
20343
- context.reporter
20884
+ context.reporter,
20885
+ context.recordDiagnostic
20344
20886
  );
20345
- const isMilestone = raw.type === "milestone";
20887
+ const isMilestone = raw.type === ACTIVITY_TYPE.MILESTONE;
20346
20888
  const startDate = parseBackendDate(raw.start_date);
20347
20889
  const endDate = isMilestone ? startDate : parseBackendDate(raw.end_date);
20348
20890
  const durationDays = isMilestone ? 0 : Number(raw.duration);
@@ -20383,7 +20925,12 @@ function parseActivity(raw, context) {
20383
20925
  pendingRequestIds: parseIdList(raw.pendingRequests),
20384
20926
  responsableIds: parseIdList(raw.responsables),
20385
20927
  tagIds: parseIdList(raw.tags),
20386
- baselinePoints: parseBaselinePoints(raw.baseline_points, context.reporter),
20928
+ baselinePoints: parseBaselinePoints(
20929
+ raw.baseline_points,
20930
+ context.reporter,
20931
+ context.recordDiagnostic,
20932
+ String(raw.unique_id)
20933
+ ),
20387
20934
  baselineSnapshot: null,
20388
20935
  recursiveDurationHours: durationToHours(
20389
20936
  Number(raw.sumOfDurationRecursively ?? 0),
@@ -20407,17 +20954,18 @@ function normalizeCustomId(raw) {
20407
20954
  }
20408
20955
  function forceRootProjectToRoot(activities) {
20409
20956
  const rootProject = activities.find(
20410
- (activity) => activity.correlativeId === 0 && activity.type === "project"
20957
+ (activity) => activity.correlativeId === 0 && activity.type === ACTIVITY_TYPE.PROJECT
20411
20958
  );
20412
20959
  if (rootProject) rootProject.parentId = null;
20413
20960
  }
20414
- function reparentOrphansToRoot(activities, ids, reporter) {
20961
+ function reparentOrphansToRoot(activities, ids, reporter, recordDiagnostic) {
20415
20962
  for (const activity of activities) {
20416
20963
  if (activity.parentId === null) continue;
20417
20964
  if (!ids.has(activity.parentId)) {
20418
20965
  reporter.warn(
20419
20966
  `[parseFromBackend] activity "${activity.id}" references unknown parent "${activity.parentId}" \u2014 re-parenting to root (null)`
20420
20967
  );
20968
+ recordDiagnostic(LOAD_DIAGNOSTIC_CODE.ORPHAN_ACTIVITY, activity.id);
20421
20969
  activity.parentId = null;
20422
20970
  }
20423
20971
  }
@@ -20641,14 +21189,11 @@ function isMissingValue(value) {
20641
21189
  }
20642
21190
 
20643
21191
  // src/boundary/backend/normalize-link.ts
20644
- function isLinkTypeCode(value) {
20645
- return value === "0" || value === "1" || value === "2" || value === "3";
20646
- }
20647
21192
  function resolveLinkType(rawType) {
20648
21193
  if (typeof rawType !== "string") return null;
20649
21194
  const fromLabel = parseLinkTypeCode(rawType);
20650
21195
  if (fromLabel) return fromLabel;
20651
- if (isLinkTypeCode(rawType)) return rawType;
21196
+ if (isLinkType(rawType)) return rawType;
20652
21197
  return null;
20653
21198
  }
20654
21199
  function normalizePersistedLinkId(rawId) {
@@ -20667,13 +21212,17 @@ function normalizeLinks(rawLinks, context) {
20667
21212
  parseLink(rawLink, context.knownActivityIds, context.hoursPerDay)
20668
21213
  );
20669
21214
  } catch (parseError2) {
21215
+ context.recordDiagnostic(
21216
+ LOAD_DIAGNOSTIC_CODE.INVALID_LINK,
21217
+ String(rawLink.unique_id ?? rawLink.id)
21218
+ );
20670
21219
  context.reporter.warn(
20671
21220
  "[parseFromBackend] dropping invalid link",
20672
21221
  parseError2
20673
21222
  );
20674
21223
  }
20675
21224
  }
20676
- return dedupeLinksBySignature(parsedLinks);
21225
+ return dedupeLinksBySignature(parsedLinks, context.recordDiagnostic);
20677
21226
  }
20678
21227
  function parseLink(link, activityIds, hoursPerDay) {
20679
21228
  const id = String(link.unique_id ?? link.id);
@@ -20711,12 +21260,19 @@ function parseLink(link, activityIds, hoursPerDay) {
20711
21260
  ...proplannerId === void 0 ? {} : { proplannerId }
20712
21261
  };
20713
21262
  }
20714
- function dedupeLinksBySignature(links) {
21263
+ function dedupeLinksBySignature(links, recordDiagnostic) {
20715
21264
  const bySignature = /* @__PURE__ */ new Map();
20716
21265
  for (const link of links) {
20717
21266
  const signature = `${link.source}-${link.target}-${link.type}`;
20718
21267
  const existing = bySignature.get(signature);
20719
- if (!existing || linkIdAsNumber(link) > linkIdAsNumber(existing)) {
21268
+ if (!existing) {
21269
+ bySignature.set(signature, link);
21270
+ continue;
21271
+ }
21272
+ const incomingWins = linkIdAsNumber(link) > linkIdAsNumber(existing);
21273
+ const discarded = incomingWins ? existing : link;
21274
+ recordDiagnostic(LOAD_DIAGNOSTIC_CODE.DUPLICATE_LINK, discarded.id);
21275
+ if (incomingWins) {
20720
21276
  bySignature.set(signature, link);
20721
21277
  }
20722
21278
  }
@@ -20774,7 +21330,7 @@ function parseSector(sector) {
20774
21330
  }
20775
21331
 
20776
21332
  // src/boundary/backend/parse-from-backend.ts
20777
- function parseFromBackend(input, reporter = noopReporter) {
21333
+ function parseFromBackend(input, reporter = noopReporter, recordDiagnostic = noopLoadDiagnosticRecorder) {
20778
21334
  const sector = parseSector(input.sector);
20779
21335
  const { calendars, baseCalendars, knownCalendarIds, defaultCalendarId } = normalizeCalendars(
20780
21336
  input.calendars,
@@ -20788,13 +21344,15 @@ function parseFromBackend(input, reporter = noopReporter) {
20788
21344
  knownCalendarIds,
20789
21345
  defaultCalendarId,
20790
21346
  hoursPerDay: sector.hoursPerDay,
20791
- reporter
21347
+ reporter,
21348
+ recordDiagnostic
20792
21349
  }
20793
21350
  );
20794
21351
  const links = normalizeLinks(input.links, {
20795
21352
  knownActivityIds: activityIds,
20796
21353
  hoursPerDay: sector.hoursPerDay,
20797
- reporter
21354
+ reporter,
21355
+ recordDiagnostic
20798
21356
  });
20799
21357
  return {
20800
21358
  sector,
@@ -21010,6 +21568,11 @@ function maxSuffixFromArray(suffixes) {
21010
21568
  }
21011
21569
 
21012
21570
  // src/generators/custom-id/generation-strategies.ts
21571
+ var GENERATION_STRATEGY = {
21572
+ PARENT_CONVERSION: "parentConversion",
21573
+ PASTE_REFERENCE: "pasteReference",
21574
+ NO_CONTEXT: "noContext"
21575
+ };
21013
21576
  function parentConversionStrategy(defaultPrefix) {
21014
21577
  return { prefix: defaultPrefix, baseSuffix: null };
21015
21578
  }
@@ -21025,12 +21588,12 @@ function noContextStrategy(defaultPrefix) {
21025
21588
  }
21026
21589
  function selectGenerationStrategy(customId, useActivityCustomIdAsReference) {
21027
21590
  if (isParentConversionCase(customId, useActivityCustomIdAsReference)) {
21028
- return "parentConversion";
21591
+ return GENERATION_STRATEGY.PARENT_CONVERSION;
21029
21592
  }
21030
21593
  if (isPasteOrLineReferenceCase(customId, useActivityCustomIdAsReference)) {
21031
- return "pasteReference";
21594
+ return GENERATION_STRATEGY.PASTE_REFERENCE;
21032
21595
  }
21033
- return "noContext";
21596
+ return GENERATION_STRATEGY.NO_CONTEXT;
21034
21597
  }
21035
21598
 
21036
21599
  // src/generators/custom-id/tracker.ts
@@ -21343,15 +21906,15 @@ var CustomIdTracker = class _CustomIdTracker {
21343
21906
  customId
21344
21907
  );
21345
21908
  let capturedNextSuffix = null;
21346
- if (strategyKey === "parentConversion" && this.prefixMap.has(prefix)) {
21909
+ if (strategyKey === GENERATION_STRATEGY.PARENT_CONVERSION && this.prefixMap.has(prefix)) {
21347
21910
  this._ensureFreshBounds(prefix);
21348
21911
  const currentMax = this.prefixMap.get(prefix).max;
21349
21912
  capturedNextSuffix = addToSuffix(currentMax, this.suffixIncrement);
21350
21913
  }
21351
- if (strategyKey === "parentConversion") {
21914
+ if (strategyKey === GENERATION_STRATEGY.PARENT_CONVERSION) {
21352
21915
  this.releaseCustomId(customId);
21353
21916
  }
21354
- const effectiveBaseSuffix = strategyKey === "parentConversion" && capturedNextSuffix ? capturedNextSuffix : baseSuffix;
21917
+ const effectiveBaseSuffix = strategyKey === GENERATION_STRATEGY.PARENT_CONVERSION && capturedNextSuffix ? capturedNextSuffix : baseSuffix;
21355
21918
  const nextSuffix = this.getNextAvailableSuffix(prefix, effectiveBaseSuffix);
21356
21919
  if (nextSuffix === null) {
21357
21920
  const generatedId2 = this._generateDefaultCustomId();
@@ -21367,9 +21930,9 @@ var CustomIdTracker = class _CustomIdTracker {
21367
21930
  }
21368
21931
  _applyGenerationStrategy(strategyKey, customId) {
21369
21932
  switch (strategyKey) {
21370
- case "parentConversion":
21933
+ case GENERATION_STRATEGY.PARENT_CONVERSION:
21371
21934
  return parentConversionStrategy(this.defaultPrefix);
21372
- case "pasteReference":
21935
+ case GENERATION_STRATEGY.PASTE_REFERENCE:
21373
21936
  return pasteReferenceStrategy(customId, this.suffixIncrement);
21374
21937
  default:
21375
21938
  return noContextStrategy(this.defaultPrefix);
@@ -21485,7 +22048,7 @@ function buildComparator(order, context) {
21485
22048
  function demoteChildlessSummaries(state) {
21486
22049
  const idsToDemote = [];
21487
22050
  state.forEachActivity((activity, activityId) => {
21488
- if (activity.type !== "project") return;
22051
+ if (activity.type !== ACTIVITY_TYPE.PROJECT) return;
21489
22052
  if (state.getChildren(String(activityId)).length === 0) {
21490
22053
  idsToDemote.push(String(activityId));
21491
22054
  }
@@ -21603,7 +22166,7 @@ function normalizeLoadedConstraintDates(state) {
21603
22166
  const type = activity.constraintType;
21604
22167
  if (!type || !activity.constraintDate) return;
21605
22168
  const constraintDate = activity.constraintDate;
21606
- if (activity.type === "milestone" && (constraintDate.getUTCHours() !== 0 || constraintDate.getUTCMinutes() !== 0)) {
22169
+ if (activity.type === ACTIVITY_TYPE.MILESTONE && (constraintDate.getUTCHours() !== 0 || constraintDate.getUTCMinutes() !== 0)) {
21607
22170
  return;
21608
22171
  }
21609
22172
  const calendar = state.calendarReader.getCalendar(
@@ -21619,7 +22182,7 @@ function normalizeLoadedConstraintDates(state) {
21619
22182
  }
21620
22183
  function normalizeMilestoneConstraintDatesForDisplay(state) {
21621
22184
  state.forEachActivity((activity) => {
21622
- if (activity.type !== "milestone") return;
22185
+ if (activity.type !== ACTIVITY_TYPE.MILESTONE) return;
21623
22186
  const type = activity.constraintType;
21624
22187
  if (!type || !activity.constraintDate) return;
21625
22188
  const calendar = state.calendarReader.getCalendar(
@@ -21645,6 +22208,7 @@ function initializeCore(input) {
21645
22208
  const initializedAt = clock?.() ?? null;
21646
22209
  const loadNow = initializedAt ? endOfLocalDay(initializedAt) : null;
21647
22210
  const reporter = input.reporter ?? noopReporter;
22211
+ const loadDiagnostics = createLoadDiagnosticsCollector();
21648
22212
  const parsed2 = parseFromBackend(
21649
22213
  {
21650
22214
  sector: input.sector,
@@ -21653,7 +22217,8 @@ function initializeCore(input) {
21653
22217
  calendars: input.calendars,
21654
22218
  baseCalendars: input.baseCalendars
21655
22219
  },
21656
- reporter
22220
+ reporter,
22221
+ loadDiagnostics.record
21657
22222
  );
21658
22223
  const sector = parsed2.sector;
21659
22224
  sector.statusCriteria = resolveStatusCriteria(input.statusCriteria);
@@ -21693,7 +22258,8 @@ function initializeCore(input) {
21693
22258
  input.baselinePoints,
21694
22259
  loadNow,
21695
22260
  reporter,
21696
- defaultBaseCalendarId
22261
+ defaultBaseCalendarId,
22262
+ loadDiagnostics.record
21697
22263
  );
21698
22264
  }
21699
22265
  const initPromise = runInitialPasses({
@@ -21715,6 +22281,7 @@ function initializeCore(input) {
21715
22281
  baseCalendars,
21716
22282
  clock,
21717
22283
  reporter,
22284
+ loadDiagnostics: loadDiagnostics.snapshot,
21718
22285
  initPromise
21719
22286
  };
21720
22287
  }
@@ -21776,18 +22343,22 @@ function entityChanges(target, source) {
21776
22343
  const before = sourceById.get(id);
21777
22344
  const after = targetById.get(id);
21778
22345
  if (after === void 0) {
21779
- changes.push({ id, kind: "deleted", after: null });
22346
+ changes.push({ id, kind: ENTITY_CHANGE_KIND.DELETED, after: null });
21780
22347
  continue;
21781
22348
  }
21782
22349
  if (before === void 0) {
21783
- changes.push({ id, kind: "created", after: cloneDomainValue(after) });
22350
+ changes.push({
22351
+ id,
22352
+ kind: ENTITY_CHANGE_KIND.CREATED,
22353
+ after: cloneDomainValue(after)
22354
+ });
21784
22355
  continue;
21785
22356
  }
21786
22357
  const fields = changedFields(before, after);
21787
22358
  if (Object.keys(fields).length > 0) {
21788
22359
  changes.push({
21789
22360
  id,
21790
- kind: "updated",
22361
+ kind: ENTITY_CHANGE_KIND.UPDATED,
21791
22362
  fields,
21792
22363
  after: cloneDomainValue(after)
21793
22364
  });
@@ -22002,8 +22573,8 @@ function acknowledgesPersistence(action) {
22002
22573
  }
22003
22574
  function changesRequireFilterProjectionRebuild(changes) {
22004
22575
  for (const change of changes.activities) {
22005
- if (change.kind === "deleted") return true;
22006
- const hasMovedParent = change.kind === "updated" && change.fields !== void 0 && "parentId" in change.fields;
22576
+ if (change.kind === ENTITY_CHANGE_KIND.DELETED) return true;
22577
+ const hasMovedParent = change.kind === ENTITY_CHANGE_KIND.UPDATED && change.fields !== void 0 && "parentId" in change.fields;
22007
22578
  if (hasMovedParent) return true;
22008
22579
  }
22009
22580
  return false;
@@ -22055,6 +22626,7 @@ var ScheduleCore = class _ScheduleCore {
22055
22626
  _undo = new UndoRecorder();
22056
22627
  _opQueue = Promise.resolve();
22057
22628
  _scheduleRevision = 0;
22629
+ _stateRevision = 0;
22058
22630
  _pendingScheduleRevision = 0;
22059
22631
  _criticalPathRevision = -1;
22060
22632
  _activeCriticalPath = null;
@@ -22080,7 +22652,8 @@ var ScheduleCore = class _ScheduleCore {
22080
22652
  ),
22081
22653
  baseCalendars: cloneDomainValue(source.coreRuntime.baseCalendars),
22082
22654
  clock: source.coreRuntime.clock,
22083
- reporter: source.coreRuntime.reporter
22655
+ reporter: source.coreRuntime.reporter,
22656
+ loadDiagnostics: source.coreRuntime.loadDiagnostics
22084
22657
  };
22085
22658
  this._activityClipboard.value = cloneDomainValue(
22086
22659
  source._activityClipboard.value
@@ -22088,6 +22661,7 @@ var ScheduleCore = class _ScheduleCore {
22088
22661
  this._undo = source._undo.fork();
22089
22662
  this._saveTracker = source._saveTracker.fork();
22090
22663
  this._scheduleRevision = source._scheduleRevision;
22664
+ this._stateRevision = source._stateRevision;
22091
22665
  this._pendingScheduleRevision = source._scheduleRevision;
22092
22666
  this._criticalPathRevision = source._criticalPathRevision;
22093
22667
  this._initPromise = Promise.resolve();
@@ -22110,7 +22684,8 @@ var ScheduleCore = class _ScheduleCore {
22110
22684
  initialized.calendars.map((calendar) => [calendar.id, calendar])
22111
22685
  ),
22112
22686
  baseCalendars: initialized.baseCalendars,
22113
- reporter: initialized.reporter
22687
+ reporter: initialized.reporter,
22688
+ loadDiagnostics: initialized.loadDiagnostics
22114
22689
  };
22115
22690
  this._initPromise = initialized.initPromise.then(() => {
22116
22691
  if (this._status === SCHEDULE_CORE_STATUS.DESTROYED) return;
@@ -22175,6 +22750,11 @@ var ScheduleCore = class _ScheduleCore {
22175
22750
  getSector() {
22176
22751
  return cloneDomainValue(this.coreRuntime.sector);
22177
22752
  }
22753
+ /** Returns immutable data-quality diagnostics collected during loading. */
22754
+ getLoadDiagnostics() {
22755
+ this.assertReady();
22756
+ return this.coreRuntime.loadDiagnostics();
22757
+ }
22178
22758
  /**
22179
22759
  * Reads a defensive activity snapshot from a ready schedule.
22180
22760
  *
@@ -22444,6 +23024,10 @@ var ScheduleCore = class _ScheduleCore {
22444
23024
  getScheduleRevision() {
22445
23025
  return this._scheduleRevision;
22446
23026
  }
23027
+ /** @returns The monotonic canonical-state revision without a readiness guard. */
23028
+ getStateRevision() {
23029
+ return this._stateRevision;
23030
+ }
22447
23031
  /** @returns The undo-history boundary for an external save checkpoint. */
22448
23032
  capturePersistenceHistoryBoundary() {
22449
23033
  this.assertReady();
@@ -22553,6 +23137,21 @@ var ScheduleCore = class _ScheduleCore {
22553
23137
  const admitted = this._beginScheduleMutation(action);
22554
23138
  return this._enqueue(() => this._dispatchInner(action, options, admitted));
22555
23139
  }
23140
+ /** Builds the defensive canonical conversion intent without mutating state. */
23141
+ planLookaheadConversion(input) {
23142
+ this.assertReady();
23143
+ return buildLookaheadConversionPlan(input, {
23144
+ adapter: this.coreRuntime.state,
23145
+ stateRevision: this._stateRevision
23146
+ });
23147
+ }
23148
+ /** Applies one revision-guarded conversion through the serialized dispatcher. */
23149
+ applyLookaheadConversion(input) {
23150
+ return this.dispatch({
23151
+ ...input,
23152
+ kind: DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_CONVERT
23153
+ });
23154
+ }
22556
23155
  async _dispatchInner(action, options = {}, admitted = false) {
22557
23156
  let changedState = false;
22558
23157
  try {
@@ -22603,6 +23202,7 @@ var ScheduleCore = class _ScheduleCore {
22603
23202
  customIdTracker: this.coreRuntime.customIdTracker,
22604
23203
  reporter: this.coreRuntime.reporter,
22605
23204
  activityClipboard: this._activityClipboard,
23205
+ stateRevision: this._stateRevision,
22606
23206
  defaultBaseCalendarId: this.coreRuntime.baseCalendars.find(
22607
23207
  (calendar) => calendar.baseDefault
22608
23208
  )?.id ?? null,
@@ -22620,7 +23220,7 @@ var ScheduleCore = class _ScheduleCore {
22620
23220
  this.coreRuntime.state.endWriteCapture();
22621
23221
  this.coreRuntime.customIdTracker.commitCustomIdTransaction();
22622
23222
  }
22623
- if (result.ok && historyPolicy === "record" && changeSetIsSubstantive(result.changes)) {
23223
+ if (result.ok && historyPolicy === DISPATCH_HISTORY_POLICY.RECORD && changeSetIsSubstantive(result.changes)) {
22624
23224
  const created = captureCreatedSnapshots(
22625
23225
  this.coreRuntime.state,
22626
23226
  result.changes
@@ -22646,7 +23246,7 @@ var ScheduleCore = class _ScheduleCore {
22646
23246
  );
22647
23247
  }
22648
23248
  if (result.ok) {
22649
- if (historyPolicy === "checkpoint-on-success") {
23249
+ if (historyPolicy === DISPATCH_HISTORY_POLICY.CHECKPOINT_ON_SUCCESS) {
22650
23250
  if (action.kind !== DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
22651
23251
  throw new Error(
22652
23252
  "checkpoint-on-success requires persistence acknowledge"
@@ -22688,7 +23288,9 @@ var ScheduleCore = class _ScheduleCore {
22688
23288
  }
22689
23289
  result = this._withReappliedViewState(action, result);
22690
23290
  if (!result.ok) return { result, changedState: false };
22691
- if (dispatchChangesSchedulingState(action) && changeSetIsSubstantive(result.changes)) {
23291
+ const hasSubstantiveChanges = changeSetIsSubstantive(result.changes);
23292
+ if (hasSubstantiveChanges) this._stateRevision++;
23293
+ if (dispatchChangesSchedulingState(action) && hasSubstantiveChanges) {
22692
23294
  this._recordScheduleMutation(
22693
23295
  options.skipAutoSchedule !== true && options.skipCriticalPath !== true && resolveRunCriticalPath(action)
22694
23296
  );
@@ -22763,7 +23365,7 @@ var ScheduleCore = class _ScheduleCore {
22763
23365
  }
22764
23366
  const affectedParents = new Set(resequencedParents);
22765
23367
  for (const change of changes.activities) {
22766
- if (change.kind === "deleted") {
23368
+ if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
22767
23369
  return { ...changes, order: collectBranchOrder(adapter) };
22768
23370
  }
22769
23371
  const parentId = adapter.getParentId(change.id);
@@ -22957,7 +23559,7 @@ var ScheduleCore = class _ScheduleCore {
22957
23559
  const changes = buildInverseChangeSet(
22958
23560
  this.coreRuntime.state,
22959
23561
  entry,
22960
- "before"
23562
+ CHANGE_SET_SIDE.BEFORE
22961
23563
  );
22962
23564
  this._saveTracker.recordChanges(
22963
23565
  changes.activities,
@@ -23014,7 +23616,7 @@ var ScheduleCore = class _ScheduleCore {
23014
23616
  const changes = buildInverseChangeSet(
23015
23617
  this.coreRuntime.state,
23016
23618
  entry,
23017
- "after"
23619
+ CHANGE_SET_SIDE.AFTER
23018
23620
  );
23019
23621
  this._saveTracker.recordChanges(
23020
23622
  changes.activities,
@@ -23075,6 +23677,7 @@ var ScheduleCore = class _ScheduleCore {
23075
23677
  _rollback(generatorSnapshot) {
23076
23678
  try {
23077
23679
  this.coreRuntime.state.restoreFromCapture();
23680
+ this.coreRuntime.scheduler.invalidateAllCaches();
23078
23681
  this.coreRuntime.customIdTracker.rollbackCustomIdTransaction();
23079
23682
  if (generatorSnapshot) {
23080
23683
  this.coreRuntime.activityIdGenerator.restore(generatorSnapshot[0]);
@@ -23140,6 +23743,7 @@ exports.ACTIVITY_BATCH_MODE = ACTIVITY_BATCH_MODE;
23140
23743
  exports.ACTIVITY_DATE_EDGE = ACTIVITY_DATE_EDGE;
23141
23744
  exports.ACTIVITY_FIELD = ACTIVITY_FIELD;
23142
23745
  exports.ACTIVITY_PONDERATOR_CRITERION = ACTIVITY_PONDERATOR_CRITERION;
23746
+ exports.ACTIVITY_PROGRESS_ORIGIN = ACTIVITY_PROGRESS_ORIGIN;
23143
23747
  exports.ACTIVITY_TYPE = ACTIVITY_TYPE;
23144
23748
  exports.CALENDAR_UNIT = CALENDAR_UNIT;
23145
23749
  exports.CHANGE_SET_SOURCE_KIND = CHANGE_SET_SOURCE_KIND;
@@ -23155,12 +23759,14 @@ exports.DISPATCH_ACTION_KIND = DISPATCH_ACTION_KIND;
23155
23759
  exports.DISPATCH_ACTION_KINDS = DISPATCH_ACTION_KINDS;
23156
23760
  exports.DISPATCH_LINK_OPERATION_KIND = DISPATCH_LINK_OPERATION_KIND;
23157
23761
  exports.DISPATCH_TRACK_EVENT = DISPATCH_TRACK_EVENT;
23762
+ exports.ENTITY_CHANGE_KIND = ENTITY_CHANGE_KIND;
23158
23763
  exports.FILTER_FIELD = FILTER_FIELD;
23159
23764
  exports.FILTER_LOGIC = FILTER_LOGIC;
23160
23765
  exports.FILTER_OPERATOR = FILTER_OPERATOR;
23161
23766
  exports.FILTER_REJECTION_REASON = FILTER_REJECTION_REASON;
23162
23767
  exports.FILTER_VALUE_KIND = FILTER_VALUE_KIND;
23163
23768
  exports.LINK_BATCH_OPERATION_KIND = LINK_BATCH_OPERATION_KIND;
23769
+ exports.LINK_CODE = LINK_CODE;
23164
23770
  exports.LINK_CODE_TO_TYPE = LINK_CODE_TO_TYPE;
23165
23771
  exports.LINK_REJECTION_REASON = LINK_REJECTION_REASON;
23166
23772
  exports.LINK_RELATIONSHIP = LINK_RELATIONSHIP;