@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.
Files changed (303) hide show
  1. package/dist/src/allocation/adapters.d.ts +159 -0
  2. package/dist/src/allocation/adapters.d.ts.map +1 -0
  3. package/dist/src/allocation/adapters.js +241 -0
  4. package/dist/src/allocation/adapters.js.map +1 -0
  5. package/dist/src/allocation/functions.d.ts +664 -0
  6. package/dist/src/allocation/functions.d.ts.map +1 -0
  7. package/dist/src/allocation/functions.js +782 -0
  8. package/dist/src/allocation/functions.js.map +1 -0
  9. package/dist/src/allocation/index.d.ts +2985 -0
  10. package/dist/src/allocation/index.d.ts.map +1 -0
  11. package/dist/src/allocation/index.js +499 -0
  12. package/dist/src/allocation/index.js.map +1 -0
  13. package/dist/src/allocation/types.d.ts +832 -0
  14. package/dist/src/allocation/types.d.ts.map +1 -0
  15. package/dist/src/allocation/types.js +360 -0
  16. package/dist/src/allocation/types.js.map +1 -0
  17. package/dist/src/bind/func.d.ts +14 -0
  18. package/dist/src/bind/func.d.ts.map +1 -1
  19. package/dist/src/bind/func.js +22 -1
  20. package/dist/src/bind/func.js.map +1 -1
  21. package/dist/src/calendar/index.d.ts +510 -1639
  22. package/dist/src/calendar/index.d.ts.map +1 -1
  23. package/dist/src/calendar/index.js +56 -29
  24. package/dist/src/calendar/index.js.map +1 -1
  25. package/dist/src/flowchart/canvas.d.ts +9 -21
  26. package/dist/src/flowchart/canvas.d.ts.map +1 -1
  27. package/dist/src/flowchart/canvas.js +10 -22
  28. package/dist/src/flowchart/canvas.js.map +1 -1
  29. package/dist/src/flowchart/flowchart.d.ts +19 -13
  30. package/dist/src/flowchart/flowchart.d.ts.map +1 -1
  31. package/dist/src/flowchart/flowchart.js.map +1 -1
  32. package/dist/src/flowchart/index.d.ts +44 -21
  33. package/dist/src/flowchart/index.d.ts.map +1 -1
  34. package/dist/src/flowchart/index.js +43 -20
  35. package/dist/src/flowchart/index.js.map +1 -1
  36. package/dist/src/flowchart/library.d.ts +166 -81
  37. package/dist/src/flowchart/library.d.ts.map +1 -1
  38. package/dist/src/flowchart/library.js +232 -105
  39. package/dist/src/flowchart/library.js.map +1 -1
  40. package/dist/src/flowchart/over.d.ts +9 -16
  41. package/dist/src/flowchart/over.d.ts.map +1 -1
  42. package/dist/src/flowchart/over.js +9 -16
  43. package/dist/src/flowchart/over.js.map +1 -1
  44. package/dist/src/flowchart/payload.d.ts +710 -508
  45. package/dist/src/flowchart/payload.d.ts.map +1 -1
  46. package/dist/src/flowchart/payload.js +128 -74
  47. package/dist/src/flowchart/payload.js.map +1 -1
  48. package/dist/src/flowchart/window.d.ts +132 -347
  49. package/dist/src/flowchart/window.d.ts.map +1 -1
  50. package/dist/src/flowchart/window.js +48 -55
  51. package/dist/src/flowchart/window.js.map +1 -1
  52. package/dist/src/index.d.ts +11 -7
  53. package/dist/src/index.d.ts.map +1 -1
  54. package/dist/src/index.js +14 -6
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/internal.d.ts +18 -7
  57. package/dist/src/internal.d.ts.map +1 -1
  58. package/dist/src/internal.js +28 -9
  59. package/dist/src/internal.js.map +1 -1
  60. package/dist/src/plan/event-rows.d.ts +26 -10
  61. package/dist/src/plan/event-rows.d.ts.map +1 -1
  62. package/dist/src/plan/event-rows.js +39 -13
  63. package/dist/src/plan/event-rows.js.map +1 -1
  64. package/dist/src/plan/ir.d.ts +244 -815
  65. package/dist/src/plan/ir.d.ts.map +1 -1
  66. package/dist/src/plan/ir.js +8 -6
  67. package/dist/src/plan/ir.js.map +1 -1
  68. package/dist/src/plan/library.d.ts +3 -0
  69. package/dist/src/plan/library.d.ts.map +1 -1
  70. package/dist/src/plan/library.js +1 -1
  71. package/dist/src/plan/library.js.map +1 -1
  72. package/dist/src/plan/ordered-source.d.ts +1 -0
  73. package/dist/src/plan/ordered-source.d.ts.map +1 -1
  74. package/dist/src/plan/plan.d.ts +559 -1667
  75. package/dist/src/plan/plan.d.ts.map +1 -1
  76. package/dist/src/plan/plan.js +123 -45
  77. package/dist/src/plan/plan.js.map +1 -1
  78. package/dist/src/plan/root.d.ts +16 -20
  79. package/dist/src/plan/root.d.ts.map +1 -1
  80. package/dist/src/plan/root.js +23 -33
  81. package/dist/src/plan/root.js.map +1 -1
  82. package/dist/src/roster/coverage.d.ts +17 -231
  83. package/dist/src/roster/coverage.d.ts.map +1 -1
  84. package/dist/src/roster/coverage.js +94 -90
  85. package/dist/src/roster/coverage.js.map +1 -1
  86. package/dist/src/roster/fit.d.ts +59 -0
  87. package/dist/src/roster/fit.d.ts.map +1 -0
  88. package/dist/src/roster/fit.js +155 -0
  89. package/dist/src/roster/fit.js.map +1 -0
  90. package/dist/src/roster/index.d.ts +2862 -3662
  91. package/dist/src/roster/index.d.ts.map +1 -1
  92. package/dist/src/roster/index.js +383 -81
  93. package/dist/src/roster/index.js.map +1 -1
  94. package/dist/src/roster/library.d.ts +37 -92
  95. package/dist/src/roster/library.d.ts.map +1 -1
  96. package/dist/src/roster/library.js +25 -64
  97. package/dist/src/roster/library.js.map +1 -1
  98. package/dist/src/roster/lists.d.ts +195 -0
  99. package/dist/src/roster/lists.d.ts.map +1 -0
  100. package/dist/src/roster/lists.js +233 -0
  101. package/dist/src/roster/lists.js.map +1 -0
  102. package/dist/src/roster/rules.d.ts +17 -260
  103. package/dist/src/roster/rules.d.ts.map +1 -1
  104. package/dist/src/roster/rules.js +135 -132
  105. package/dist/src/roster/rules.js.map +1 -1
  106. package/dist/src/roster/targets.d.ts +115 -0
  107. package/dist/src/roster/targets.d.ts.map +1 -0
  108. package/dist/src/roster/targets.js +213 -0
  109. package/dist/src/roster/targets.js.map +1 -0
  110. package/dist/src/roster/times.d.ts +251 -0
  111. package/dist/src/roster/times.d.ts.map +1 -0
  112. package/dist/src/roster/times.js +174 -0
  113. package/dist/src/roster/times.js.map +1 -0
  114. package/dist/src/roster/types.d.ts +828 -183
  115. package/dist/src/roster/types.d.ts.map +1 -1
  116. package/dist/src/roster/types.js +224 -97
  117. package/dist/src/roster/types.js.map +1 -1
  118. package/dist/src/schedule/accessor.d.ts +28 -0
  119. package/dist/src/schedule/accessor.d.ts.map +1 -0
  120. package/dist/src/schedule/accessor.js +39 -0
  121. package/dist/src/schedule/accessor.js.map +1 -0
  122. package/dist/src/schedule/events.d.ts +170 -42
  123. package/dist/src/schedule/events.d.ts.map +1 -1
  124. package/dist/src/schedule/events.js +431 -171
  125. package/dist/src/schedule/events.js.map +1 -1
  126. package/dist/src/schedule/index.d.ts +41 -4
  127. package/dist/src/schedule/index.d.ts.map +1 -1
  128. package/dist/src/schedule/index.js +35 -3
  129. package/dist/src/schedule/index.js.map +1 -1
  130. package/dist/src/schedule/library.d.ts +13 -3
  131. package/dist/src/schedule/library.d.ts.map +1 -1
  132. package/dist/src/schedule/library.js +11 -4
  133. package/dist/src/schedule/library.js.map +1 -1
  134. package/dist/src/schedule/periods.d.ts +115 -0
  135. package/dist/src/schedule/periods.d.ts.map +1 -0
  136. package/dist/src/schedule/periods.js +215 -0
  137. package/dist/src/schedule/periods.js.map +1 -0
  138. package/dist/src/schedule/record-window.d.ts +25 -3
  139. package/dist/src/schedule/record-window.d.ts.map +1 -1
  140. package/dist/src/schedule/record-window.js +31 -18
  141. package/dist/src/schedule/record-window.js.map +1 -1
  142. package/dist/src/schedule/resources.d.ts +82 -4
  143. package/dist/src/schedule/resources.d.ts.map +1 -1
  144. package/dist/src/schedule/resources.js +44 -14
  145. package/dist/src/schedule/resources.js.map +1 -1
  146. package/dist/src/schedule/session.d.ts +69 -0
  147. package/dist/src/schedule/session.d.ts.map +1 -0
  148. package/dist/src/schedule/session.js +121 -0
  149. package/dist/src/schedule/session.js.map +1 -0
  150. package/dist/src/schedule/templates.d.ts +14 -2
  151. package/dist/src/schedule/templates.d.ts.map +1 -1
  152. package/dist/src/schedule/templates.js +5 -3
  153. package/dist/src/schedule/templates.js.map +1 -1
  154. package/dist/src/schedule/types.d.ts +1671 -37
  155. package/dist/src/schedule/types.d.ts.map +1 -1
  156. package/dist/src/schedule/types.js +196 -5
  157. package/dist/src/schedule/types.js.map +1 -1
  158. package/dist/src/schedule/window.d.ts +14 -0
  159. package/dist/src/schedule/window.d.ts.map +1 -1
  160. package/dist/src/schedule/window.js +14 -4
  161. package/dist/src/schedule/window.js.map +1 -1
  162. package/dist/src/schedule/words.d.ts +22 -0
  163. package/dist/src/schedule/words.d.ts.map +1 -0
  164. package/dist/src/schedule/words.js +25 -0
  165. package/dist/src/schedule/words.js.map +1 -0
  166. package/dist/src/sheet/index.d.ts +61 -27
  167. package/dist/src/sheet/index.d.ts.map +1 -1
  168. package/dist/src/sheet/index.js +59 -25
  169. package/dist/src/sheet/index.js.map +1 -1
  170. package/dist/src/sheet/library.d.ts +21 -3
  171. package/dist/src/sheet/library.d.ts.map +1 -1
  172. package/dist/src/sheet/library.js +23 -6
  173. package/dist/src/sheet/library.js.map +1 -1
  174. package/dist/src/sheet/registers.d.ts +100 -85
  175. package/dist/src/sheet/registers.d.ts.map +1 -1
  176. package/dist/src/sheet/registers.js +100 -85
  177. package/dist/src/sheet/registers.js.map +1 -1
  178. package/dist/src/sheet/root.d.ts +8 -12
  179. package/dist/src/sheet/root.d.ts.map +1 -1
  180. package/dist/src/sheet/root.js +6 -40
  181. package/dist/src/sheet/root.js.map +1 -1
  182. package/dist/src/sheet/sheet.d.ts +598 -2349
  183. package/dist/src/sheet/sheet.d.ts.map +1 -1
  184. package/dist/src/sheet/sheet.js +124 -37
  185. package/dist/src/sheet/sheet.js.map +1 -1
  186. package/dist/src/sheet/sub-rows.d.ts +74 -28
  187. package/dist/src/sheet/sub-rows.d.ts.map +1 -1
  188. package/dist/src/sheet/sub-rows.js +74 -28
  189. package/dist/src/sheet/sub-rows.js.map +1 -1
  190. package/dist/src/sheet/templates.d.ts +98 -34
  191. package/dist/src/sheet/templates.d.ts.map +1 -1
  192. package/dist/src/sheet/templates.js +102 -58
  193. package/dist/src/sheet/templates.js.map +1 -1
  194. package/dist/src/sheet/types.d.ts +289 -1359
  195. package/dist/src/sheet/types.d.ts.map +1 -1
  196. package/dist/src/sheet/types.js +20 -26
  197. package/dist/src/sheet/types.js.map +1 -1
  198. package/dist/src/sheet/views.d.ts +10 -11
  199. package/dist/src/sheet/views.d.ts.map +1 -1
  200. package/dist/src/sheet/views.js +15 -20
  201. package/dist/src/sheet/views.js.map +1 -1
  202. package/dist/src/{roster/visibility.d.ts → utils/key-visibility.d.ts} +42 -7
  203. package/dist/src/utils/key-visibility.d.ts.map +1 -0
  204. package/dist/src/utils/key-visibility.js +36 -0
  205. package/dist/src/utils/key-visibility.js.map +1 -0
  206. package/dist/src/utils/ordered-source.d.ts +1 -0
  207. package/dist/src/utils/ordered-source.d.ts.map +1 -1
  208. package/dist/src/utils/ordered-source.js +8 -3
  209. package/dist/src/utils/ordered-source.js.map +1 -1
  210. package/dist/src/utils/record-sources.d.ts +107 -0
  211. package/dist/src/utils/record-sources.d.ts.map +1 -0
  212. package/dist/src/utils/record-sources.js +132 -0
  213. package/dist/src/utils/record-sources.js.map +1 -0
  214. package/dist/test/allocation/allocation.examples.d.ts +2902 -0
  215. package/dist/test/allocation/allocation.examples.d.ts.map +1 -0
  216. package/dist/test/allocation/allocation.examples.js +643 -0
  217. package/dist/test/allocation/allocation.examples.js.map +1 -0
  218. package/dist/test/allocation/fit.examples.d.ts +546 -0
  219. package/dist/test/allocation/fit.examples.d.ts.map +1 -0
  220. package/dist/test/allocation/fit.examples.js +171 -0
  221. package/dist/test/allocation/fit.examples.js.map +1 -0
  222. package/dist/test/allocation/kiln-yard.d.ts +181 -0
  223. package/dist/test/allocation/kiln-yard.d.ts.map +1 -0
  224. package/dist/test/allocation/kiln-yard.js +228 -0
  225. package/dist/test/allocation/kiln-yard.js.map +1 -0
  226. package/dist/test/bind/data/data.examples.d.ts +651 -1
  227. package/dist/test/bind/data/data.examples.d.ts.map +1 -1
  228. package/dist/test/bind/data/data.examples.js +140 -2
  229. package/dist/test/bind/data/data.examples.js.map +1 -1
  230. package/dist/test/bind/func/func.examples.d.ts +10 -1
  231. package/dist/test/bind/func/func.examples.d.ts.map +1 -1
  232. package/dist/test/bind/func/func.examples.js +8 -1
  233. package/dist/test/bind/func/func.examples.js.map +1 -1
  234. package/dist/test/bind/record/record.examples.d.ts +633 -1
  235. package/dist/test/bind/record/record.examples.d.ts.map +1 -1
  236. package/dist/test/bind/record/record.examples.js +26 -2
  237. package/dist/test/bind/record/record.examples.js.map +1 -1
  238. package/dist/test/calendar/calendar-records.examples.d.ts.map +1 -1
  239. package/dist/test/calendar/calendar-records.examples.js +18 -14
  240. package/dist/test/calendar/calendar-records.examples.js.map +1 -1
  241. package/dist/test/calendar/calendar.examples.d.ts +521 -16
  242. package/dist/test/calendar/calendar.examples.d.ts.map +1 -1
  243. package/dist/test/calendar/calendar.examples.js +182 -135
  244. package/dist/test/calendar/calendar.examples.js.map +1 -1
  245. package/dist/test/examples-package.d.ts +75 -0
  246. package/dist/test/examples-package.d.ts.map +1 -0
  247. package/dist/test/examples-package.js +263 -0
  248. package/dist/test/examples-package.js.map +1 -0
  249. package/dist/test/flowchart/flowchart.examples.d.ts +211 -19
  250. package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -1
  251. package/dist/test/flowchart/flowchart.examples.js +102 -75
  252. package/dist/test/flowchart/flowchart.examples.js.map +1 -1
  253. package/dist/test/plan/plan-events.examples.d.ts +1439 -209
  254. package/dist/test/plan/plan-events.examples.d.ts.map +1 -1
  255. package/dist/test/plan/plan-events.examples.js +199 -59
  256. package/dist/test/plan/plan-events.examples.js.map +1 -1
  257. package/dist/test/plan/plan-records.examples.d.ts +420 -0
  258. package/dist/test/plan/plan-records.examples.d.ts.map +1 -1
  259. package/dist/test/plan/plan-records.examples.js +70 -19
  260. package/dist/test/plan/plan-records.examples.js.map +1 -1
  261. package/dist/test/plan/plan-windows.examples.d.ts +636 -55
  262. package/dist/test/plan/plan-windows.examples.d.ts.map +1 -1
  263. package/dist/test/plan/plan-windows.examples.js +69 -33
  264. package/dist/test/plan/plan-windows.examples.js.map +1 -1
  265. package/dist/test/plan/plan.examples.d.ts +153 -31
  266. package/dist/test/plan/plan.examples.d.ts.map +1 -1
  267. package/dist/test/plan/plan.examples.js +178 -101
  268. package/dist/test/plan/plan.examples.js.map +1 -1
  269. package/dist/test/roster/domain.examples.d.ts +467 -250
  270. package/dist/test/roster/domain.examples.d.ts.map +1 -1
  271. package/dist/test/roster/domain.examples.js +92 -29
  272. package/dist/test/roster/domain.examples.js.map +1 -1
  273. package/dist/test/roster/roster-records.examples.d.ts +430 -586
  274. package/dist/test/roster/roster-records.examples.d.ts.map +1 -1
  275. package/dist/test/roster/roster-records.examples.js +102 -43
  276. package/dist/test/roster/roster-records.examples.js.map +1 -1
  277. package/dist/test/roster/roster.examples.d.ts +2319 -606
  278. package/dist/test/roster/roster.examples.d.ts.map +1 -1
  279. package/dist/test/roster/roster.examples.js +456 -148
  280. package/dist/test/roster/roster.examples.js.map +1 -1
  281. package/dist/test/roster/warehouse.d.ts +172 -63
  282. package/dist/test/roster/warehouse.d.ts.map +1 -1
  283. package/dist/test/roster/warehouse.js +172 -39
  284. package/dist/test/roster/warehouse.js.map +1 -1
  285. package/dist/test/schedule/schedule.examples.d.ts +3499 -0
  286. package/dist/test/schedule/schedule.examples.d.ts.map +1 -0
  287. package/dist/test/schedule/schedule.examples.js +192 -0
  288. package/dist/test/schedule/schedule.examples.js.map +1 -0
  289. package/dist/test/sheet/sheet-records.examples.d.ts.map +1 -1
  290. package/dist/test/sheet/sheet-records.examples.js +22 -18
  291. package/dist/test/sheet/sheet-records.examples.js.map +1 -1
  292. package/dist/test/sheet/sheet.examples.d.ts +715 -26
  293. package/dist/test/sheet/sheet.examples.d.ts.map +1 -1
  294. package/dist/test/sheet/sheet.examples.js +204 -130
  295. package/dist/test/sheet/sheet.examples.js.map +1 -1
  296. package/package.json +17 -10
  297. package/dist/src/roster/people.d.ts +0 -50
  298. package/dist/src/roster/people.d.ts.map +0 -1
  299. package/dist/src/roster/people.js +0 -32
  300. package/dist/src/roster/people.js.map +0 -1
  301. package/dist/src/roster/visibility.d.ts.map +0 -1
  302. package/dist/src/roster/visibility.js +0 -25
  303. package/dist/src/roster/visibility.js.map +0 -1
@@ -0,0 +1,643 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@elaraai/e3-ui/jsx-runtime";
2
+ /**
3
+ * Copyright (c) 2025 Elara AI Pty Ltd
4
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
5
+ */
6
+ /** @jsxImportSource @elaraai/e3-ui */
7
+ import { ArrayType, DateTimeType, DictType, East, FunctionType, NullType, PatchType, StringType, example, none, some, variant } from "@elaraai/east";
8
+ import e3 from "@elaraai/e3";
9
+ import { Box, Field, Reactive, Slice, UIComponentType, VStack } from "@elaraai/east-ui";
10
+ import { Allocation, Data, Func, Record, Schedule } from "@elaraai/e3-ui";
11
+ import { Bay, Kiln, KilnBin, MinimalBin, TimberLoad, YardDay, yardArrivals, yardBayRows, yardBinHistoryRows, yardBinRows, yardDay, yardDayHistoryRows, yardDayRows, yardKilns, yardMinimalBinRows, yardPublishedDay, yardSplitDay, } from "./kiln-yard.js";
12
+ // The kiln yard's own records (`Builder Interfaces Spec.md` §6.5): its bins and the days of its plan, which the board
13
+ // writes, each through its patch door; and what it reads — its kilns, its loads and its bays.
14
+ /** The bins, every day's, each the yard's own row. */
15
+ export const kilnBins = e3.record("kiln_bins", DictType(StringType, KilnBin), yardBinRows);
16
+ export const kilnBinsPatch = e3.mutation.patch(kilnBins);
17
+ /** The bins by their time: what the board's slice reads a day of them through, its navigation writing the range. */
18
+ export const kilnBinsByTime = e3.recordIndex("kiln_bins_by_time", kilnBins, { interval: { from: "at", to: "at" } });
19
+ /** The days of the yard's plan, what the board publishes: Tue 4 May issued, Tue 11 and Wed 12 drafts. */
20
+ export const yardDays = e3.record("yard_days", DictType(DateTimeType, YardDay), yardDayRows);
21
+ export const yardDaysPatch = e3.mutation.patch(yardDays);
22
+ /** The same bins, locked for the day: their door, a checked one, refuses every change, naming why — what a Save over it is answered. */
23
+ export const kilnLockedBins = e3.record("kiln_locked_bins", DictType(StringType, KilnBin), yardBinRows);
24
+ export const kilnLockedBinsByTime = e3.recordIndex("kiln_locked_bins_by_time", kilnLockedBins, { interval: { from: "at", to: "at" } });
25
+ export const kilnLockedBinsPatch = e3.mutation.reduce("patch", kilnLockedBins, East.function([DictType(StringType, KilnBin), PatchType(DictType(StringType, KilnBin))], DictType(StringType, KilnBin), ($, bins, _patch) => {
26
+ $.error("the yard's bins are locked for the day");
27
+ return bins;
28
+ }));
29
+ /** The same days, locked: the site office issues them, and their door refuses every change, naming why. */
30
+ export const yardLockedDays = e3.record("yard_locked_days", DictType(DateTimeType, YardDay), yardDayRows);
31
+ export const yardLockedDaysPatch = e3.mutation.reduce("patch", yardLockedDays, East.function([DictType(DateTimeType, YardDay), PatchType(DictType(DateTimeType, YardDay))], DictType(DateTimeType, YardDay), ($, days, _patch) => {
32
+ $.error("the site office issues the yard's days");
33
+ return days;
34
+ }));
35
+ /** Two years of the yard's bins, for the board read a day at a time through its slice. */
36
+ export const kilnBinHistory = e3.record("kiln_bin_history", DictType(StringType, KilnBin), yardBinHistoryRows);
37
+ export const kilnBinHistoryPatch = e3.mutation.patch(kilnBinHistory);
38
+ export const kilnBinHistoryByTime = e3.recordIndex("kiln_bin_history_by_time", kilnBinHistory, { interval: { from: "at", to: "at" } });
39
+ /** The days of those two years, read by key. */
40
+ export const yardDayHistory = e3.record("yard_day_history", DictType(DateTimeType, YardDay), yardDayHistoryRows);
41
+ export const yardDayHistoryPatch = e3.mutation.patch(yardDayHistory);
42
+ // The kilns, indexed by group for the narrowing; and by group then max, so a group and a range of max combine, and by name, for a search.
43
+ export const kilns = e3.record("kilns", DictType(StringType, Kiln), yardKilns);
44
+ export const kilnsByGroup = e3.recordIndex("kilns_by_group", kilns, { on: ["group"] });
45
+ export const kilnsByGroupMax = e3.recordIndex("kilns_by_group_max", kilns, { on: ["group", "max"] });
46
+ export const kilnsByName = e3.recordIndex("kilns_by_name", kilns, { on: ["name"] });
47
+ // The kilns' patch door: another session's edit of the yard's kilns, as the renderer's tests on e3 commit it (#1376).
48
+ export const kilnsPatch = e3.mutation.patch(kilns);
49
+ // Every load the day may book: booked or not, the board tells them apart by its bins; indexed by spec for the narrowing.
50
+ export const arrivals = e3.record("arrivals", DictType(StringType, TimberLoad), yardArrivals);
51
+ export const arrivalsBySpec = e3.recordIndex("arrivals_by_spec", arrivals, { on: ["spec"] });
52
+ // The unloading bays, by key: each takes one bin an hour, at its offset past the hour; indexed by area, and by cover, for the narrowing.
53
+ export const yardBays = e3.record("yard_bays", DictType(StringType, Bay), yardBayRows);
54
+ export const yardBaysByArea = e3.recordIndex("yard_bays_by_area", yardBays, { on: ["area"] });
55
+ export const yardBaysByCover = e3.recordIndex("yard_bays_by_cover", yardBays, { on: ["cover"] });
56
+ // The smallest board's own bins (§6.5): the board's roles alone.
57
+ export const minimalBins = e3.record("kiln_minimal_bins", DictType(StringType, MinimalBin), yardMinimalBinRows);
58
+ export const minimalBinsPatch = e3.mutation.patch(minimalBins);
59
+ /** The yard's fit's body: the built-in rules, then a greedy look-ahead over the day's other loads. */
60
+ export const yardFitBody = East.function([Allocation.Types.FitRequest(KilnBin)], Allocation.Types.FitResult, ($, req) => {
61
+ const answer = $.const(Allocation.answer(KilnBin));
62
+ const rule = $.const(Allocation.fit);
63
+ const ahead = $.const(Allocation.lookahead(KilnBin));
64
+ return answer(req, East.function([Allocation.Types.Candidate], Allocation.Types.Fit, (_$2, c) => ahead(req, c, rule)), "ranked by load, kind and spare days, and what it leaves for the day's other loads");
65
+ });
66
+ // The yard's fit, on e3: a fit that leaves more of the day's unbooked loads with nowhere to go ranks lower.
67
+ export const yardFit = e3.function("yard_fit", yardFitBody);
68
+ /** A yard rule over the ready-made fit: a bulk kiln takes no load under 20 m³. */
69
+ export const bulkFitBody = East.function([Allocation.Types.FitRequest(KilnBin)], Allocation.Types.FitResult, ($, req) => {
70
+ const answer = $.const(Allocation.answer(KilnBin));
71
+ const rule = $.const(Allocation.fit);
72
+ return answer(req, East.function([Allocation.Types.Candidate], Allocation.Types.Fit, ($2, c) => {
73
+ $2.if(East.equal(c.resource.group, some("Bulk")).and(() => c.reserve.not()).and(() => East.less(c.quantity, 20.0)), ($3) => {
74
+ $3.return(variant("refused", { group: "Too small", reason: East.str `bulk kilns take 20 m³ and more`, measure: variant("none", null) }));
75
+ });
76
+ return rule(c);
77
+ }), "ranked by load, kind and spare days; bulk kilns take 20 m³ and more");
78
+ });
79
+ export const bulkFit = e3.function("yard_bulk_fit", bulkFitBody);
80
+ /** The smallest board's fit's body (§6.5): the built-in rules over its own bins. */
81
+ export const minimalFitBody = East.function([Allocation.Types.FitRequest(MinimalBin)], Allocation.Types.FitResult, ($, req) => {
82
+ const answer = $.const(Allocation.answer(MinimalBin));
83
+ const rule = $.const(Allocation.fit);
84
+ return answer(req, rule, "ranked by load, kind and spare days");
85
+ });
86
+ export const minimalFit = e3.function("yard_minimal_fit", minimalFitBody);
87
+ export const allocationMinimal = example({
88
+ description: "The smallest board over the app's own records: bins with only the board's roles — their bay, time, load, m³, split across kilns and drying time — the bays, the kilns and the day's loads, and the yard's fit on e3. No library, no inspector and no Publish; every gesture is still a draft until Save.",
89
+ keywords: ["Allocation", "Schedule.events", "Schedule.resources", "Allocation.arrivals", "Record.bind", "Func.bind", "e3.function", "fit", "minimal", "BuilderFrame", "Save"], inputs: [],
90
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
91
+ const bins = $.let(Record.bind(minimalBins, [minimalBinsPatch]));
92
+ const loads = $.let(Data.bind(arrivals));
93
+ const yard = $.let(Data.bind(kilns));
94
+ const bays = $.let(Data.bind(yardBays));
95
+ const fit = $.let(Func.bind(minimalFit));
96
+ return _jsx(Box, { width: "100%", height: "760px", children: _jsx(Allocation, { id: "allocationMinimal", fit: fit, view: { date: yardDay }, events: { bin: Schedule.events(bins, {
97
+ name: "Bin", icon: "box",
98
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
99
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor",
100
+ }) }, resources: {
101
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
102
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, min: k => k.min, max: k => k.max, jobs: k => k.charges }),
103
+ }, arrivals: Allocation.arrivals(loads.read(), { label: l => l.code, quantity: l => l.m3, hold: l => variant("days", l.dryingDays) }) }) });
104
+ } })),
105
+ });
106
+ export const allocationKilnYard = example({
107
+ description: "The kiln yard's board over its own records: its bins, each with the yard's spec and grade beside the board's roles, read a day at a time through the slice; the days it publishes; a check over the bins' own fields; the rail over the bays, the kilns and the loads — each source with its icon, and each narrowing every place its rows appear, the Library's tabs included; the yard's fields as columns; the Arrivals and Resources library; the inspector; and the yard's greedy fit on e3.",
108
+ keywords: ["Allocation", "Schedule.events", "Schedule.resources", "Schedule.periods", "Allocation.arrivals", "Slice.bindRecords", "Data.bindPaged", "Func.bind", "fit", "check", "columns", "links", "Publish", "Library", "narrowing"], inputs: [],
109
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
110
+ // What the board writes: the bins and the days of the plan, each through its patch door.
111
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
112
+ const entries = $.let(Data.bindPaged(kilnBins));
113
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
114
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
115
+ // Every bay, kiln and load is the calculation scope; the narrowing only chooses which show.
116
+ const yard = $.let(Data.bind(kilns));
117
+ const loads = $.let(Data.bind(arrivals));
118
+ const bays = $.let(Data.bind(yardBays));
119
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea, yardBaysByCover] }));
120
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroupMax, kilnsByName] }));
121
+ const loadIndex = $.let(Data.bindPaged(arrivals, { indexes: [arrivalsBySpec] }));
122
+ const slice = $.let(Slice.bindRecords("ex.allocationKilnYard", {
123
+ // The day's bins: the board's navigation writes the range; no chip picks the day.
124
+ bin: { source: byTime, range: "at" },
125
+ bays: { source: bayIndex, icon: { prefix: "fas", name: "warehouse" },
126
+ fields: { area: { label: "Area", hints: ["North", "South"] }, cover: { label: "Cover", hints: ["Covered", "Open"] } } },
127
+ // A max narrows within a group (one index on group, then max); a name is searched by its start.
128
+ kilns: { source: kilnIndex, icon: { prefix: "fas", name: "fire" },
129
+ fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] }, max: { label: "Max m³" }, name: { label: "Name" } } },
130
+ arrivals: { source: loadIndex, icon: { prefix: "fas", name: "truck" }, fields: { spec: { label: "Spec", hints: ["MC08", "MC10", "MC12", "MC14", "MC16", "MC18", "MC20", "MC22"] } } },
131
+ }, {
132
+ presets: [
133
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
134
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
135
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
136
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
137
+ ],
138
+ }));
139
+ const fit = $.let(Func.bind(yardFit));
140
+ // The yard's check reads its own fields: a bin measured off its booked spec is flagged, never refused.
141
+ const check = $.const(East.function([Allocation.Types.CheckContext(KilnBin)], ArrayType(Allocation.Types.Issue), ($2, cx) => {
142
+ const issues = $2.let([], ArrayType(Allocation.Types.Issue));
143
+ $2.for(cx.plan.bins, ($3, bin, id) => {
144
+ $3.match(bin.arrival, { some: ($4, code) => {
145
+ $4.if(East.notEqual(bin.row.specBooked, bin.row.specMeasured), ($5) => {
146
+ $5(issues.pushLast({ kind: variant("custom", "Spec mismatch"), tone: variant("neutral", null),
147
+ title: East.str `${code} · bin ${id}`,
148
+ detail: East.str `Spec booked ${bin.row.specBooked} · measured ${bin.row.specMeasured} · ${bin.lane} ${bin.at.printFormatted("HH:mm")}`,
149
+ bin: some(id), resource: none, flag: some("≠ spec"), fix: none }));
150
+ });
151
+ } });
152
+ });
153
+ return issues;
154
+ }));
155
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationKilnYard", title: "Kiln loading", fit: fit, check: check, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardDay }, events: { bin: Schedule.events(bins, {
156
+ name: "Bin", icon: "box", entries,
157
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
158
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
159
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
160
+ }) }, resources: {
161
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
162
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
163
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
164
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
165
+ }, arrivals: Allocation.arrivals(loads.read(), {
166
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
167
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
168
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
169
+ details: l => [{ label: "Settings", value: l.schedule }],
170
+ // A booked bin's own fields: the ones no role maps.
171
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
172
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
173
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
174
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
175
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
176
+ ] }) });
177
+ } })),
178
+ });
179
+ export const allocationTable = example({
180
+ description: "The kiln yard as a Table: one row per bay slot and one per extra bin of a batch, in four foldable time bands, narrowed by the bays' area or cover, the kilns' group, max or name, and the loads' spec; the same drafts, library and inspector as the Timeline.",
181
+ keywords: ["Allocation", "Table", "Schedule.events", "Schedule.resources", "Schedule.periods", "Allocation.arrivals", "Func.bind", "columns", "Chooser", "Slice.bindRecords"], inputs: [],
182
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
183
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
184
+ const entries = $.let(Data.bindPaged(kilnBins));
185
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
186
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
187
+ // Every bay, kiln and load is the calculation scope; the narrowing only chooses which show.
188
+ const yard = $.let(Data.bind(kilns));
189
+ const loads = $.let(Data.bind(arrivals));
190
+ const bays = $.let(Data.bind(yardBays));
191
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea, yardBaysByCover] }));
192
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroupMax, kilnsByName] }));
193
+ const loadIndex = $.let(Data.bindPaged(arrivals, { indexes: [arrivalsBySpec] }));
194
+ const slice = $.let(Slice.bindRecords("ex.allocationTable", {
195
+ bin: { source: byTime, range: "at" },
196
+ bays: { source: bayIndex, icon: { prefix: "fas", name: "warehouse" },
197
+ fields: { area: { label: "Area", hints: ["North", "South"] }, cover: { label: "Cover", hints: ["Covered", "Open"] } } },
198
+ // A max narrows within a group (one index on group, then max); a name is searched by its start.
199
+ kilns: { source: kilnIndex, icon: { prefix: "fas", name: "fire" },
200
+ fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] }, max: { label: "Max m³" }, name: { label: "Name" } } },
201
+ arrivals: { source: loadIndex, icon: { prefix: "fas", name: "truck" }, fields: { spec: { label: "Spec", hints: ["MC08", "MC10", "MC12", "MC14", "MC16", "MC18", "MC20", "MC22"] } } },
202
+ }, {
203
+ presets: [
204
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
205
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
206
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
207
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
208
+ ],
209
+ }));
210
+ const fit = $.let(Func.bind(yardFit));
211
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationTable", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "table", date: yardDay }, events: { bin: Schedule.events(bins, {
212
+ name: "Bin", icon: "box", entries,
213
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
214
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
215
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
216
+ }) }, resources: {
217
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
218
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
219
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
220
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
221
+ }, arrivals: Allocation.arrivals(loads.read(), {
222
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
223
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
224
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
225
+ details: l => [{ label: "Settings", value: l.schedule }],
226
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
227
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
228
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
229
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
230
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
231
+ ] }) });
232
+ } })),
233
+ });
234
+ export const allocationLabels = example({
235
+ description: "The kiln yard in its own words: labels={{ lane: \"Bay\", arrival: { one: \"Delivery\", other: \"Deliveries\" }, resource: \"Kiln\", quantity: \"Vol\" }} names the board's lanes, arrivals, resources and quantity everywhere it writes them — the Table's heads, the Chooser, the placeholders, the drag captions, the banners and the narrowing's summary — and table={{ bands }} sets the Table's time bands to the yard's shifts.",
236
+ keywords: ["Allocation", "labels", "nouns", "arrival", "Table", "bands", "Schedule.events", "Allocation.arrivals", "Func.bind"], inputs: [],
237
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
238
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
239
+ const entries = $.let(Data.bindPaged(kilnBins));
240
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
241
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
242
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
243
+ const yard = $.let(Data.bind(kilns));
244
+ const loads = $.let(Data.bind(arrivals));
245
+ const bays = $.let(Data.bind(yardBays));
246
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
247
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
248
+ const slice = $.let(Slice.bindRecords("ex.allocationLabels", {
249
+ bin: { source: byTime, range: "at" },
250
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
251
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
252
+ }, {
253
+ presets: [
254
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
255
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
256
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
257
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
258
+ ],
259
+ }));
260
+ const fit = $.let(Func.bind(yardFit));
261
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationLabels", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "table", date: yardDay }, labels: { lane: "Bay", arrival: { one: "Delivery", other: "Deliveries" }, resource: "Kiln", quantity: "Vol" }, table: { bands: [{ from: 0, label: "Night" }, { from: 6, label: "Day shift" }, { from: 18, label: "Evening" }] }, events: { bin: Schedule.events(bins, {
262
+ name: "Bin", icon: "box", entries,
263
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
264
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
265
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
266
+ }) }, resources: {
267
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
268
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
269
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
270
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
271
+ }, arrivals: Allocation.arrivals(loads.read(), {
272
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
273
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
274
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
275
+ details: l => [{ label: "Settings", value: l.schedule }],
276
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
277
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
278
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
279
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
280
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
281
+ ] }) });
282
+ } })),
283
+ });
284
+ export const allocationPublished = example({
285
+ description: "A published day, Tue 4 May, its status the yard's own day issued: read-only under its banner; navigation, the narrowing, the focus, links and the inspector still work.",
286
+ keywords: ["Allocation", "Schedule.periods", "Publish", "published", "readOnly", "Record.bind"], inputs: [],
287
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
288
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
289
+ const entries = $.let(Data.bindPaged(kilnBins));
290
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
291
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
292
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
293
+ const yard = $.let(Data.bind(kilns));
294
+ const loads = $.let(Data.bind(arrivals));
295
+ const bays = $.let(Data.bind(yardBays));
296
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
297
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
298
+ const slice = $.let(Slice.bindRecords("ex.allocationPublished", {
299
+ bin: { source: byTime, range: "at" },
300
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
301
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
302
+ }, {
303
+ presets: [
304
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
305
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
306
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
307
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
308
+ ],
309
+ }));
310
+ const fit = $.let(Func.bind(yardFit));
311
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationPublished", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardPublishedDay }, events: { bin: Schedule.events(bins, {
312
+ name: "Bin", icon: "box", entries,
313
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
314
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
315
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
316
+ }) }, resources: {
317
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
318
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
319
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
320
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
321
+ }, arrivals: Allocation.arrivals(loads.read(), {
322
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
323
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
324
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
325
+ details: l => [{ label: "Settings", value: l.schedule }],
326
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
327
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
328
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
329
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
330
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
331
+ ] }) });
332
+ } })),
333
+ });
334
+ export const allocationNoPublish = example({
335
+ description: "The kiln yard with no `periods`: no status chip and no Publish; Save writes the day's bins as drafts.",
336
+ keywords: ["Allocation", "periods", "publish", "Save", "Schedule.events", "Record.bind"], inputs: [],
337
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
338
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
339
+ const entries = $.let(Data.bindPaged(kilnBins));
340
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
341
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
342
+ const yard = $.let(Data.bind(kilns));
343
+ const loads = $.let(Data.bind(arrivals));
344
+ const bays = $.let(Data.bind(yardBays));
345
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
346
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
347
+ const slice = $.let(Slice.bindRecords("ex.allocationNoPublish", {
348
+ bin: { source: byTime, range: "at" },
349
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
350
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
351
+ }, {
352
+ presets: [
353
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
354
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
355
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
356
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
357
+ ],
358
+ }));
359
+ const fit = $.let(Func.bind(yardFit));
360
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationNoPublish", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardDay }, events: { bin: Schedule.events(bins, {
361
+ name: "Bin", icon: "box", entries,
362
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
363
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
364
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
365
+ }) }, resources: {
366
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
367
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
368
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
369
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
370
+ }, arrivals: Allocation.arrivals(loads.read(), {
371
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
372
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
373
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
374
+ details: l => [{ label: "Settings", value: l.schedule }],
375
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
376
+ }), columns: [
377
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
378
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
379
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
380
+ ] }) });
381
+ } })),
382
+ });
383
+ export const allocationSplit = example({
384
+ description: "Loads split across kilns on Wed 12 May: each bin's parts on their kilns, one load with 4 m³ unallocated and its Partly allocated issue, and a link to each part.",
385
+ keywords: ["Allocation", "split", "parts", "unallocated", "Find a fit", "links", "Schedule.events"], inputs: [],
386
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
387
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
388
+ const entries = $.let(Data.bindPaged(kilnBins));
389
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
390
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
391
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
392
+ const yard = $.let(Data.bind(kilns));
393
+ const loads = $.let(Data.bind(arrivals));
394
+ const bays = $.let(Data.bind(yardBays));
395
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
396
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
397
+ const slice = $.let(Slice.bindRecords("ex.allocationSplit", {
398
+ bin: { source: byTime, range: "at" },
399
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
400
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
401
+ }, {
402
+ presets: [
403
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
404
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
405
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
406
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
407
+ ],
408
+ }));
409
+ const fit = $.let(Func.bind(yardFit));
410
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationSplit", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardSplitDay }, events: { bin: Schedule.events(bins, {
411
+ name: "Bin", icon: "box", entries,
412
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
413
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
414
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
415
+ }) }, resources: {
416
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
417
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
418
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
419
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
420
+ }, arrivals: Allocation.arrivals(loads.read(), {
421
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
422
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
423
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
424
+ details: l => [{ label: "Settings", value: l.schedule }],
425
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
426
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
427
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
428
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
429
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
430
+ ] }) });
431
+ } })),
432
+ });
433
+ export const allocationWindowed = example({
434
+ description: "Two years of bins read a day at a time through the slice's bin source — an interval index over their times, its range the board's own navigation — and the plan's days by key: only the active day and the open picker's month are requested, never a record whole.",
435
+ keywords: ["Allocation", "Schedule.events", "Schedule.periods", "Slice.bindRecords", "Data.bindPaged", "recordIndex", "interval", "history", "entries", "BuilderFrame", "Save", "Publish"], inputs: [],
436
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
437
+ const bins = $.let(Record.bind(kilnBinHistory, [kilnBinHistoryPatch]));
438
+ const entries = $.let(Data.bindPaged(kilnBinHistory));
439
+ const byTime = $.let(Data.bindPaged(kilnBinHistory, { indexes: [kilnBinHistoryByTime] }));
440
+ // The days of the plan read by key: the day, and the open picker's month.
441
+ const days = $.let(Record.bind(yardDayHistory, [yardDayHistoryPatch]));
442
+ const dayEntries = $.let(Data.bindPaged(yardDayHistory));
443
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
444
+ const yard = $.let(Data.bind(kilns));
445
+ const loads = $.let(Data.bind(arrivals));
446
+ const bays = $.let(Data.bind(yardBays));
447
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
448
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
449
+ const slice = $.let(Slice.bindRecords("ex.allocationWindowed", {
450
+ // The day's bins: the board's navigation writes the range.
451
+ bin: { source: byTime, range: "at" },
452
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
453
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
454
+ }, {
455
+ presets: [
456
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
457
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
458
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
459
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
460
+ ],
461
+ }));
462
+ const fit = $.let(Func.bind(yardFit));
463
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationWindowed", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardDay }, events: { bin: Schedule.events(bins, {
464
+ name: "Bin", icon: "box", entries,
465
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
466
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
467
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
468
+ }) }, resources: {
469
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
470
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
471
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
472
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
473
+ }, arrivals: Allocation.arrivals(loads.read(), {
474
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
475
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
476
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
477
+ details: l => [{ label: "Settings", value: l.schedule }],
478
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
479
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" }, entries: dayEntries }), columns: [
480
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
481
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
482
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
483
+ ] }) });
484
+ } })),
485
+ });
486
+ export const allocationMobile = example({
487
+ description: "The kiln yard in a 390px container: a card per kiln (or per slot in the Table) with Book, Reserve, Allocate, Unlink and Back to Arrivals in anchored popovers; no drag source or target.",
488
+ keywords: ["Allocation", "mobile", "narrow", "cards", "Schedule.events", "Record.bind"], inputs: [],
489
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
490
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
491
+ const entries = $.let(Data.bindPaged(kilnBins));
492
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
493
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
494
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
495
+ const yard = $.let(Data.bind(kilns));
496
+ const loads = $.let(Data.bind(arrivals));
497
+ const bays = $.let(Data.bind(yardBays));
498
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
499
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
500
+ const slice = $.let(Slice.bindRecords("ex.allocationMobile", {
501
+ bin: { source: byTime, range: "at" },
502
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
503
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
504
+ }, {
505
+ presets: [
506
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
507
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
508
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
509
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
510
+ ],
511
+ }));
512
+ const fit = $.let(Func.bind(yardFit));
513
+ return _jsx(Box, { width: "100%", maxWidth: "390px", height: "760px", children: _jsx(Allocation, { id: "allocationMobile", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardDay }, events: { bin: Schedule.events(bins, {
514
+ name: "Bin", icon: "box", entries,
515
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
516
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
517
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
518
+ }) }, resources: {
519
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
520
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
521
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
522
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
523
+ }, arrivals: Allocation.arrivals(loads.read(), {
524
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
525
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
526
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
527
+ details: l => [{ label: "Settings", value: l.schedule }],
528
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
529
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
530
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
531
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
532
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
533
+ ] }) });
534
+ } })),
535
+ });
536
+ export const allocationCustomBin = example({
537
+ description: "The bin kind's own inspector: the yard's typed bin form — its m³ and its loading instruction, each change the bin written back whole — in place of the built-in quantity field and the row's other fields.",
538
+ keywords: ["Allocation", "Schedule.events", "inspector", "bin", "Field", "typed form"], inputs: [],
539
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
540
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
541
+ const entries = $.let(Data.bindPaged(kilnBins));
542
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
543
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
544
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
545
+ const yard = $.let(Data.bind(kilns));
546
+ const loads = $.let(Data.bind(arrivals));
547
+ const bays = $.let(Data.bind(yardBays));
548
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
549
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
550
+ const slice = $.let(Slice.bindRecords("ex.allocationCustomBin", {
551
+ bin: { source: byTime, range: "at" },
552
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
553
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
554
+ }, {
555
+ presets: [
556
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
557
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
558
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
559
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
560
+ ],
561
+ }));
562
+ const fit = $.let(Func.bind(yardFit));
563
+ // The bin's own form: its m³ and its loading instruction, each change the bin written back whole.
564
+ const binForm = $.const(East.function([KilnBin, FunctionType([KilnBin], NullType)], UIComponentType, (_$2, row, update) => _jsxs(VStack, { children: [_jsx(Field.FloatInput, { label: "Quantity", value: row.m3, min: 0, step: 1, onChange: (_$3, m3) => update({ bay: row.bay, at: row.at, load: row.load,
565
+ m3, spec: row.spec, dryFor: row.dryFor, kilns: row.kilns, specBooked: row.specBooked, specMeasured: row.specMeasured,
566
+ gradeBooked: row.gradeBooked, gradeMeasured: row.gradeMeasured, instruction: row.instruction }) }), _jsx(Field.StringInput, { label: "Loading instruction", value: row.instruction.unwrap("some", () => ""), onChange: (_$3, text) => update({ bay: row.bay,
567
+ at: row.at, load: row.load, m3: row.m3, spec: row.spec, dryFor: row.dryFor, kilns: row.kilns, specBooked: row.specBooked,
568
+ specMeasured: row.specMeasured, gradeBooked: row.gradeBooked, gradeMeasured: row.gradeMeasured,
569
+ instruction: East.equal(text, "").ifElse(() => none, () => some(text)) }) })] })));
570
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationCustomBin", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardDay }, events: { bin: Schedule.events(bins, {
571
+ name: "Bin", icon: "box", entries,
572
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
573
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
574
+ inspector: binForm,
575
+ }) }, resources: {
576
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
577
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
578
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
579
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
580
+ }, arrivals: Allocation.arrivals(loads.read(), {
581
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
582
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
583
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
584
+ details: l => [{ label: "Settings", value: l.schedule }],
585
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
586
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
587
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
588
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
589
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
590
+ ] }) });
591
+ } })),
592
+ });
593
+ export const allocationFitRule = example({
594
+ description: "The ready-made fit with one yard rule over it, as an e3.function: a bulk kiln takes no load under 20 m³, so LD-2235 (8 m³) fits K-305 alone.",
595
+ keywords: ["Allocation", "fit", "e3.function", "Func.bind", "Allocation.fit", "Allocation.answer", "rule"], inputs: [],
596
+ fn: East.function([], UIComponentType, _$ => _jsx(Reactive, { children: $ => {
597
+ const bins = $.let(Record.bind(kilnBins, [kilnBinsPatch]));
598
+ const entries = $.let(Data.bindPaged(kilnBins));
599
+ const byTime = $.let(Data.bindPaged(kilnBins, { indexes: [kilnBinsByTime] }));
600
+ const days = $.let(Record.bind(yardDays, [yardDaysPatch]));
601
+ // Every bay and kiln is the calculation scope; the narrowing only chooses which show.
602
+ const yard = $.let(Data.bind(kilns));
603
+ const loads = $.let(Data.bind(arrivals));
604
+ const bays = $.let(Data.bind(yardBays));
605
+ const bayIndex = $.let(Data.bindPaged(yardBays, { indexes: [yardBaysByArea] }));
606
+ const kilnIndex = $.let(Data.bindPaged(kilns, { indexes: [kilnsByGroup] }));
607
+ const slice = $.let(Slice.bindRecords("ex.allocationFitRule", {
608
+ bin: { source: byTime, range: "at" },
609
+ bays: { source: bayIndex, fields: { area: { label: "Area", hints: ["North", "South"] } } },
610
+ kilns: { source: kilnIndex, fields: { group: { label: "Kiln group", hints: ["Hall A", "Hall B", "Compact", "Standard", "Large", "Bulk"] } } },
611
+ }, {
612
+ presets: [
613
+ { id: "halls", name: "Halls", where: { kilns: { group: ["Hall A", "Hall B"] } } },
614
+ { id: "small", name: "Compact and standard", where: { kilns: { group: ["Compact", "Standard"] } } },
615
+ { id: "large", name: "Large and bulk", where: { kilns: { group: ["Large", "Bulk"] } } },
616
+ { id: "north", name: "North bays, halls", where: { bays: { area: ["North"] }, kilns: { group: ["Hall A", "Hall B"] } } },
617
+ ],
618
+ }));
619
+ const fit = $.let(Func.bind(bulkFit));
620
+ return _jsx(Box, { width: "100%", height: "900px", children: _jsx(Allocation, { id: "allocationFitRule", title: "Kiln loading", fit: fit, slice: { slice }, inspector: true, library: [Allocation.library.arrivals(), Allocation.library.resources()], view: { layout: "timeline", date: yardDay }, events: { bin: Schedule.events(bins, {
621
+ name: "Bin", icon: "box", entries,
622
+ at: "at", resource: { field: "bay", of: "bays" }, arrival: "load",
623
+ quantity: { field: "m3", unit: "m³" }, parts: { field: "kilns", of: "kilns" }, hold: "dryFor", kind: "spec",
624
+ fields: { specMeasured: Schedule.field.text({ label: "Spec measured" }), instruction: Schedule.field.text({ label: "Loading instruction" }) },
625
+ }) }, resources: {
626
+ bays: Schedule.resources(bays.read(), { name: "Bays", icon: "warehouse", label: b => b.name, offset: b => b.offset }),
627
+ kilns: Schedule.resources(yard.read(), { name: "Kilns", icon: "fire", label: k => k.name, group: k => k.group,
628
+ meta: k => some(East.str `${k.group} · ${East.Float.roundHalf(k.max)} m³`), note: k => k.note,
629
+ min: k => k.min, max: k => k.max, hold: k => variant("days", k.days), jobs: k => k.charges }),
630
+ }, arrivals: Allocation.arrivals(loads.read(), {
631
+ label: l => l.code, meta: l => some(East.str `${l.mill} · ${l.grade} · spec ${l.spec}`),
632
+ quantity: l => l.m3, hold: l => variant("days", l.dryingDays), kind: l => some(l.spec),
633
+ due: l => some(l.due), window: l => some({ from: l.from, to: l.to }),
634
+ details: l => [{ label: "Settings", value: l.schedule }],
635
+ values: l => ({ specBooked: l.spec, specMeasured: l.spec, gradeBooked: l.grade.substring(0n, 1n), gradeMeasured: l.grade, instruction: l.instruction }),
636
+ }), periods: Schedule.periods(days, { every: "day", status: { field: "state", draft: "draft", published: "issued" } }), columns: [
637
+ { key: "spec", label: "Spec", text: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => b.specMeasured, () => East.str `booked ${b.specBooked} · measured ${b.specMeasured}`),
638
+ tone: b => East.equal(b.specBooked, b.specMeasured).ifElse(() => none, () => some(variant("warning", null))) },
639
+ { key: "grade", label: "Grade", text: b => b.gradeMeasured.startsWith(b.gradeBooked).ifElse(() => b.gradeMeasured, () => East.str `booked ${b.gradeBooked} · measured ${b.gradeMeasured}`), table: false },
640
+ ] }) });
641
+ } })),
642
+ });
643
+ //# sourceMappingURL=allocation.examples.js.map