@elaraai/e3-ui 1.0.94 → 1.0.95
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/src/allocation/adapters.d.ts +159 -0
- package/dist/src/allocation/adapters.d.ts.map +1 -0
- package/dist/src/allocation/adapters.js +241 -0
- package/dist/src/allocation/adapters.js.map +1 -0
- package/dist/src/allocation/functions.d.ts +664 -0
- package/dist/src/allocation/functions.d.ts.map +1 -0
- package/dist/src/allocation/functions.js +782 -0
- package/dist/src/allocation/functions.js.map +1 -0
- package/dist/src/allocation/index.d.ts +2985 -0
- package/dist/src/allocation/index.d.ts.map +1 -0
- package/dist/src/allocation/index.js +499 -0
- package/dist/src/allocation/index.js.map +1 -0
- package/dist/src/allocation/types.d.ts +832 -0
- package/dist/src/allocation/types.d.ts.map +1 -0
- package/dist/src/allocation/types.js +360 -0
- package/dist/src/allocation/types.js.map +1 -0
- package/dist/src/bind/func.d.ts +14 -0
- package/dist/src/bind/func.d.ts.map +1 -1
- package/dist/src/bind/func.js +22 -1
- package/dist/src/bind/func.js.map +1 -1
- package/dist/src/calendar/index.d.ts +510 -1639
- package/dist/src/calendar/index.d.ts.map +1 -1
- package/dist/src/calendar/index.js +56 -29
- package/dist/src/calendar/index.js.map +1 -1
- package/dist/src/flowchart/canvas.d.ts +9 -21
- package/dist/src/flowchart/canvas.d.ts.map +1 -1
- package/dist/src/flowchart/canvas.js +10 -22
- package/dist/src/flowchart/canvas.js.map +1 -1
- package/dist/src/flowchart/flowchart.d.ts +19 -13
- package/dist/src/flowchart/flowchart.d.ts.map +1 -1
- package/dist/src/flowchart/flowchart.js.map +1 -1
- package/dist/src/flowchart/index.d.ts +44 -21
- package/dist/src/flowchart/index.d.ts.map +1 -1
- package/dist/src/flowchart/index.js +43 -20
- package/dist/src/flowchart/index.js.map +1 -1
- package/dist/src/flowchart/library.d.ts +166 -81
- package/dist/src/flowchart/library.d.ts.map +1 -1
- package/dist/src/flowchart/library.js +232 -105
- package/dist/src/flowchart/library.js.map +1 -1
- package/dist/src/flowchart/over.d.ts +9 -16
- package/dist/src/flowchart/over.d.ts.map +1 -1
- package/dist/src/flowchart/over.js +9 -16
- package/dist/src/flowchart/over.js.map +1 -1
- package/dist/src/flowchart/payload.d.ts +710 -508
- package/dist/src/flowchart/payload.d.ts.map +1 -1
- package/dist/src/flowchart/payload.js +128 -74
- package/dist/src/flowchart/payload.js.map +1 -1
- package/dist/src/flowchart/window.d.ts +132 -347
- package/dist/src/flowchart/window.d.ts.map +1 -1
- package/dist/src/flowchart/window.js +48 -55
- package/dist/src/flowchart/window.js.map +1 -1
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +14 -6
- package/dist/src/index.js.map +1 -1
- package/dist/src/internal.d.ts +18 -7
- package/dist/src/internal.d.ts.map +1 -1
- package/dist/src/internal.js +28 -9
- package/dist/src/internal.js.map +1 -1
- package/dist/src/plan/event-rows.d.ts +26 -10
- package/dist/src/plan/event-rows.d.ts.map +1 -1
- package/dist/src/plan/event-rows.js +39 -13
- package/dist/src/plan/event-rows.js.map +1 -1
- package/dist/src/plan/ir.d.ts +244 -815
- package/dist/src/plan/ir.d.ts.map +1 -1
- package/dist/src/plan/ir.js +8 -6
- package/dist/src/plan/ir.js.map +1 -1
- package/dist/src/plan/library.d.ts +3 -0
- package/dist/src/plan/library.d.ts.map +1 -1
- package/dist/src/plan/library.js +1 -1
- package/dist/src/plan/library.js.map +1 -1
- package/dist/src/plan/ordered-source.d.ts +1 -0
- package/dist/src/plan/ordered-source.d.ts.map +1 -1
- package/dist/src/plan/plan.d.ts +559 -1667
- package/dist/src/plan/plan.d.ts.map +1 -1
- package/dist/src/plan/plan.js +123 -45
- package/dist/src/plan/plan.js.map +1 -1
- package/dist/src/plan/root.d.ts +16 -20
- package/dist/src/plan/root.d.ts.map +1 -1
- package/dist/src/plan/root.js +23 -33
- package/dist/src/plan/root.js.map +1 -1
- package/dist/src/roster/coverage.d.ts +17 -231
- package/dist/src/roster/coverage.d.ts.map +1 -1
- package/dist/src/roster/coverage.js +94 -90
- package/dist/src/roster/coverage.js.map +1 -1
- package/dist/src/roster/fit.d.ts +59 -0
- package/dist/src/roster/fit.d.ts.map +1 -0
- package/dist/src/roster/fit.js +155 -0
- package/dist/src/roster/fit.js.map +1 -0
- package/dist/src/roster/index.d.ts +2862 -3662
- package/dist/src/roster/index.d.ts.map +1 -1
- package/dist/src/roster/index.js +383 -81
- package/dist/src/roster/index.js.map +1 -1
- package/dist/src/roster/library.d.ts +37 -92
- package/dist/src/roster/library.d.ts.map +1 -1
- package/dist/src/roster/library.js +25 -64
- package/dist/src/roster/library.js.map +1 -1
- package/dist/src/roster/lists.d.ts +195 -0
- package/dist/src/roster/lists.d.ts.map +1 -0
- package/dist/src/roster/lists.js +233 -0
- package/dist/src/roster/lists.js.map +1 -0
- package/dist/src/roster/rules.d.ts +17 -260
- package/dist/src/roster/rules.d.ts.map +1 -1
- package/dist/src/roster/rules.js +135 -132
- package/dist/src/roster/rules.js.map +1 -1
- package/dist/src/roster/targets.d.ts +115 -0
- package/dist/src/roster/targets.d.ts.map +1 -0
- package/dist/src/roster/targets.js +213 -0
- package/dist/src/roster/targets.js.map +1 -0
- package/dist/src/roster/times.d.ts +251 -0
- package/dist/src/roster/times.d.ts.map +1 -0
- package/dist/src/roster/times.js +174 -0
- package/dist/src/roster/times.js.map +1 -0
- package/dist/src/roster/types.d.ts +828 -183
- package/dist/src/roster/types.d.ts.map +1 -1
- package/dist/src/roster/types.js +224 -97
- package/dist/src/roster/types.js.map +1 -1
- package/dist/src/schedule/accessor.d.ts +28 -0
- package/dist/src/schedule/accessor.d.ts.map +1 -0
- package/dist/src/schedule/accessor.js +39 -0
- package/dist/src/schedule/accessor.js.map +1 -0
- package/dist/src/schedule/events.d.ts +170 -42
- package/dist/src/schedule/events.d.ts.map +1 -1
- package/dist/src/schedule/events.js +431 -171
- package/dist/src/schedule/events.js.map +1 -1
- package/dist/src/schedule/index.d.ts +41 -4
- package/dist/src/schedule/index.d.ts.map +1 -1
- package/dist/src/schedule/index.js +35 -3
- package/dist/src/schedule/index.js.map +1 -1
- package/dist/src/schedule/library.d.ts +13 -3
- package/dist/src/schedule/library.d.ts.map +1 -1
- package/dist/src/schedule/library.js +11 -4
- package/dist/src/schedule/library.js.map +1 -1
- package/dist/src/schedule/periods.d.ts +115 -0
- package/dist/src/schedule/periods.d.ts.map +1 -0
- package/dist/src/schedule/periods.js +215 -0
- package/dist/src/schedule/periods.js.map +1 -0
- package/dist/src/schedule/record-window.d.ts +25 -3
- package/dist/src/schedule/record-window.d.ts.map +1 -1
- package/dist/src/schedule/record-window.js +31 -18
- package/dist/src/schedule/record-window.js.map +1 -1
- package/dist/src/schedule/resources.d.ts +82 -4
- package/dist/src/schedule/resources.d.ts.map +1 -1
- package/dist/src/schedule/resources.js +44 -14
- package/dist/src/schedule/resources.js.map +1 -1
- package/dist/src/schedule/session.d.ts +69 -0
- package/dist/src/schedule/session.d.ts.map +1 -0
- package/dist/src/schedule/session.js +121 -0
- package/dist/src/schedule/session.js.map +1 -0
- package/dist/src/schedule/templates.d.ts +14 -2
- package/dist/src/schedule/templates.d.ts.map +1 -1
- package/dist/src/schedule/templates.js +5 -3
- package/dist/src/schedule/templates.js.map +1 -1
- package/dist/src/schedule/types.d.ts +1671 -37
- package/dist/src/schedule/types.d.ts.map +1 -1
- package/dist/src/schedule/types.js +196 -5
- package/dist/src/schedule/types.js.map +1 -1
- package/dist/src/schedule/window.d.ts +14 -0
- package/dist/src/schedule/window.d.ts.map +1 -1
- package/dist/src/schedule/window.js +14 -4
- package/dist/src/schedule/window.js.map +1 -1
- package/dist/src/schedule/words.d.ts +22 -0
- package/dist/src/schedule/words.d.ts.map +1 -0
- package/dist/src/schedule/words.js +25 -0
- package/dist/src/schedule/words.js.map +1 -0
- package/dist/src/sheet/index.d.ts +61 -27
- package/dist/src/sheet/index.d.ts.map +1 -1
- package/dist/src/sheet/index.js +59 -25
- package/dist/src/sheet/index.js.map +1 -1
- package/dist/src/sheet/library.d.ts +21 -3
- package/dist/src/sheet/library.d.ts.map +1 -1
- package/dist/src/sheet/library.js +23 -6
- package/dist/src/sheet/library.js.map +1 -1
- package/dist/src/sheet/registers.d.ts +100 -85
- package/dist/src/sheet/registers.d.ts.map +1 -1
- package/dist/src/sheet/registers.js +100 -85
- package/dist/src/sheet/registers.js.map +1 -1
- package/dist/src/sheet/root.d.ts +8 -12
- package/dist/src/sheet/root.d.ts.map +1 -1
- package/dist/src/sheet/root.js +6 -40
- package/dist/src/sheet/root.js.map +1 -1
- package/dist/src/sheet/sheet.d.ts +598 -2349
- package/dist/src/sheet/sheet.d.ts.map +1 -1
- package/dist/src/sheet/sheet.js +124 -37
- package/dist/src/sheet/sheet.js.map +1 -1
- package/dist/src/sheet/sub-rows.d.ts +74 -28
- package/dist/src/sheet/sub-rows.d.ts.map +1 -1
- package/dist/src/sheet/sub-rows.js +74 -28
- package/dist/src/sheet/sub-rows.js.map +1 -1
- package/dist/src/sheet/templates.d.ts +98 -34
- package/dist/src/sheet/templates.d.ts.map +1 -1
- package/dist/src/sheet/templates.js +102 -58
- package/dist/src/sheet/templates.js.map +1 -1
- package/dist/src/sheet/types.d.ts +289 -1359
- package/dist/src/sheet/types.d.ts.map +1 -1
- package/dist/src/sheet/types.js +20 -26
- package/dist/src/sheet/types.js.map +1 -1
- package/dist/src/sheet/views.d.ts +10 -11
- package/dist/src/sheet/views.d.ts.map +1 -1
- package/dist/src/sheet/views.js +15 -20
- package/dist/src/sheet/views.js.map +1 -1
- package/dist/src/{roster/visibility.d.ts → utils/key-visibility.d.ts} +42 -7
- package/dist/src/utils/key-visibility.d.ts.map +1 -0
- package/dist/src/utils/key-visibility.js +36 -0
- package/dist/src/utils/key-visibility.js.map +1 -0
- package/dist/src/utils/ordered-source.d.ts +1 -0
- package/dist/src/utils/ordered-source.d.ts.map +1 -1
- package/dist/src/utils/ordered-source.js +8 -3
- package/dist/src/utils/ordered-source.js.map +1 -1
- package/dist/src/utils/record-sources.d.ts +107 -0
- package/dist/src/utils/record-sources.d.ts.map +1 -0
- package/dist/src/utils/record-sources.js +132 -0
- package/dist/src/utils/record-sources.js.map +1 -0
- package/dist/test/allocation/allocation.examples.d.ts +2902 -0
- package/dist/test/allocation/allocation.examples.d.ts.map +1 -0
- package/dist/test/allocation/allocation.examples.js +643 -0
- package/dist/test/allocation/allocation.examples.js.map +1 -0
- package/dist/test/allocation/fit.examples.d.ts +546 -0
- package/dist/test/allocation/fit.examples.d.ts.map +1 -0
- package/dist/test/allocation/fit.examples.js +171 -0
- package/dist/test/allocation/fit.examples.js.map +1 -0
- package/dist/test/allocation/kiln-yard.d.ts +181 -0
- package/dist/test/allocation/kiln-yard.d.ts.map +1 -0
- package/dist/test/allocation/kiln-yard.js +228 -0
- package/dist/test/allocation/kiln-yard.js.map +1 -0
- package/dist/test/bind/data/data.examples.d.ts +651 -1
- package/dist/test/bind/data/data.examples.d.ts.map +1 -1
- package/dist/test/bind/data/data.examples.js +140 -2
- package/dist/test/bind/data/data.examples.js.map +1 -1
- package/dist/test/bind/func/func.examples.d.ts +10 -1
- package/dist/test/bind/func/func.examples.d.ts.map +1 -1
- package/dist/test/bind/func/func.examples.js +8 -1
- package/dist/test/bind/func/func.examples.js.map +1 -1
- package/dist/test/bind/record/record.examples.d.ts +633 -1
- package/dist/test/bind/record/record.examples.d.ts.map +1 -1
- package/dist/test/bind/record/record.examples.js +26 -2
- package/dist/test/bind/record/record.examples.js.map +1 -1
- package/dist/test/calendar/calendar-records.examples.d.ts.map +1 -1
- package/dist/test/calendar/calendar-records.examples.js +18 -14
- package/dist/test/calendar/calendar-records.examples.js.map +1 -1
- package/dist/test/calendar/calendar.examples.d.ts +521 -16
- package/dist/test/calendar/calendar.examples.d.ts.map +1 -1
- package/dist/test/calendar/calendar.examples.js +182 -135
- package/dist/test/calendar/calendar.examples.js.map +1 -1
- package/dist/test/examples-package.d.ts +75 -0
- package/dist/test/examples-package.d.ts.map +1 -0
- package/dist/test/examples-package.js +263 -0
- package/dist/test/examples-package.js.map +1 -0
- package/dist/test/flowchart/flowchart.examples.d.ts +211 -19
- package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -1
- package/dist/test/flowchart/flowchart.examples.js +102 -75
- package/dist/test/flowchart/flowchart.examples.js.map +1 -1
- package/dist/test/plan/plan-events.examples.d.ts +1439 -209
- package/dist/test/plan/plan-events.examples.d.ts.map +1 -1
- package/dist/test/plan/plan-events.examples.js +199 -59
- package/dist/test/plan/plan-events.examples.js.map +1 -1
- package/dist/test/plan/plan-records.examples.d.ts +420 -0
- package/dist/test/plan/plan-records.examples.d.ts.map +1 -1
- package/dist/test/plan/plan-records.examples.js +70 -19
- package/dist/test/plan/plan-records.examples.js.map +1 -1
- package/dist/test/plan/plan-windows.examples.d.ts +636 -55
- package/dist/test/plan/plan-windows.examples.d.ts.map +1 -1
- package/dist/test/plan/plan-windows.examples.js +69 -33
- package/dist/test/plan/plan-windows.examples.js.map +1 -1
- package/dist/test/plan/plan.examples.d.ts +153 -31
- package/dist/test/plan/plan.examples.d.ts.map +1 -1
- package/dist/test/plan/plan.examples.js +178 -101
- package/dist/test/plan/plan.examples.js.map +1 -1
- package/dist/test/roster/domain.examples.d.ts +467 -250
- package/dist/test/roster/domain.examples.d.ts.map +1 -1
- package/dist/test/roster/domain.examples.js +92 -29
- package/dist/test/roster/domain.examples.js.map +1 -1
- package/dist/test/roster/roster-records.examples.d.ts +430 -586
- package/dist/test/roster/roster-records.examples.d.ts.map +1 -1
- package/dist/test/roster/roster-records.examples.js +102 -43
- package/dist/test/roster/roster-records.examples.js.map +1 -1
- package/dist/test/roster/roster.examples.d.ts +2319 -606
- package/dist/test/roster/roster.examples.d.ts.map +1 -1
- package/dist/test/roster/roster.examples.js +456 -148
- package/dist/test/roster/roster.examples.js.map +1 -1
- package/dist/test/roster/warehouse.d.ts +172 -63
- package/dist/test/roster/warehouse.d.ts.map +1 -1
- package/dist/test/roster/warehouse.js +172 -39
- package/dist/test/roster/warehouse.js.map +1 -1
- package/dist/test/schedule/schedule.examples.d.ts +3499 -0
- package/dist/test/schedule/schedule.examples.d.ts.map +1 -0
- package/dist/test/schedule/schedule.examples.js +192 -0
- package/dist/test/schedule/schedule.examples.js.map +1 -0
- package/dist/test/sheet/sheet-records.examples.d.ts.map +1 -1
- package/dist/test/sheet/sheet-records.examples.js +22 -18
- package/dist/test/sheet/sheet-records.examples.js.map +1 -1
- package/dist/test/sheet/sheet.examples.d.ts +715 -26
- package/dist/test/sheet/sheet.examples.d.ts.map +1 -1
- package/dist/test/sheet/sheet.examples.js +204 -130
- package/dist/test/sheet/sheet.examples.js.map +1 -1
- package/package.json +17 -10
- package/dist/src/roster/people.d.ts +0 -50
- package/dist/src/roster/people.d.ts.map +0 -1
- package/dist/src/roster/people.js +0 -32
- package/dist/src/roster/people.js.map +0 -1
- package/dist/src/roster/visibility.d.ts.map +0 -1
- package/dist/src/roster/visibility.js +0 -25
- package/dist/src/roster/visibility.js.map +0 -1
|
@@ -2,108 +2,112 @@
|
|
|
2
2
|
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
3
|
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
|
-
import { ArrayType, BooleanType, DictType, East, FloatType, IntegerType, StringType, none, some } from "@elaraai/east";
|
|
6
|
-
import { RosterContextType, RosterCoverageLineType, RosterCoverageType, RosterRequirementType, RosterSlotType,
|
|
5
|
+
import { ArrayType, BooleanType, DictType, East, FloatType, IntegerType, StringType, none, some, } from "@elaraai/east";
|
|
6
|
+
import { RosterContextType, RosterCoverageLineType, RosterCoverageType, RosterPayType, RosterRequirementType, RosterSlotType, RosterWeekTypeFor, } from "./types.js";
|
|
7
7
|
/**
|
|
8
|
-
* Calculates every configured slot's staffing, activity coverage and
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* @
|
|
12
|
-
* @
|
|
8
|
+
* Calculates every configured slot's staffing, activity coverage and pay
|
|
9
|
+
* (`Builder Interfaces Spec.md` §5.4).
|
|
10
|
+
*
|
|
11
|
+
* @typeParam R - The app's duty row type
|
|
12
|
+
* @param row - The app's duty row type
|
|
13
|
+
* @returns An East function `(week, context, pay) → Dict<Slot, Coverage>`: coverage keyed by day, group and shift
|
|
14
|
+
* @remarks Pure East: tasks and the renderer compile this same calculation. Each duty counts its own hours; requests fill positions, but never supply skills or a lead. A slot's cost is its duties' pay, every code summed: zero without `pay`.
|
|
13
15
|
*/
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
$.
|
|
31
|
-
$.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
$.
|
|
41
|
-
|
|
16
|
+
export function rosterCoverage(row) {
|
|
17
|
+
return East.function([RosterWeekTypeFor(row), RosterContextType, RosterPayType], DictType(RosterSlotType, RosterCoverageType), ($, week, context, pay) => {
|
|
18
|
+
const result = $.let(new Map(), DictType(RosterSlotType, RosterCoverageType));
|
|
19
|
+
// The duties: the activities of no group, which every group may need.
|
|
20
|
+
const duties = $.const(context.activities.filter((_$, activity) => activity.group.hasTag("none")));
|
|
21
|
+
$.for(East.Array.range(0n, 7n), ($, day) => {
|
|
22
|
+
$.for(context.groups, ($, group) => {
|
|
23
|
+
// The group's skills, then the duties, each in the activities' order.
|
|
24
|
+
const activities = $.const(context.activities.filter((_$, activity) => East.equal(activity.group, some(group.key))).concat(duties));
|
|
25
|
+
$.for(context.shifts, ($, shift) => {
|
|
26
|
+
const slot = $.const({ day, group: group.key, shift: shift.key }, RosterSlotType);
|
|
27
|
+
const target = $.const(week.requirements.get(slot, $ => $.const({ positions: 0n, hours: new Map() }, RosterRequirementType)));
|
|
28
|
+
const assignments = $.const(week.assignments.filter((_$, a) => East.equal(a.slot, slot)));
|
|
29
|
+
const permanent = $.let(0.0, FloatType);
|
|
30
|
+
const agency = $.let(0.0, FloatType);
|
|
31
|
+
const requested = $.let(0.0, FloatType);
|
|
32
|
+
const cost = $.let(0.0, FloatType);
|
|
33
|
+
const people = $.let(0n, IntegerType);
|
|
34
|
+
const lead = $.let(false, BooleanType);
|
|
35
|
+
const trainer = $.let(false, BooleanType);
|
|
36
|
+
$.for(assignments, ($, a, id) => {
|
|
37
|
+
// The slot's pay: its duties' costs, every code summed.
|
|
38
|
+
$.match(pay.tryGet(id), { some: ($, costs) => { $.for(costs, ($, amount) => { $.assign(cost, cost.add(amount)); }); } });
|
|
39
|
+
$.match(a.who, {
|
|
40
|
+
request: $ => { $.assign(requested, requested.add(a.hours)); },
|
|
41
|
+
person: ($, key) => {
|
|
42
|
+
$.assign(people, people.add(1n));
|
|
43
|
+
$.if(context.people.has(key), $ => {
|
|
44
|
+
const person = $.const(context.people.get(key));
|
|
45
|
+
$.if(person.agency, $ => { $.assign(agency, agency.add(a.hours)); })
|
|
46
|
+
.else($ => { $.assign(permanent, permanent.add(a.hours)); });
|
|
47
|
+
$.if(person.trainer, $ => { $.assign(trainer, true); });
|
|
48
|
+
$.for(context.positions, ($, position) => {
|
|
49
|
+
$.if(East.equal(position.key, a.position).and(() => position.lead), $ => { $.assign(lead, true); });
|
|
50
|
+
});
|
|
42
51
|
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
52
|
+
},
|
|
53
|
+
});
|
|
45
54
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
const lines = $.let([], ArrayType(RosterCoverageLineType));
|
|
56
|
+
const needed = $.let(0.0, FloatType);
|
|
57
|
+
$.for(target.hours, ($, hours) => { $.assign(needed, needed.add(hours)); });
|
|
58
|
+
$.for(activities, ($, skill) => {
|
|
59
|
+
$.if(target.hours.has(skill.key), $ => {
|
|
60
|
+
const duty = $.const(skill.group.hasTag("none"));
|
|
61
|
+
const holders = $.let(0n, IntegerType);
|
|
62
|
+
const assigned = $.let(0.0, FloatType);
|
|
63
|
+
$.for(assignments, ($, a) => {
|
|
64
|
+
$.match(a.who, { person: ($, key) => {
|
|
65
|
+
$.if(context.people.has(key), $ => {
|
|
66
|
+
$.if(context.people.get(key).skills.has(skill.key), $ => { $.assign(holders, holders.add(1n)); });
|
|
67
|
+
});
|
|
68
|
+
$.if(East.equal(a.activity, some(skill.key)), $ => { $.assign(assigned, assigned.add(a.hours)); });
|
|
69
|
+
} });
|
|
70
|
+
});
|
|
71
|
+
const hours = $.const(target.hours.get(skill.key));
|
|
72
|
+
// A holder's capacity is the shift's nominal hours.
|
|
73
|
+
const capacity = $.const(holders.toFloat().multiply(shift.hours));
|
|
74
|
+
$(lines.pushLast({
|
|
75
|
+
skill: skill.key, needed: hours, assigned,
|
|
76
|
+
holders: duty.ifElse(() => none, () => some(holders)),
|
|
77
|
+
capacity: duty.ifElse(() => none, () => some(capacity)),
|
|
78
|
+
gap: duty.ifElse(() => 0.0, () => East.max(hours.subtract(capacity), $.const(0.0, FloatType))),
|
|
79
|
+
}));
|
|
62
80
|
});
|
|
63
|
-
const hours = $.const(target.hours.get(skill.key));
|
|
64
|
-
const capacity = $.const(holders.toFloat().multiply(shift.hours));
|
|
65
|
-
$(lines.pushLast({
|
|
66
|
-
skill: skill.key, needed: hours, assigned,
|
|
67
|
-
holders: duty.ifElse(() => none, () => some(holders)),
|
|
68
|
-
capacity: duty.ifElse(() => none, () => some(capacity)),
|
|
69
|
-
gap: duty.ifElse(() => 0.0, () => East.max(hours.subtract(capacity), $.const(0.0, FloatType))),
|
|
70
|
-
}));
|
|
71
81
|
});
|
|
82
|
+
$(result.insert(slot, {
|
|
83
|
+
positions: target.positions, filled: assignments.size(), open: East.max(target.positions.subtract(assignments.size()), $.const(0n, IntegerType)), people,
|
|
84
|
+
hours: { permanent, agency, requested, needed, rostered: permanent.add(agency).add(requested) },
|
|
85
|
+
lines, cost, lead, trainer,
|
|
86
|
+
}));
|
|
72
87
|
});
|
|
73
|
-
const cost = $.let(0.0, FloatType);
|
|
74
|
-
$.match(context.costs, { some: ($, costs) => {
|
|
75
|
-
$.assign(cost, permanent.multiply(costs.rates.permanent)
|
|
76
|
-
.add(agency.add(requested).multiply(costs.rates.agency))
|
|
77
|
-
.add(overtime.multiply(costs.rates.overtime)));
|
|
78
|
-
} });
|
|
79
|
-
$(result.insert(slot, {
|
|
80
|
-
positions: target.positions, filled: assignments.size(), open: East.max(target.positions.subtract(assignments.size()), $.const(0n, IntegerType)), people,
|
|
81
|
-
hours: { permanent, agency, overtime, requested, needed, rostered: permanent.add(agency).add(requested).add(overtime) },
|
|
82
|
-
lines, cost, lead, trainer,
|
|
83
|
-
}));
|
|
84
88
|
});
|
|
85
89
|
});
|
|
90
|
+
return result;
|
|
86
91
|
});
|
|
87
|
-
|
|
88
|
-
});
|
|
92
|
+
}
|
|
89
93
|
/**
|
|
90
|
-
* Calculates each person's
|
|
91
|
-
*
|
|
92
|
-
* @
|
|
93
|
-
* @
|
|
94
|
-
* @
|
|
94
|
+
* Calculates each person's hours for the week: each of their duties' hours.
|
|
95
|
+
*
|
|
96
|
+
* @typeParam R - The app's duty row type
|
|
97
|
+
* @param row - The app's duty row type
|
|
98
|
+
* @returns An East function `(week, context) → Dict<String, Float>`: weekly hours by the original staff key, zero for unassigned staff
|
|
99
|
+
* @remarks Used by both layouts, library cards and the inspector, and by the ready-made fit.
|
|
95
100
|
*/
|
|
96
|
-
export
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
$.if(shifts.has(a.slot.shift), $ => {
|
|
101
|
+
export function rosterWeekHours(row) {
|
|
102
|
+
return East.function([RosterWeekTypeFor(row), RosterContextType], DictType(StringType, FloatType), ($, week, context) => {
|
|
103
|
+
const result = $.let(context.people.map((_$, _person) => 0.0));
|
|
104
|
+
$.for(week.assignments, ($, a) => {
|
|
105
|
+
$.match(a.who, { person: ($, key) => {
|
|
102
106
|
const prior = $.const(result.get(key, () => 0.0));
|
|
103
|
-
$(result.insertOrUpdate(key, prior.add(
|
|
104
|
-
});
|
|
105
|
-
|
|
107
|
+
$(result.insertOrUpdate(key, prior.add(a.hours)));
|
|
108
|
+
} });
|
|
109
|
+
});
|
|
110
|
+
return result;
|
|
106
111
|
});
|
|
107
|
-
|
|
108
|
-
});
|
|
112
|
+
}
|
|
109
113
|
//# sourceMappingURL=coverage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../../src/roster/coverage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../../src/roster/coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The Roster's fit (#1334, `Allocation Spec.md` §13): who fits a Find fix's
|
|
7
|
+
* need — a lead, a trainer, a holder of a skill — on its issue's slot. The
|
|
8
|
+
* app's `e3.function` answers, bound to the Roster's `fit` with `Func.bind`,
|
|
9
|
+
* the contract the Allocation's fit keeps; `Roster.fit(R)` is the ready-made
|
|
10
|
+
* rule such a function may call, replace or build on, and `Roster.answer(R)`
|
|
11
|
+
* maps a rule over every person. Each takes the app's duty row type, as the
|
|
12
|
+
* request does (`Builder Interfaces Spec.md` §5.4). The renderer decides no
|
|
13
|
+
* one itself.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { FloatType, FunctionType, StringType, type EastType, type ExprType } from "@elaraai/east";
|
|
18
|
+
import { RosterContextType, RosterFitRequestTypeFor, RosterFitResultType, RosterFitType, RosterPersonType, RosterWeekTypeFor } from "./types.js";
|
|
19
|
+
/**
|
|
20
|
+
* One person's hours this week: each of their duties' hours — the hours
|
|
21
|
+
* `Roster.weekHours` gives them.
|
|
22
|
+
*
|
|
23
|
+
* @typeParam R - The app's duty row type
|
|
24
|
+
* @param row - The app's duty row type
|
|
25
|
+
* @returns An East function `(week, context, key) → Float`: their hours
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare function rosterPersonHours<R extends EastType>(row: R): ExprType<FunctionType<[RosterWeekTypeFor<R>, RosterContextType, StringType], FloatType>>;
|
|
29
|
+
/**
|
|
30
|
+
* The ready-made fit (§13): one person's verdict for a need on a slot.
|
|
31
|
+
*
|
|
32
|
+
* @typeParam R - The app's duty row type
|
|
33
|
+
* @param row - The app's duty row type
|
|
34
|
+
* @returns An East function `(request, person) → Fit`: their verdict
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* In order: a person who doesn't hold the need is refused — `Not a lead`
|
|
38
|
+
* (`Associate · not a lead`), `Not a trainer`, `Not skilled` (`doesn't hold
|
|
39
|
+
* Unloading`); one rostered that day is refused, `Rostered` (`rostered on
|
|
40
|
+
* Inbound · Early`), since moving them would leave their own shift short; one
|
|
41
|
+
* whose rest before or after the slot's shift falls under the rules' minimum is
|
|
42
|
+
* refused, `Rest too short` (`6 h rest · minimum 10 h`, its measure the rest),
|
|
43
|
+
* the shift run as a new duty would run it, from its start on the slot's day.
|
|
44
|
+
* Otherwise they fit, the slot's group first, then spare contract hours: the
|
|
45
|
+
* score is their spare hours this week — their contract less the hours of
|
|
46
|
+
* their duties — and a week's 168 hours more in the slot's group. The reason
|
|
47
|
+
* names their group and those hours (`Dispatch · 14 h spare`, `from Inbound ·
|
|
48
|
+
* 2 h over contract`), and nothing warns.
|
|
49
|
+
*/
|
|
50
|
+
export declare function rosterFit<R extends EastType>(row: R): ExprType<FunctionType<[RosterFitRequestTypeFor<R>, RosterPersonType], RosterFitType>>;
|
|
51
|
+
/**
|
|
52
|
+
* Answers the fit's question with a rule per person (§13).
|
|
53
|
+
*
|
|
54
|
+
* @typeParam R - The app's duty row type
|
|
55
|
+
* @param row - The app's duty row type
|
|
56
|
+
* @returns An East function `(request, fit) → FitResult`: a verdict for every person of the context, by staff key, with the need and the slot it answers
|
|
57
|
+
*/
|
|
58
|
+
export declare function rosterAnswer<R extends EastType>(row: R): ExprType<FunctionType<[RosterFitRequestTypeFor<R>, FunctionType<[RosterFitRequestTypeFor<R>, RosterPersonType], RosterFitType>], RosterFitResultType>>;
|
|
59
|
+
//# sourceMappingURL=fit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../../src/roster/fit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,EACG,SAAS,EAAE,YAAY,EAAE,UAAU,EACzC,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAC/B,MAAM,eAAe,CAAC;AAIvB,OAAO,EACsB,iBAAiB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAC/I,MAAM,YAAY,CAAC;AAKpB;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,QAAQ,EAAE,GAAG,EAAE,CAAC,GASvC,QAAQ,CAAC,YAAY,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC,CAC5G;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,GAAG,EAAE,CAAC,GA4E/B,QAAQ,CAAC,YAAY,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,aAAa,CAAC,CAAC,CACzG;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,EAAE,GAAG,EAAE,CAAC,GAKjC,QAAQ,CAAC,YAAY,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAC3K"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The Roster's fit (#1334, `Allocation Spec.md` §13): who fits a Find fix's
|
|
7
|
+
* need — a lead, a trainer, a holder of a skill — on its issue's slot. The
|
|
8
|
+
* app's `e3.function` answers, bound to the Roster's `fit` with `Func.bind`,
|
|
9
|
+
* the contract the Allocation's fit keeps; `Roster.fit(R)` is the ready-made
|
|
10
|
+
* rule such a function may call, replace or build on, and `Roster.answer(R)`
|
|
11
|
+
* maps a rule over every person. Each takes the app's duty row type, as the
|
|
12
|
+
* request does (`Builder Interfaces Spec.md` §5.4). The renderer decides no
|
|
13
|
+
* one itself.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { East, FloatType, FunctionType, StringType, defaultValue, none, variant, } from "@elaraai/east";
|
|
18
|
+
import { scheduleNumberText } from "../schedule/words.js";
|
|
19
|
+
import { rosterRest } from "./rules.js";
|
|
20
|
+
import { rosterShiftStart } from "./times.js";
|
|
21
|
+
import { RosterAssignmentTypeFor, RosterContextType, RosterFitRequestTypeFor, RosterFitResultType, RosterFitType, RosterPersonType, RosterWeekTypeFor, } from "./types.js";
|
|
22
|
+
/** A week's hours: the slot's group's bonus, more than any spare hours of a week. */
|
|
23
|
+
const WEEK_HOURS = 168.0;
|
|
24
|
+
/**
|
|
25
|
+
* One person's hours this week: each of their duties' hours — the hours
|
|
26
|
+
* `Roster.weekHours` gives them.
|
|
27
|
+
*
|
|
28
|
+
* @typeParam R - The app's duty row type
|
|
29
|
+
* @param row - The app's duty row type
|
|
30
|
+
* @returns An East function `(week, context, key) → Float`: their hours
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export function rosterPersonHours(row) {
|
|
34
|
+
return East.function([RosterWeekTypeFor(row), RosterContextType, StringType], FloatType, ($, week, _context, key) => {
|
|
35
|
+
const hours = $.let(0.0, FloatType);
|
|
36
|
+
$.for(week.assignments, ($2, a) => {
|
|
37
|
+
$2.match(a.who, { person: ($3, who) => {
|
|
38
|
+
$3.if(East.equal(who, key), ($4) => { $4.assign(hours, hours.add(a.hours)); });
|
|
39
|
+
} });
|
|
40
|
+
});
|
|
41
|
+
return hours;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The ready-made fit (§13): one person's verdict for a need on a slot.
|
|
46
|
+
*
|
|
47
|
+
* @typeParam R - The app's duty row type
|
|
48
|
+
* @param row - The app's duty row type
|
|
49
|
+
* @returns An East function `(request, person) → Fit`: their verdict
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* In order: a person who doesn't hold the need is refused — `Not a lead`
|
|
53
|
+
* (`Associate · not a lead`), `Not a trainer`, `Not skilled` (`doesn't hold
|
|
54
|
+
* Unloading`); one rostered that day is refused, `Rostered` (`rostered on
|
|
55
|
+
* Inbound · Early`), since moving them would leave their own shift short; one
|
|
56
|
+
* whose rest before or after the slot's shift falls under the rules' minimum is
|
|
57
|
+
* refused, `Rest too short` (`6 h rest · minimum 10 h`, its measure the rest),
|
|
58
|
+
* the shift run as a new duty would run it, from its start on the slot's day.
|
|
59
|
+
* Otherwise they fit, the slot's group first, then spare contract hours: the
|
|
60
|
+
* score is their spare hours this week — their contract less the hours of
|
|
61
|
+
* their duties — and a week's 168 hours more in the slot's group. The reason
|
|
62
|
+
* names their group and those hours (`Dispatch · 14 h spare`, `from Inbound ·
|
|
63
|
+
* 2 h over contract`), and nothing warns.
|
|
64
|
+
*/
|
|
65
|
+
export function rosterFit(row) {
|
|
66
|
+
const Row = row;
|
|
67
|
+
const restFn = rosterRest(Row);
|
|
68
|
+
const hoursFn = rosterPersonHours(Row);
|
|
69
|
+
const Assignment = RosterAssignmentTypeFor(Row);
|
|
70
|
+
// A candidate duty's row: the row type's default, which no rule reads.
|
|
71
|
+
const blank = defaultValue(Row);
|
|
72
|
+
return East.function([RosterFitRequestTypeFor(Row), RosterPersonType], RosterFitType, ($, request, person) => {
|
|
73
|
+
const restOf = $.const(restFn);
|
|
74
|
+
const hoursOf = $.const(hoursFn);
|
|
75
|
+
const shiftStart = $.const(rosterShiftStart);
|
|
76
|
+
const hoursText = $.const(scheduleNumberText);
|
|
77
|
+
const context = $.const(request.context);
|
|
78
|
+
const slot = $.const(request.slot);
|
|
79
|
+
const groups = $.const(context.groups.toDict((_$2, group) => group.key, (_$2, group) => group.label));
|
|
80
|
+
const labels = $.const(context.shifts.toDict((_$2, shift) => shift.key, (_$2, shift) => shift.label));
|
|
81
|
+
const shifts = $.const(context.shifts.toDict((_$2, shift) => shift.key, (_$2, shift) => shift));
|
|
82
|
+
// The need held.
|
|
83
|
+
$.match(request.need, {
|
|
84
|
+
leads: ($2) => {
|
|
85
|
+
const positions = $2.const(context.positions.filter((_$3, position) => East.equal(position.key, person.position)));
|
|
86
|
+
$2.if(positions.some((_$3, position) => position.lead).not(), ($3) => {
|
|
87
|
+
const reason = $3.const(East.greater(positions.size(), 0n).ifElse(() => East.str `${positions.get(0n).label} · not a lead`, () => East.str `not a lead`));
|
|
88
|
+
$3.return(variant("refused", { group: "Not a lead", reason, measure: variant("none", null) }));
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
trainers: ($2) => {
|
|
92
|
+
$2.if(person.trainer.not(), ($3) => {
|
|
93
|
+
$3.return(variant("refused", { group: "Not a trainer", reason: "not a trainer", measure: variant("none", null) }));
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
skill: ($2, key) => {
|
|
97
|
+
$2.if(person.skills.has(key).not(), ($3) => {
|
|
98
|
+
const skills = $3.const(context.activities.filter((_$4, activity) => East.equal(activity.key, key)));
|
|
99
|
+
const label = $3.const(East.greater(skills.size(), 0n).ifElse(() => skills.get(0n).label, () => key));
|
|
100
|
+
$3.return(variant("refused", { group: "Not skilled", reason: East.str `doesn't hold ${label}`, measure: variant("none", null) }));
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
// Not rostered that day: moving them would leave their own shift short.
|
|
105
|
+
const thatDay = $.const(request.week.assignments.filter((_$2, a) => East.equal(a.slot.day, slot.day)
|
|
106
|
+
.and(() => a.who.match({ person: (_$3, key) => East.equal(key, person.key), request: (_$3, _agency) => false }))).toArray((_$2, a) => a));
|
|
107
|
+
$.if(East.greater(thatDay.size(), 0n), ($2) => {
|
|
108
|
+
const held = $2.const(thatDay.get(0n));
|
|
109
|
+
$2.return(variant("refused", {
|
|
110
|
+
group: "Rostered", reason: East.str `rostered on ${groups.get(held.slot.group, () => held.slot.group)} · ${labels.get(held.slot.shift, () => held.slot.shift)}`,
|
|
111
|
+
measure: variant("none", null),
|
|
112
|
+
}));
|
|
113
|
+
});
|
|
114
|
+
// Rest kept, before and after the slot's shift, run as a new duty runs it.
|
|
115
|
+
$.if(shifts.has(slot.shift), ($2) => {
|
|
116
|
+
const shift = $2.const(shifts.get(slot.shift));
|
|
117
|
+
const start = $2.const(shiftStart(request.start.addDays(slot.day), shift));
|
|
118
|
+
const candidate = $2.const(East.value({
|
|
119
|
+
slot, who: variant("person", person.key), position: person.position, activity: none,
|
|
120
|
+
start, end: start.addHours(shift.hours), hours: shift.hours, row: blank,
|
|
121
|
+
}, Assignment));
|
|
122
|
+
const rest = $2.const(restOf(candidate, "", request.week, context));
|
|
123
|
+
$2.if(East.greater(context.rules.rest, 0.0).and(() => East.less(rest.minimum, context.rules.rest)), ($3) => {
|
|
124
|
+
$3.return(variant("refused", {
|
|
125
|
+
group: "Rest too short", reason: East.str `${hoursText(rest.minimum)} h rest · minimum ${hoursText(context.rules.rest)} h`,
|
|
126
|
+
measure: variant("amount", { lead: "rest", value: rest.minimum }),
|
|
127
|
+
}));
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
// It fits: the slot's group first, then spare contract hours.
|
|
131
|
+
const spare = $.const(person.contract.subtract(hoursOf(request.week, context, person.key)));
|
|
132
|
+
const home = $.const(East.equal(person.group, slot.group));
|
|
133
|
+
const hours = $.const(East.greater(spare, 0.0).ifElse(() => East.str `${hoursText(spare)} h spare`, () => East.equal(spare, 0.0).ifElse(() => East.str `no spare hours`, () => East.str `${hoursText(spare.negate())} h over contract`)));
|
|
134
|
+
return variant("fits", {
|
|
135
|
+
score: spare.add(home.ifElse(() => WEEK_HOURS, () => 0.0)),
|
|
136
|
+
why: home.ifElse(() => East.str `${groups.get(slot.group, () => slot.group)} · ${hours}`, () => East.str `from ${groups.get(person.group, () => person.group)} · ${hours}`),
|
|
137
|
+
warn: none,
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Answers the fit's question with a rule per person (§13).
|
|
143
|
+
*
|
|
144
|
+
* @typeParam R - The app's duty row type
|
|
145
|
+
* @param row - The app's duty row type
|
|
146
|
+
* @returns An East function `(request, fit) → FitResult`: a verdict for every person of the context, by staff key, with the need and the slot it answers
|
|
147
|
+
*/
|
|
148
|
+
export function rosterAnswer(row) {
|
|
149
|
+
const Request = RosterFitRequestTypeFor(row);
|
|
150
|
+
return East.function([Request, FunctionType([Request, RosterPersonType], RosterFitType)], RosterFitResultType, (_$, request, fit) => ({
|
|
151
|
+
need: request.need, slot: request.slot,
|
|
152
|
+
people: request.context.people.map((_$2, person) => fit(request, person)),
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=fit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.js","sourceRoot":"","sources":["../../../src/roster/fit.ts"],"names":[],"mappings":"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"}
|