dabke 0.81.1 → 0.83.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/CHANGELOG.md +58 -0
- package/README.md +45 -27
- package/dist/client.d.ts +20 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -1
- package/dist/client.js.map +1 -1
- package/dist/client.types.d.ts +9 -0
- package/dist/client.types.d.ts.map +1 -1
- package/dist/client.types.js +1 -0
- package/dist/client.types.js.map +1 -1
- package/dist/cpsat/model-builder.d.ts +9 -0
- package/dist/cpsat/model-builder.d.ts.map +1 -1
- package/dist/cpsat/model-builder.js +36 -34
- package/dist/cpsat/model-builder.js.map +1 -1
- package/dist/cpsat/response.d.ts +13 -1
- package/dist/cpsat/response.d.ts.map +1 -1
- package/dist/cpsat/response.js +4 -0
- package/dist/cpsat/response.js.map +1 -1
- package/dist/cpsat/rules/cost-utils.d.ts +11 -0
- package/dist/cpsat/rules/cost-utils.d.ts.map +1 -0
- package/dist/cpsat/rules/cost-utils.js +24 -0
- package/dist/cpsat/rules/cost-utils.js.map +1 -0
- package/dist/cpsat/rules/day-cost-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/day-cost-multiplier.js +3 -14
- package/dist/cpsat/rules/day-cost-multiplier.js.map +1 -1
- package/dist/cpsat/rules/day-cost-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/day-cost-surcharge.js +3 -7
- package/dist/cpsat/rules/day-cost-surcharge.js.map +1 -1
- package/dist/cpsat/rules/index.d.ts +3 -0
- package/dist/cpsat/rules/index.d.ts.map +1 -1
- package/dist/cpsat/rules/index.js +3 -0
- package/dist/cpsat/rules/index.js.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.js +16 -2
- package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/max-days-week.d.ts +44 -0
- package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/max-days-week.js +95 -0
- package/dist/cpsat/rules/max-days-week.js.map +1 -0
- package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-day.js +15 -2
- package/dist/cpsat/rules/max-hours-day.js.map +1 -1
- package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-week.js +16 -2
- package/dist/cpsat/rules/max-hours-week.js.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.js +15 -2
- package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.js +15 -2
- package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/min-days-week.d.ts +34 -0
- package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/min-days-week.js +84 -0
- package/dist/cpsat/rules/min-days-week.js.map +1 -0
- package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-day.js +15 -2
- package/dist/cpsat/rules/min-hours-day.js.map +1 -1
- package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-week.js +16 -2
- package/dist/cpsat/rules/min-hours-week.js.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.js +72 -2
- package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
- package/dist/cpsat/rules/minimize-cost.d.ts.map +1 -1
- package/dist/cpsat/rules/minimize-cost.js +2 -23
- package/dist/cpsat/rules/minimize-cost.js.map +1 -1
- package/dist/cpsat/rules/must-assign.d.ts +49 -0
- package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
- package/dist/cpsat/rules/must-assign.js +86 -0
- package/dist/cpsat/rules/must-assign.js.map +1 -0
- package/dist/cpsat/rules/overtime-daily-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-daily-multiplier.js +1 -12
- package/dist/cpsat/rules/overtime-daily-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-daily-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-daily-surcharge.js +1 -5
- package/dist/cpsat/rules/overtime-daily-surcharge.js.map +1 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts +5 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.js +1 -12
- package/dist/cpsat/rules/overtime-tiered-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-multiplier.js +1 -12
- package/dist/cpsat/rules/overtime-weekly-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-surcharge.js +1 -5
- package/dist/cpsat/rules/overtime-weekly-surcharge.js.map +1 -1
- package/dist/cpsat/rules/registry.d.ts +28 -2
- package/dist/cpsat/rules/registry.d.ts.map +1 -1
- package/dist/cpsat/rules/registry.js +4 -1
- package/dist/cpsat/rules/registry.js.map +1 -1
- package/dist/cpsat/rules/resolver.js +2 -2
- package/dist/cpsat/rules/resolver.js.map +1 -1
- package/dist/cpsat/rules/rules.types.d.ts +3 -0
- package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +18 -1
- package/dist/cpsat/rules/scope.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.js +59 -16
- package/dist/cpsat/rules/scope.types.js.map +1 -1
- package/dist/cpsat/rules/time-cost-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/time-cost-surcharge.js +2 -1
- package/dist/cpsat/rules/time-cost-surcharge.js.map +1 -1
- package/dist/cpsat/rules/time-off.d.ts.map +1 -1
- package/dist/cpsat/rules/time-off.js +6 -3
- package/dist/cpsat/rules/time-off.js.map +1 -1
- package/dist/cpsat/semantic-time.d.ts +44 -42
- package/dist/cpsat/semantic-time.d.ts.map +1 -1
- package/dist/cpsat/semantic-time.js +64 -46
- package/dist/cpsat/semantic-time.js.map +1 -1
- package/dist/cpsat/types.d.ts +37 -27
- package/dist/cpsat/types.d.ts.map +1 -1
- package/dist/cpsat/utils.d.ts.map +1 -1
- package/dist/cpsat/utils.js +7 -12
- package/dist/cpsat/utils.js.map +1 -1
- package/dist/cpsat/validation-reporter.d.ts +10 -7
- package/dist/cpsat/validation-reporter.d.ts.map +1 -1
- package/dist/cpsat/validation-reporter.js +44 -72
- package/dist/cpsat/validation-reporter.js.map +1 -1
- package/dist/cpsat/validation.types.d.ts +54 -44
- package/dist/cpsat/validation.types.d.ts.map +1 -1
- package/dist/cpsat/validation.types.js +15 -10
- package/dist/cpsat/validation.types.js.map +1 -1
- package/dist/datetime.utils.d.ts +3 -203
- package/dist/datetime.utils.d.ts.map +1 -1
- package/dist/datetime.utils.js +1 -288
- package/dist/datetime.utils.js.map +1 -1
- package/dist/index.d.ts +14 -83
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -83
- package/dist/index.js.map +1 -1
- package/dist/schedule/cost.d.ts +204 -0
- package/dist/schedule/cost.d.ts.map +1 -0
- package/dist/schedule/cost.js +187 -0
- package/dist/schedule/cost.js.map +1 -0
- package/dist/schedule/coverage.d.ts +85 -0
- package/dist/schedule/coverage.d.ts.map +1 -0
- package/dist/schedule/coverage.js +33 -0
- package/dist/schedule/coverage.js.map +1 -0
- package/dist/schedule/definition.d.ts +227 -0
- package/dist/schedule/definition.d.ts.map +1 -0
- package/dist/schedule/definition.js +659 -0
- package/dist/schedule/definition.js.map +1 -0
- package/dist/schedule/index.d.ts +67 -0
- package/dist/schedule/index.d.ts.map +1 -0
- package/dist/schedule/index.js +69 -0
- package/dist/schedule/index.js.map +1 -0
- package/dist/schedule/rules.d.ts +353 -0
- package/dist/schedule/rules.d.ts.map +1 -0
- package/dist/schedule/rules.js +352 -0
- package/dist/schedule/rules.js.map +1 -0
- package/dist/schedule/shift-patterns.d.ts +34 -0
- package/dist/schedule/shift-patterns.d.ts.map +1 -0
- package/dist/schedule/shift-patterns.js +41 -0
- package/dist/schedule/shift-patterns.js.map +1 -0
- package/dist/schedule/time-periods.d.ts +69 -0
- package/dist/schedule/time-periods.d.ts.map +1 -0
- package/dist/schedule/time-periods.js +91 -0
- package/dist/schedule/time-periods.js.map +1 -0
- package/dist/types.d.ts +14 -78
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -9
- package/solver/src/solver/app.py +1 -1
- package/solver/src/solver/solver.py +7 -4
- package/src/client.ts +6 -8
- package/src/client.types.ts +9 -0
- package/src/cpsat/model-builder.ts +44 -35
- package/src/cpsat/response.ts +13 -1
- package/src/cpsat/rules/cost-utils.ts +25 -0
- package/src/cpsat/rules/day-cost-multiplier.ts +3 -14
- package/src/cpsat/rules/day-cost-surcharge.ts +3 -8
- package/src/cpsat/rules/index.ts +3 -0
- package/src/cpsat/rules/max-consecutive-days.ts +17 -0
- package/src/cpsat/rules/max-days-week.ts +143 -0
- package/src/cpsat/rules/max-hours-day.ts +21 -1
- package/src/cpsat/rules/max-hours-week.ts +22 -1
- package/src/cpsat/rules/max-shifts-day.ts +21 -1
- package/src/cpsat/rules/min-consecutive-days.ts +16 -1
- package/src/cpsat/rules/min-days-week.ts +120 -0
- package/src/cpsat/rules/min-hours-day.ts +16 -1
- package/src/cpsat/rules/min-hours-week.ts +17 -1
- package/src/cpsat/rules/min-rest-between-shifts.ts +92 -2
- package/src/cpsat/rules/minimize-cost.ts +2 -29
- package/src/cpsat/rules/must-assign.ts +108 -0
- package/src/cpsat/rules/overtime-daily-multiplier.ts +1 -12
- package/src/cpsat/rules/overtime-daily-surcharge.ts +1 -6
- package/src/cpsat/rules/overtime-tiered-multiplier.ts +6 -13
- package/src/cpsat/rules/overtime-weekly-multiplier.ts +1 -12
- package/src/cpsat/rules/overtime-weekly-surcharge.ts +1 -6
- package/src/cpsat/rules/registry.ts +8 -2
- package/src/cpsat/rules/resolver.ts +2 -2
- package/src/cpsat/rules/rules.types.ts +3 -0
- package/src/cpsat/rules/scope.types.ts +73 -20
- package/src/cpsat/rules/time-cost-surcharge.ts +2 -1
- package/src/cpsat/rules/time-off.ts +6 -2
- package/src/cpsat/semantic-time.ts +115 -91
- package/src/cpsat/types.ts +37 -27
- package/src/cpsat/utils.ts +8 -12
- package/src/cpsat/validation-reporter.ts +51 -82
- package/src/cpsat/validation.types.ts +72 -47
- package/src/datetime.utils.ts +3 -334
- package/src/index.ts +35 -107
- package/src/schedule/cost.ts +242 -0
- package/src/schedule/coverage.ts +135 -0
- package/src/schedule/definition.ts +958 -0
- package/src/schedule/index.ts +112 -0
- package/src/schedule/rules.ts +529 -0
- package/src/schedule/shift-patterns.ts +46 -0
- package/src/schedule/time-periods.ts +110 -0
- package/src/types.ts +14 -88
- package/dist/errors.d.ts +0 -12
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -17
- package/dist/errors.js.map +0 -1
- package/dist/llms.d.ts +0 -2
- package/dist/llms.d.ts.map +0 -1
- package/dist/llms.js +0 -3
- package/dist/llms.js.map +0 -1
- package/dist/schedule.d.ts +0 -724
- package/dist/schedule.d.ts.map +0 -1
- package/dist/schedule.js +0 -899
- package/dist/schedule.js.map +0 -1
- package/dist/validation.d.ts +0 -105
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -130
- package/dist/validation.js.map +0 -1
- package/llms.txt +0 -925
- package/src/errors.ts +0 -17
- package/src/llms.ts +0 -3
- package/src/schedule.ts +0 -1419
- package/src/validation.ts +0 -188
package/dist/cpsat/types.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { TimeOfDay, DayOfWeek } from "../types.js";
|
|
2
2
|
import type { SolverRequest, SolverTerm } from "../client.types.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { ValidationGroup } from "./validation.types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Pay per hour in the caller's smallest currency unit (e.g., pence, cents).
|
|
6
|
+
*
|
|
7
|
+
* @category Supporting Types
|
|
6
8
|
*/
|
|
7
9
|
export interface HourlyPay {
|
|
8
10
|
/** Pay per hour in smallest currency unit. */
|
|
@@ -17,6 +19,8 @@ export interface HourlyPay {
|
|
|
17
19
|
*
|
|
18
20
|
* Note: overtime multiplier rules apply only to hourly members.
|
|
19
21
|
* Overtime surcharge rules apply to all members regardless of pay type.
|
|
22
|
+
*
|
|
23
|
+
* @category Supporting Types
|
|
20
24
|
*/
|
|
21
25
|
export interface SalariedPay {
|
|
22
26
|
/** Annual salary in smallest currency unit. */
|
|
@@ -29,6 +33,8 @@ export interface SalariedPay {
|
|
|
29
33
|
*
|
|
30
34
|
* - `"LOW"`, `"MEDIUM"`, `"HIGH"`: soft constraints with increasing penalty for violations
|
|
31
35
|
* - `"MANDATORY"`: hard constraint; the solver will not produce a solution that violates it
|
|
36
|
+
*
|
|
37
|
+
* @category Supporting Types
|
|
32
38
|
*/
|
|
33
39
|
export type Priority = "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
34
40
|
/**
|
|
@@ -36,14 +42,16 @@ export type Priority = "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
|
36
42
|
*
|
|
37
43
|
* Members are assigned to shift patterns by the solver based on
|
|
38
44
|
* coverage requirements, rules, and constraints.
|
|
45
|
+
*
|
|
46
|
+
* @category Supporting Types
|
|
39
47
|
*/
|
|
40
48
|
export interface SchedulingMember {
|
|
41
49
|
/** Unique identifier for this member. Must not contain colons. */
|
|
42
50
|
id: string;
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
|
|
51
|
+
/** Role IDs this member can fill (e.g. "nurse", "doctor"). */
|
|
52
|
+
roleIds: string[];
|
|
53
|
+
/** Skill IDs this member has (e.g. "charge_nurse", "forklift"). */
|
|
54
|
+
skillIds?: string[];
|
|
47
55
|
/** Base pay. Required when cost rules are used. */
|
|
48
56
|
pay?: HourlyPay | SalariedPay;
|
|
49
57
|
}
|
|
@@ -62,9 +70,11 @@ export interface SchedulingMember {
|
|
|
62
70
|
* @example
|
|
63
71
|
* // Role-restricted shifts
|
|
64
72
|
* const patterns: ShiftPattern[] = [
|
|
65
|
-
* { id: "ward_day", startTime: { hours: 7 }, endTime: { hours: 15 },
|
|
66
|
-
* { id: "reception", startTime: { hours: 8 }, endTime: { hours: 16 },
|
|
73
|
+
* { id: "ward_day", startTime: { hours: 7 }, endTime: { hours: 15 }, roleIds: ["nurse", "doctor"] },
|
|
74
|
+
* { id: "reception", startTime: { hours: 8 }, endTime: { hours: 16 }, roleIds: ["admin"] },
|
|
67
75
|
* ];
|
|
76
|
+
*
|
|
77
|
+
* @category Supporting Types
|
|
68
78
|
*/
|
|
69
79
|
export interface ShiftPattern {
|
|
70
80
|
/**
|
|
@@ -73,7 +83,7 @@ export interface ShiftPattern {
|
|
|
73
83
|
*/
|
|
74
84
|
id: string;
|
|
75
85
|
/**
|
|
76
|
-
* Restricts who can be assigned to this shift based on their
|
|
86
|
+
* Restricts who can be assigned to this shift based on their role IDs.
|
|
77
87
|
*
|
|
78
88
|
* - If omitted: anyone can work this shift
|
|
79
89
|
* - If provided: only team members whose roles overlap with this list can be assigned
|
|
@@ -82,7 +92,7 @@ export interface ShiftPattern {
|
|
|
82
92
|
* Use it when different roles have different schedules (e.g., kitchen staff starts
|
|
83
93
|
* earlier than floor staff).
|
|
84
94
|
*/
|
|
85
|
-
|
|
95
|
+
roleIds?: [string, ...string[]];
|
|
86
96
|
/**
|
|
87
97
|
* Restricts which days of the week this shift pattern can be used.
|
|
88
98
|
*
|
|
@@ -98,7 +108,7 @@ export interface ShiftPattern {
|
|
|
98
108
|
* { id: "full_shift", startTime: t(9), endTime: t(18), dayOfWeek: ["monday", "tuesday", "wednesday", "thursday", "friday"] }
|
|
99
109
|
* ```
|
|
100
110
|
*/
|
|
101
|
-
dayOfWeek?: DayOfWeek[];
|
|
111
|
+
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
102
112
|
/**
|
|
103
113
|
* Physical location where this shift takes place.
|
|
104
114
|
* Used for multi-location scheduling and location-based constraints.
|
|
@@ -121,13 +131,13 @@ interface CoverageRequirementBase extends TimeInterval {
|
|
|
121
131
|
targetCount: number;
|
|
122
132
|
priority: Priority;
|
|
123
133
|
/**
|
|
124
|
-
* Groups this requirement with others
|
|
125
|
-
*
|
|
126
|
-
*
|
|
134
|
+
* Groups this requirement with others for validation reporting.
|
|
135
|
+
* All coverage constraints generated from this requirement will share the
|
|
136
|
+
* same group, enabling meaningful aggregation in reports.
|
|
127
137
|
*
|
|
128
|
-
* If not provided, an auto-generated
|
|
138
|
+
* If not provided, an auto-generated group will be used based on the coverage parameters.
|
|
129
139
|
*/
|
|
130
|
-
|
|
140
|
+
group?: ValidationGroup;
|
|
131
141
|
}
|
|
132
142
|
/**
|
|
133
143
|
* Coverage requiring specific roles, optionally filtered by skills.
|
|
@@ -136,16 +146,16 @@ interface CoverageRequirementBase extends TimeInterval {
|
|
|
136
146
|
*/
|
|
137
147
|
interface RoleBasedCoverageRequirement extends CoverageRequirementBase {
|
|
138
148
|
/**
|
|
139
|
-
*
|
|
149
|
+
* Role IDs that satisfy this coverage (OR logic).
|
|
140
150
|
* A person matches if they have ANY of these roles.
|
|
141
151
|
* Must have at least one role.
|
|
142
152
|
*/
|
|
143
|
-
|
|
153
|
+
roleIds: [string, ...string[]];
|
|
144
154
|
/**
|
|
145
|
-
* Additional skill filter (AND logic with roles).
|
|
155
|
+
* Additional skill ID filter (AND logic with roles).
|
|
146
156
|
* If provided, team members must have ALL specified skills in addition to matching a role.
|
|
147
157
|
*/
|
|
148
|
-
|
|
158
|
+
skillIds?: [string, ...string[]];
|
|
149
159
|
}
|
|
150
160
|
/**
|
|
151
161
|
* Coverage requiring specific skills only (any role).
|
|
@@ -155,18 +165,18 @@ interface SkillBasedCoverageRequirement extends CoverageRequirementBase {
|
|
|
155
165
|
/**
|
|
156
166
|
* Must not be present for skill-based coverage.
|
|
157
167
|
*/
|
|
158
|
-
|
|
168
|
+
roleIds?: never;
|
|
159
169
|
/**
|
|
160
|
-
*
|
|
170
|
+
* Skill IDs required to satisfy this coverage (ALL required, AND logic).
|
|
161
171
|
* Must have at least one skill.
|
|
162
172
|
*/
|
|
163
|
-
|
|
173
|
+
skillIds: [string, ...string[]];
|
|
164
174
|
}
|
|
165
175
|
/**
|
|
166
176
|
* Defines staffing needs for a specific time period.
|
|
167
177
|
*
|
|
168
178
|
* This is a discriminated union that enforces at compile time that at least
|
|
169
|
-
* one of `
|
|
179
|
+
* one of `roleIds` or `skillIds` must be provided:
|
|
170
180
|
*
|
|
171
181
|
* - Role-based: `{ roles: ["waiter"], ... }` - anyone with ANY of these roles (OR logic)
|
|
172
182
|
* - Role + skill: `{ roles: ["waiter"], skills: ["senior"], ... }` - role AND skills
|
|
@@ -174,19 +184,19 @@ interface SkillBasedCoverageRequirement extends CoverageRequirementBase {
|
|
|
174
184
|
*
|
|
175
185
|
* @example
|
|
176
186
|
* // Need 2 waiters during lunch (role-based)
|
|
177
|
-
* { day: "2024-01-01", startTime: { hours: 11 }, endTime: { hours: 14 },
|
|
187
|
+
* { day: "2024-01-01", startTime: { hours: 11 }, endTime: { hours: 14 }, roleIds: ["waiter"], targetCount: 2, priority: "MANDATORY" }
|
|
178
188
|
*
|
|
179
189
|
* @example
|
|
180
190
|
* // Need 1 manager OR supervisor during service (OR logic on roles)
|
|
181
|
-
* { day: "2024-01-01", startTime: { hours: 11 }, endTime: { hours: 22 },
|
|
191
|
+
* { day: "2024-01-01", startTime: { hours: 11 }, endTime: { hours: 22 }, roleIds: ["manager", "supervisor"], targetCount: 1, priority: "MANDATORY" }
|
|
182
192
|
*
|
|
183
193
|
* @example
|
|
184
194
|
* // Need 1 keyholder for opening (skill-only, any role)
|
|
185
|
-
* { day: "2024-01-01", startTime: { hours: 6 }, endTime: { hours: 8 },
|
|
195
|
+
* { day: "2024-01-01", startTime: { hours: 6 }, endTime: { hours: 8 }, skillIds: ["keyholder"], targetCount: 1, priority: "MANDATORY" }
|
|
186
196
|
*
|
|
187
197
|
* @example
|
|
188
198
|
* // Need 1 senior waiter for training shift (role + skill filter)
|
|
189
|
-
* { day: "2024-01-01", startTime: { hours: 9 }, endTime: { hours: 17 },
|
|
199
|
+
* { day: "2024-01-01", startTime: { hours: 9 }, endTime: { hours: 17 }, roleIds: ["waiter"], skillIds: ["senior"], targetCount: 1, priority: "HIGH" }
|
|
190
200
|
*/
|
|
191
201
|
export type CoverageRequirement = RoleBasedCoverageRequirement | SkillBasedCoverageRequirement;
|
|
192
202
|
/** Optional settings for the model builder. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cpsat/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cpsat/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/cpsat/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,eAAe,QAAU,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,iBAAiB;IAC5B,0EAA0E;;IAE1E,6DAA6D;;IAE7D,sFAAsF;;IAEtF,+EAA+E;;IAE/E,8CAA8C;;CAEtC,CAAC;AAEX;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGpF;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/cpsat/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,eAAe,QAAU,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,iBAAiB;IAC5B,0EAA0E;;IAE1E,6DAA6D;;IAE7D,sFAAsF;;IAEtF,+EAA+E;;IAE/E,8CAA8C;;CAEtC,CAAC;AAEX;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGpF;AASD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE5D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAa1F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,SAAS,GAAG,MAAM,EAAE,EAAE,CA+BlF"}
|
package/dist/cpsat/utils.js
CHANGED
|
@@ -52,19 +52,14 @@ export function normalizeEndMinutes(startMinutes, endMinutes) {
|
|
|
52
52
|
return endMinutes + MINUTES_PER_DAY;
|
|
53
53
|
return endMinutes < startMinutes ? endMinutes + MINUTES_PER_DAY : endMinutes;
|
|
54
54
|
}
|
|
55
|
+
const PRIORITY_PENALTIES = {
|
|
56
|
+
LOW: 1,
|
|
57
|
+
MEDIUM: 10,
|
|
58
|
+
HIGH: 25,
|
|
59
|
+
MANDATORY: 0,
|
|
60
|
+
};
|
|
55
61
|
export function priorityToPenalty(priority) {
|
|
56
|
-
|
|
57
|
-
case "HIGH":
|
|
58
|
-
return 25;
|
|
59
|
-
case "MEDIUM":
|
|
60
|
-
return 10;
|
|
61
|
-
case "LOW":
|
|
62
|
-
return 1;
|
|
63
|
-
case "MANDATORY":
|
|
64
|
-
return 0;
|
|
65
|
-
default:
|
|
66
|
-
return 0;
|
|
67
|
-
}
|
|
62
|
+
return PRIORITY_PENALTIES[priority];
|
|
68
63
|
}
|
|
69
64
|
/**
|
|
70
65
|
* Computes the total duration of the union of time ranges.
|
package/dist/cpsat/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/cpsat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAIvD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,0EAA0E;IAC1E,YAAY,EAAE,IAAI;IAClB,6DAA6D;IAC7D,IAAI,EAAE,GAAG;IACT,sFAAsF;IACtF,qBAAqB,EAAE,EAAE;IACzB,+EAA+E;IAC/E,QAAQ,EAAE,CAAC;IACX,8CAA8C;IAC9C,eAAe,EAAE,CAAC;CACV,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,IAAI,IAAI,CAAC,GAAG,GAAG,YAAY,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAe;IAChD,OAAO,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAoB,EAAE,UAAkB;IAC1E,IAAI,UAAU,KAAK,YAAY;QAAE,OAAO,UAAU,GAAG,eAAe,CAAC;IACrE,OAAO,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC;AAC/E,CAAC;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/cpsat/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ export interface ValidationReporter {
|
|
|
4
4
|
excludeFromCoverage(exclusion: CoverageExclusion): void;
|
|
5
5
|
reportCoverageError(error: Omit<CoverageError, "type" | "id">): void;
|
|
6
6
|
reportRuleError(error: Omit<RuleError, "type" | "id">): void;
|
|
7
|
-
reportSolverError(
|
|
7
|
+
reportSolverError(message: string): void;
|
|
8
8
|
reportCoverageViolation(violation: Omit<CoverageViolation, "type" | "id">): void;
|
|
9
9
|
reportRuleViolation(violation: Omit<RuleViolation, "type" | "id">): void;
|
|
10
10
|
reportCoveragePassed(passed: Omit<CoveragePassed, "type" | "id">): void;
|
|
@@ -20,7 +20,7 @@ export declare class ValidationReporterImpl implements ValidationReporter {
|
|
|
20
20
|
excludeFromCoverage(exclusion: CoverageExclusion): void;
|
|
21
21
|
reportCoverageError(error: Omit<CoverageError, "type" | "id">): void;
|
|
22
22
|
reportRuleError(error: Omit<RuleError, "type" | "id">): void;
|
|
23
|
-
reportSolverError(
|
|
23
|
+
reportSolverError(message: string): void;
|
|
24
24
|
reportCoverageViolation(violation: Omit<CoverageViolation, "type" | "id">): void;
|
|
25
25
|
reportRuleViolation(violation: Omit<RuleViolation, "type" | "id">): void;
|
|
26
26
|
reportCoveragePassed(passed: Omit<CoveragePassed, "type" | "id">): void;
|
|
@@ -33,17 +33,20 @@ export declare class ValidationReporterImpl implements ValidationReporter {
|
|
|
33
33
|
analyzeSolution(response: SolverResponse): void;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* Aggregates validation items by their
|
|
37
|
-
* This is a pure function that doesn't modify the input.
|
|
36
|
+
* Aggregates validation items by their group into summaries.
|
|
38
37
|
*
|
|
39
|
-
* Items
|
|
38
|
+
* Items sharing the same `group.key` are merged into a single summary.
|
|
39
|
+
* The title comes from the first item's `group.title`; for ungrouped items
|
|
40
|
+
* the item's `message` is used instead.
|
|
41
|
+
*
|
|
42
|
+
* @category Validation
|
|
40
43
|
*
|
|
41
44
|
* @example
|
|
42
45
|
* ```typescript
|
|
43
|
-
* const validation = reporter.getValidation();
|
|
44
46
|
* const summaries = summarizeValidation(validation);
|
|
45
47
|
* // summaries[0] = {
|
|
46
|
-
* // groupKey: "
|
|
48
|
+
* // groupKey: "coverage:day_ward:nurse:3:dow:monday,tuesday,...",
|
|
49
|
+
* // title: "3x nurse during day_ward (weekdays)",
|
|
47
50
|
* // status: "passed",
|
|
48
51
|
* // passedCount: 180,
|
|
49
52
|
* // days: ["2026-02-02", "2026-02-03", ...]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-reporter.d.ts","sourceRoot":"","sources":["../../src/cpsat/validation-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"validation-reporter.d.ts","sourceRoot":"","sources":["../../src/cpsat/validation-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,kBAAkB;IAEjC,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAGxD,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACrE,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7D,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzC,uBAAuB,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACjF,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAGzE,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACxE,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAGhE,eAAe,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAGrD,SAAS,IAAI,OAAO,CAAC;IACrB,aAAa,IAAI,kBAAkB,CAAC;IACpC,aAAa,IAAI,iBAAiB,EAAE,CAAC;IAGrC,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CACjD;AA2CD,qBAAa,sBAAuB,YAAW,kBAAkB;;IAQ/D,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAIvD,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAKpE,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAK5D,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMxC,uBAAuB,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAWhF,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAKxE,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAKvE,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAK/D,aAAa,IAAI,iBAAiB,EAAE;IAIpC,eAAe,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI;IAIpD,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,kBAAkB;IAQnC,qBAAqB,IAAI,iBAAiB,EAAE;IAI5C,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;CAmEhD;AAQD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,kBAAkB,GAAG,SAAS,iBAAiB,EAAE,CAyEhG"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { groupKey, } from "./validation.types.js";
|
|
2
1
|
/**
|
|
3
2
|
* Generates a deterministic ID for a coverage-based validation item.
|
|
4
3
|
* Format: {category}:coverage:{day}:{timeSlots}:{roles}:{skills}
|
|
5
4
|
*/
|
|
6
|
-
function coverageId(category, day, timeSlots,
|
|
5
|
+
function coverageId(category, day, timeSlots, roleIds, skillIds) {
|
|
7
6
|
const parts = [
|
|
8
7
|
category,
|
|
9
8
|
"coverage",
|
|
10
9
|
day,
|
|
11
10
|
[...timeSlots].toSorted().join(",") || "_",
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
roleIds && roleIds.length > 0 ? [...roleIds].toSorted().join(",") : "_",
|
|
12
|
+
skillIds ? [...skillIds].toSorted().join(",") : "_",
|
|
14
13
|
];
|
|
15
14
|
return parts.join(":");
|
|
16
15
|
}
|
|
@@ -39,20 +38,20 @@ export class ValidationReporterImpl {
|
|
|
39
38
|
this.#exclusions.push(exclusion);
|
|
40
39
|
}
|
|
41
40
|
reportCoverageError(error) {
|
|
42
|
-
const id = coverageId("error", error.day, error.timeSlots, error.
|
|
41
|
+
const id = coverageId("error", error.day, error.timeSlots, error.roleIds, error.skillIds);
|
|
43
42
|
this.#errors.push({ id, type: "coverage", ...error });
|
|
44
43
|
}
|
|
45
44
|
reportRuleError(error) {
|
|
46
45
|
const id = ruleId("error", error.rule, error.context);
|
|
47
46
|
this.#errors.push({ id, type: "rule", ...error });
|
|
48
47
|
}
|
|
49
|
-
reportSolverError(
|
|
48
|
+
reportSolverError(message) {
|
|
50
49
|
this.#solverErrorCount++;
|
|
51
50
|
const id = `error:solver:${this.#solverErrorCount}`;
|
|
52
|
-
this.#errors.push({ id, type: "solver",
|
|
51
|
+
this.#errors.push({ id, type: "solver", message });
|
|
53
52
|
}
|
|
54
53
|
reportCoverageViolation(violation) {
|
|
55
|
-
const id = coverageId("violation", violation.day, violation.timeSlots, violation.
|
|
54
|
+
const id = coverageId("violation", violation.day, violation.timeSlots, violation.roleIds, violation.skillIds);
|
|
56
55
|
this.#violations.push({ id, type: "coverage", ...violation });
|
|
57
56
|
}
|
|
58
57
|
reportRuleViolation(violation) {
|
|
@@ -60,7 +59,7 @@ export class ValidationReporterImpl {
|
|
|
60
59
|
this.#violations.push({ id, type: "rule", ...violation });
|
|
61
60
|
}
|
|
62
61
|
reportCoveragePassed(passed) {
|
|
63
|
-
const id = coverageId("passed", passed.day, passed.timeSlots, passed.
|
|
62
|
+
const id = coverageId("passed", passed.day, passed.timeSlots, passed.roleIds, passed.skillIds);
|
|
64
63
|
this.#passed.push({ id, type: "coverage", ...passed });
|
|
65
64
|
}
|
|
66
65
|
reportRulePassed(passed) {
|
|
@@ -103,33 +102,35 @@ export class ValidationReporterImpl {
|
|
|
103
102
|
for (const violation of solverViolations) {
|
|
104
103
|
const tracked = this.#trackedConstraints.get(violation.constraintId);
|
|
105
104
|
if (tracked?.type === "coverage") {
|
|
105
|
+
const roles = tracked.roleIds?.join(", ") ?? "staff";
|
|
106
|
+
const slot = tracked.timeSlot ?? "all day";
|
|
106
107
|
this.reportCoverageViolation({
|
|
107
108
|
day: tracked.day ?? "",
|
|
108
109
|
timeSlots: tracked.timeSlot ? [tracked.timeSlot] : [],
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
roleIds: tracked.roleIds,
|
|
111
|
+
skillIds: tracked.skillIds,
|
|
111
112
|
targetCount: violation.targetValue,
|
|
112
113
|
actualCount: violation.actualValue,
|
|
113
114
|
shortfall: violation.violationAmount,
|
|
114
|
-
|
|
115
|
+
message: `${roles} on ${tracked.day} (${slot}): ${violation.actualValue} assigned, need ${violation.targetValue}`,
|
|
116
|
+
group: tracked.group,
|
|
115
117
|
});
|
|
116
118
|
}
|
|
117
119
|
else if (tracked?.type === "rule") {
|
|
118
120
|
const isShortfall = tracked.comparator === ">=";
|
|
119
121
|
this.reportRuleViolation({
|
|
120
122
|
rule: tracked.rule ?? "unknown",
|
|
121
|
-
|
|
123
|
+
message: `${tracked.description}: needed ${violation.targetValue}, got ${violation.actualValue}`,
|
|
122
124
|
context: tracked.context,
|
|
123
125
|
shortfall: isShortfall ? violation.violationAmount : undefined,
|
|
124
126
|
overflow: !isShortfall ? violation.violationAmount : undefined,
|
|
125
|
-
|
|
127
|
+
group: tracked.group,
|
|
126
128
|
});
|
|
127
129
|
}
|
|
128
130
|
else {
|
|
129
|
-
// Unknown constraint - create generic rule violation
|
|
130
131
|
this.reportRuleViolation({
|
|
131
132
|
rule: "unknown",
|
|
132
|
-
|
|
133
|
+
message: `Constraint ${violation.constraintId} violated by ${violation.violationAmount}`,
|
|
133
134
|
context: {},
|
|
134
135
|
});
|
|
135
136
|
}
|
|
@@ -143,27 +144,30 @@ export class ValidationReporterImpl {
|
|
|
143
144
|
this.reportCoveragePassed({
|
|
144
145
|
day: tracked.day ?? "",
|
|
145
146
|
timeSlots: tracked.timeSlot ? [tracked.timeSlot] : [],
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
roleIds: tracked.roleIds,
|
|
148
|
+
skillIds: tracked.skillIds,
|
|
149
|
+
message: tracked.description,
|
|
150
|
+
group: tracked.group,
|
|
150
151
|
});
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
/**
|
|
156
|
-
* Aggregates validation items by their
|
|
157
|
-
* This is a pure function that doesn't modify the input.
|
|
157
|
+
* Aggregates validation items by their group into summaries.
|
|
158
158
|
*
|
|
159
|
-
* Items
|
|
159
|
+
* Items sharing the same `group.key` are merged into a single summary.
|
|
160
|
+
* The title comes from the first item's `group.title`; for ungrouped items
|
|
161
|
+
* the item's `message` is used instead.
|
|
162
|
+
*
|
|
163
|
+
* @category Validation
|
|
160
164
|
*
|
|
161
165
|
* @example
|
|
162
166
|
* ```typescript
|
|
163
|
-
* const validation = reporter.getValidation();
|
|
164
167
|
* const summaries = summarizeValidation(validation);
|
|
165
168
|
* // summaries[0] = {
|
|
166
|
-
* // groupKey: "
|
|
169
|
+
* // groupKey: "coverage:day_ward:nurse:3:dow:monday,tuesday,...",
|
|
170
|
+
* // title: "3x nurse during day_ward (weekdays)",
|
|
167
171
|
* // status: "passed",
|
|
168
172
|
* // passedCount: 180,
|
|
169
173
|
* // days: ["2026-02-02", "2026-02-03", ...]
|
|
@@ -172,11 +176,13 @@ export class ValidationReporterImpl {
|
|
|
172
176
|
*/
|
|
173
177
|
export function summarizeValidation(validation) {
|
|
174
178
|
const groups = new Map();
|
|
175
|
-
const
|
|
179
|
+
const getOrCreateStats = (item) => {
|
|
180
|
+
const key = ("group" in item && item.group?.key) || `ungrouped:${item.id}`;
|
|
181
|
+
const title = ("group" in item && item.group?.title) || item.message;
|
|
176
182
|
if (!groups.has(key)) {
|
|
177
183
|
groups.set(key, {
|
|
178
|
-
type,
|
|
179
|
-
|
|
184
|
+
type: item.type,
|
|
185
|
+
title,
|
|
180
186
|
days: new Set(),
|
|
181
187
|
passedCount: 0,
|
|
182
188
|
violatedCount: 0,
|
|
@@ -185,46 +191,36 @@ export function summarizeValidation(validation) {
|
|
|
185
191
|
}
|
|
186
192
|
return groups.get(key);
|
|
187
193
|
};
|
|
188
|
-
// Group passed items
|
|
189
194
|
for (const item of validation.passed) {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
group.items.push(item);
|
|
193
|
-
group.passedCount++;
|
|
195
|
+
const stats = getOrCreateStats(item);
|
|
196
|
+
stats.passedCount++;
|
|
194
197
|
if (item.type === "coverage" && item.day) {
|
|
195
|
-
|
|
198
|
+
stats.days.add(item.day);
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
|
-
// Group violations
|
|
199
201
|
for (const item of validation.violations) {
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
group.items.push(item);
|
|
203
|
-
group.violatedCount++;
|
|
202
|
+
const stats = getOrCreateStats(item);
|
|
203
|
+
stats.violatedCount++;
|
|
204
204
|
if (item.type === "coverage" && item.day) {
|
|
205
|
-
|
|
205
|
+
stats.days.add(item.day);
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
// Group errors (except solver errors which don't have groupKey)
|
|
209
208
|
for (const item of validation.errors) {
|
|
210
209
|
if (item.type === "solver")
|
|
211
210
|
continue;
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
group.items.push(item);
|
|
215
|
-
group.errorCount++;
|
|
211
|
+
const stats = getOrCreateStats(item);
|
|
212
|
+
stats.errorCount++;
|
|
216
213
|
if (item.type === "coverage" && item.day) {
|
|
217
|
-
|
|
214
|
+
stats.days.add(item.day);
|
|
218
215
|
}
|
|
219
216
|
}
|
|
220
|
-
// Build summaries
|
|
221
217
|
const summaries = [];
|
|
222
218
|
for (const [key, group] of groups) {
|
|
223
219
|
const status = group.errorCount > 0 ? "failed" : group.violatedCount > 0 ? "partial" : "passed";
|
|
224
220
|
summaries.push({
|
|
225
221
|
groupKey: key,
|
|
226
222
|
type: group.type,
|
|
227
|
-
|
|
223
|
+
title: group.title,
|
|
228
224
|
days: [...group.days].toSorted(),
|
|
229
225
|
status,
|
|
230
226
|
passedCount: group.passedCount,
|
|
@@ -234,28 +230,4 @@ export function summarizeValidation(validation) {
|
|
|
234
230
|
}
|
|
235
231
|
return summaries;
|
|
236
232
|
}
|
|
237
|
-
/**
|
|
238
|
-
* Infers a human-readable description from the groupKey or items.
|
|
239
|
-
*/
|
|
240
|
-
function inferDescription(key, items) {
|
|
241
|
-
// If the key looks like a human-readable description, use it
|
|
242
|
-
if (!key.startsWith("ungrouped:")) {
|
|
243
|
-
return key;
|
|
244
|
-
}
|
|
245
|
-
// Try to infer from the first item with a description
|
|
246
|
-
for (const item of items) {
|
|
247
|
-
if ("description" in item && item.description) {
|
|
248
|
-
// Extract the meaningful part (e.g., "2x waiter" from "2x waiter on 2026-02-03 at 09:00")
|
|
249
|
-
const match = item.description.match(/^(\d+x \w+)/);
|
|
250
|
-
if (match?.[1]) {
|
|
251
|
-
return match[1];
|
|
252
|
-
}
|
|
253
|
-
return item.description;
|
|
254
|
-
}
|
|
255
|
-
if ("reason" in item && item.reason) {
|
|
256
|
-
return item.reason;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return key;
|
|
260
|
-
}
|
|
261
233
|
//# sourceMappingURL=validation-reporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-reporter.js","sourceRoot":"","sources":["../../src/cpsat/validation-reporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation-reporter.js","sourceRoot":"","sources":["../../src/cpsat/validation-reporter.ts"],"names":[],"mappings":"AA8CA;;;GAGG;AACH,SAAS,UAAU,CACjB,QAA0C,EAC1C,GAAW,EACX,SAA4B,EAC5B,OAA2B,EAC3B,QAA4B;IAE5B,MAAM,KAAK,GAAG;QACZ,QAAQ;QACR,UAAU;QACV,GAAG;QACH,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG;QAC1C,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QACvE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;KACpD,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,SAAS,MAAM,CACb,QAA0C,EAC1C,IAAY,EACZ,OAAoE;IAEpE,MAAM,KAAK,GAAG;QACZ,QAAQ;QACR,MAAM;QACN,IAAI;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QAC3D,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;KACtE,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,OAAO,sBAAsB;IACjC,OAAO,GAAoB,EAAE,CAAC;IAC9B,WAAW,GAAwB,EAAE,CAAC;IACtC,OAAO,GAAqB,EAAE,CAAC;IAC/B,mBAAmB,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC3D,WAAW,GAAwB,EAAE,CAAC;IACtC,iBAAiB,GAAG,CAAC,CAAC;IAEtB,mBAAmB,CAAC,SAA4B;QAC9C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,mBAAmB,CAAC,KAAyC;QAC3D,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,eAAe,CAAC,KAAqC;QACnD,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,iBAAiB,CAAC,OAAe;QAC/B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,gBAAgB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,uBAAuB,CAAC,SAAiD;QACvE,MAAM,EAAE,GAAG,UAAU,CACnB,WAAW,EACX,SAAS,CAAC,GAAG,EACb,SAAS,CAAC,SAAS,EACnB,SAAS,CAAC,OAAO,EACjB,SAAS,CAAC,QAAQ,CACnB,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,mBAAmB,CAAC,SAA6C;QAC/D,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAClE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,oBAAoB,CAAC,MAA2C;QAC9D,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,gBAAgB,CAAC,MAAuC;QACtD,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,aAAa;QACX,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;IAED,eAAe,CAAC,UAA6B;QAC3C,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,aAAa;QACX,OAAO;YACL,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YACzB,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;YACjC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,qBAAqB;QACnB,OAAO,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,eAAe,CAAC,QAAwB;QACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACpE,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;gBACrC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,YAAY,IAAI,wBAAwB,CAAC,CAAC;YAC5E,CAAC;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC;QAEvD,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAErE,IAAI,OAAO,EAAE,IAAI,KAAK,UAAU,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;gBACrD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC;gBAC3C,IAAI,CAAC,uBAAuB,CAAC;oBAC3B,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE;oBACtB,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;oBACrD,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,SAAS,EAAE,SAAS,CAAC,eAAe;oBACpC,OAAO,EAAE,GAAG,KAAK,OAAO,OAAO,CAAC,GAAG,KAAK,IAAI,MAAM,SAAS,CAAC,WAAW,mBAAmB,SAAS,CAAC,WAAW,EAAE;oBACjH,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpC,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;gBAChD,IAAI,CAAC,mBAAmB,CAAC;oBACvB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,SAAS;oBAC/B,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,YAAY,SAAS,CAAC,WAAW,SAAS,SAAS,CAAC,WAAW,EAAE;oBAChG,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;oBAC9D,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;oBAC9D,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,mBAAmB,CAAC;oBACvB,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,cAAc,SAAS,CAAC,YAAY,gBAAgB,SAAS,CAAC,eAAe,EAAE;oBACxF,OAAO,EAAE,EAAE;iBACZ,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,8DAA8D;QAC9D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACzE,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC;YACxD,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAAE,SAAS;YAE1C,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAChC,IAAI,CAAC,oBAAoB,CAAC;oBACxB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE;oBACtB,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;oBACrD,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,OAAO,EAAE,OAAO,CAAC,WAAW;oBAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAQD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA8B;IAChE,MAAM,MAAM,GAAG,IAAI,GAAG,EAUnB,CAAC;IAEJ,MAAM,gBAAgB,GAAG,CAAC,IAAiD,EAAE,EAAE;QAC7E,MAAM,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,aAAa,IAAI,CAAC,EAAE,EAAE,CAAC;QAC3E,MAAM,KAAK,GAAG,CAAC,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC;QAErE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACd,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK;gBACL,IAAI,EAAE,IAAI,GAAG,EAAE;gBACf,WAAW,EAAE,CAAC;gBACd,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,CAAC;aACd,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IAC1B,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,aAAa,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS;QACrC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAClC,MAAM,MAAM,GACV,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEnF,SAAS,CAAC,IAAI,CAAC;YACb,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;YAChC,MAAM;YACN,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|