@harborppm/cli 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  // Built from src/tui by cli/build.mjs. Edit the source, not this file.
2
2
  import { createInterface } from "node:readline/promises";
3
3
  import { Box, Text, render, useApp, useInput, useStdout, useWindowSize } from "ink";
4
- import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
5
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import React, { Fragment, createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
5
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { basename, dirname, join, relative, resolve } from "node:path";
7
7
  import { execFile } from "node:child_process";
8
8
  import { access, chmod, mkdir, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
9
9
  import { userInfo } from "node:os";
10
10
 
11
- //#region \0rolldown/runtime.js
11
+ // \0rolldown/runtime.js
12
12
  var __defProp = Object.defineProperty;
13
13
  var __esmMin = (fn, res, err) => () => {
14
14
  if (err) throw err[0];
@@ -32,8 +32,7 @@ var __exportAll = (all, no_symbols) => {
32
32
  return target;
33
33
  };
34
34
 
35
- //#endregion
36
- //#region src/lib/clock.ts
35
+ // src/lib/clock.ts
37
36
  /** A date's local wall-clock time, with no zone: "2026-10-05T23:10:00". */
38
37
  function wallClock(d = /* @__PURE__ */ new Date()) {
39
38
  return `${d.getFullYear()}-${pad$2(d.getMonth() + 1)}-${pad$2(d.getDate())}T${pad$2(d.getHours())}:${pad$2(d.getMinutes())}:${pad$2(d.getSeconds())}`;
@@ -47,8 +46,7 @@ var init_clock = __esmMin((() => {
47
46
  pad$2 = (n) => String(n).padStart(2, "0");
48
47
  }));
49
48
 
50
- //#endregion
51
- //#region src/lib/date-text.ts
49
+ // src/lib/date-text.ts
52
50
  /**
53
51
  * `date` in local time by a pattern of yyyy, MMMM, MMM, MM, dd, d, EEEE and
54
52
  * EEE (as in date-fns: "EEEE, MMMM d" → "Friday, September 25"); anything
@@ -172,8 +170,7 @@ var init_date_text = __esmMin((() => {
172
170
  MINUTE = 6e4;
173
171
  }));
174
172
 
175
- //#endregion
176
- //#region node_modules/zustand/esm/vanilla.mjs
173
+ // node_modules/zustand/esm/vanilla.mjs
177
174
  var createStoreImpl, createStore;
178
175
  var init_vanilla = __esmMin((() => {
179
176
  createStoreImpl = (createState) => {
@@ -205,10 +202,9 @@ var init_vanilla = __esmMin((() => {
205
202
  createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
206
203
  }));
207
204
 
208
- //#endregion
209
- //#region node_modules/zustand/esm/react.mjs
205
+ // node_modules/zustand/esm/react.mjs
210
206
  function useStore(api, selector = identity) {
211
- const slice = React.useSyncExternalStore(api.subscribe, React.useCallback(() => selector(api.getState()), [api, selector]), React.useCallback(() => selector(api.getInitialState()), [api, selector]));
207
+ const slice = React.useSyncExternalStore(api.subscribe, React.useCallback(() => selector(api.getState()), [api, selector]), () => selector(api.getInitialState()));
212
208
  React.useDebugValue(slice);
213
209
  return slice;
214
210
  }
@@ -225,15 +221,13 @@ var init_react = __esmMin((() => {
225
221
  create$1 = ((createState) => createState ? createImpl(createState) : createImpl);
226
222
  }));
227
223
 
228
- //#endregion
229
- //#region node_modules/zustand/esm/index.mjs
224
+ // node_modules/zustand/esm/index.mjs
230
225
  var init_esm = __esmMin((() => {
231
226
  init_vanilla();
232
227
  init_react();
233
228
  }));
234
229
 
235
- //#endregion
236
- //#region src/tui/context.tsx
230
+ // src/tui/context.tsx
237
231
  init_date_text();
238
232
  /**
239
233
  * What every screen of the terminal app reaches for: the store, the sync
@@ -252,25 +246,16 @@ function useHarbor(selector) {
252
246
  return useStore(useDeps().store, selector);
253
247
  }
254
248
 
255
- //#endregion
256
- //#region node_modules/date-fns/constants.js
257
- var daysInYear, maxTime, minTime, millisecondsInDay, secondsInHour, secondsInDay, secondsInWeek, secondsInYear, secondsInMonth, secondsInQuarter, constructFromSymbol;
249
+ // node_modules/date-fns/constants.js
250
+ var maxTime, minTime, millisecondsInDay, constructFromSymbol;
258
251
  var init_constants = __esmMin((() => {
259
- daysInYear = 365.2425;
260
252
  maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1e3;
261
253
  minTime = -maxTime;
262
254
  millisecondsInDay = 864e5;
263
- secondsInHour = 3600;
264
- secondsInDay = secondsInHour * 24;
265
- secondsInWeek = secondsInDay * 7;
266
- secondsInYear = secondsInDay * daysInYear;
267
- secondsInMonth = secondsInYear / 12;
268
- secondsInQuarter = secondsInMonth * 3;
269
255
  constructFromSymbol = Symbol.for("constructDateFrom");
270
256
  }));
271
257
 
272
- //#endregion
273
- //#region node_modules/date-fns/constructFrom.js
258
+ // node_modules/date-fns/constructFrom.js
274
259
  /**
275
260
  * @name constructFrom
276
261
  * @category Generic Helpers
@@ -316,8 +301,7 @@ var init_constructFrom = __esmMin((() => {
316
301
  init_constants();
317
302
  }));
318
303
 
319
- //#endregion
320
- //#region node_modules/date-fns/toDate.js
304
+ // node_modules/date-fns/toDate.js
321
305
  /**
322
306
  * @name toDate
323
307
  * @category Common Helpers
@@ -363,8 +347,7 @@ var init_toDate = __esmMin((() => {
363
347
  init_constructFrom();
364
348
  }));
365
349
 
366
- //#endregion
367
- //#region node_modules/date-fns/addDays.js
350
+ // node_modules/date-fns/addDays.js
368
351
  /**
369
352
  * The {@link addDays} function options.
370
353
  */
@@ -421,8 +404,7 @@ var init_addDays = __esmMin((() => {
421
404
  init_toDate();
422
405
  }));
423
406
 
424
- //#endregion
425
- //#region node_modules/date-fns/addMonths.js
407
+ // node_modules/date-fns/addMonths.js
426
408
  /**
427
409
  * The {@link addMonths} function options.
428
410
  */
@@ -470,36 +452,28 @@ var init_addMonths = __esmMin((() => {
470
452
  init_toDate();
471
453
  }));
472
454
 
473
- //#endregion
474
- //#region node_modules/date-fns/add.js
455
+ // node_modules/date-fns/add.js
475
456
  var init_add = __esmMin((() => {}));
476
457
 
477
- //#endregion
478
- //#region node_modules/date-fns/isSaturday.js
458
+ // node_modules/date-fns/isSaturday.js
479
459
  var init_isSaturday = __esmMin((() => {}));
480
460
 
481
- //#endregion
482
- //#region node_modules/date-fns/isSunday.js
461
+ // node_modules/date-fns/isSunday.js
483
462
  var init_isSunday = __esmMin((() => {}));
484
463
 
485
- //#endregion
486
- //#region node_modules/date-fns/isWeekend.js
464
+ // node_modules/date-fns/isWeekend.js
487
465
  var init_isWeekend = __esmMin((() => {}));
488
466
 
489
- //#endregion
490
- //#region node_modules/date-fns/addBusinessDays.js
467
+ // node_modules/date-fns/addBusinessDays.js
491
468
  var init_addBusinessDays = __esmMin((() => {}));
492
469
 
493
- //#endregion
494
- //#region node_modules/date-fns/addMilliseconds.js
470
+ // node_modules/date-fns/addMilliseconds.js
495
471
  var init_addMilliseconds = __esmMin((() => {}));
496
472
 
497
- //#endregion
498
- //#region node_modules/date-fns/addHours.js
473
+ // node_modules/date-fns/addHours.js
499
474
  var init_addHours = __esmMin((() => {}));
500
475
 
501
- //#endregion
502
- //#region node_modules/date-fns/_lib/defaultOptions.js
476
+ // node_modules/date-fns/_lib/defaultOptions.js
503
477
  function getDefaultOptions() {
504
478
  return defaultOptions;
505
479
  }
@@ -508,8 +482,7 @@ var init_defaultOptions = __esmMin((() => {
508
482
  defaultOptions = {};
509
483
  }));
510
484
 
511
- //#endregion
512
- //#region node_modules/date-fns/startOfWeek.js
485
+ // node_modules/date-fns/startOfWeek.js
513
486
  /**
514
487
  * The {@link startOfWeek} function options.
515
488
  */
@@ -555,16 +528,13 @@ var init_startOfWeek = __esmMin((() => {
555
528
  init_toDate();
556
529
  }));
557
530
 
558
- //#endregion
559
- //#region node_modules/date-fns/startOfISOWeek.js
531
+ // node_modules/date-fns/startOfISOWeek.js
560
532
  var init_startOfISOWeek = __esmMin((() => {}));
561
533
 
562
- //#endregion
563
- //#region node_modules/date-fns/getISOWeekYear.js
534
+ // node_modules/date-fns/getISOWeekYear.js
564
535
  var init_getISOWeekYear = __esmMin((() => {}));
565
536
 
566
- //#endregion
567
- //#region node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js
537
+ // node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js
568
538
  /**
569
539
  * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.
570
540
  * They usually appear for dates that denote time before the timezones were introduced
@@ -586,8 +556,7 @@ var init_getTimezoneOffsetInMilliseconds = __esmMin((() => {
586
556
  init_toDate();
587
557
  }));
588
558
 
589
- //#endregion
590
- //#region node_modules/date-fns/_lib/normalizeDates.js
559
+ // node_modules/date-fns/_lib/normalizeDates.js
591
560
  function normalizeDates(context, ...dates) {
592
561
  const normalize = constructFrom.bind(null, context || dates.find((date) => typeof date === "object"));
593
562
  return dates.map(normalize);
@@ -596,8 +565,7 @@ var init_normalizeDates = __esmMin((() => {
596
565
  init_constructFrom();
597
566
  }));
598
567
 
599
- //#endregion
600
- //#region node_modules/date-fns/startOfDay.js
568
+ // node_modules/date-fns/startOfDay.js
601
569
  /**
602
570
  * The {@link startOfDay} function options.
603
571
  */
@@ -632,8 +600,7 @@ var init_startOfDay = __esmMin((() => {
632
600
  init_toDate();
633
601
  }));
634
602
 
635
- //#endregion
636
- //#region node_modules/date-fns/differenceInCalendarDays.js
603
+ // node_modules/date-fns/differenceInCalendarDays.js
637
604
  /**
638
605
  * The {@link differenceInCalendarDays} function options.
639
606
  */
@@ -683,212 +650,160 @@ var init_differenceInCalendarDays = __esmMin((() => {
683
650
  init_startOfDay();
684
651
  }));
685
652
 
686
- //#endregion
687
- //#region node_modules/date-fns/startOfISOWeekYear.js
653
+ // node_modules/date-fns/startOfISOWeekYear.js
688
654
  var init_startOfISOWeekYear = __esmMin((() => {}));
689
655
 
690
- //#endregion
691
- //#region node_modules/date-fns/setISOWeekYear.js
656
+ // node_modules/date-fns/setISOWeekYear.js
692
657
  var init_setISOWeekYear = __esmMin((() => {}));
693
658
 
694
- //#endregion
695
- //#region node_modules/date-fns/addISOWeekYears.js
659
+ // node_modules/date-fns/addISOWeekYears.js
696
660
  var init_addISOWeekYears = __esmMin((() => {}));
697
661
 
698
- //#endregion
699
- //#region node_modules/date-fns/addMinutes.js
662
+ // node_modules/date-fns/addMinutes.js
700
663
  var init_addMinutes = __esmMin((() => {}));
701
664
 
702
- //#endregion
703
- //#region node_modules/date-fns/addQuarters.js
665
+ // node_modules/date-fns/addQuarters.js
704
666
  var init_addQuarters = __esmMin((() => {}));
705
667
 
706
- //#endregion
707
- //#region node_modules/date-fns/addSeconds.js
668
+ // node_modules/date-fns/addSeconds.js
708
669
  var init_addSeconds = __esmMin((() => {}));
709
670
 
710
- //#endregion
711
- //#region node_modules/date-fns/addWeeks.js
671
+ // node_modules/date-fns/addWeeks.js
712
672
  var init_addWeeks = __esmMin((() => {}));
713
673
 
714
- //#endregion
715
- //#region node_modules/date-fns/addYears.js
674
+ // node_modules/date-fns/addYears.js
716
675
  var init_addYears = __esmMin((() => {}));
717
676
 
718
- //#endregion
719
- //#region node_modules/date-fns/areIntervalsOverlapping.js
677
+ // node_modules/date-fns/areIntervalsOverlapping.js
720
678
  var init_areIntervalsOverlapping = __esmMin((() => {}));
721
679
 
722
- //#endregion
723
- //#region node_modules/date-fns/max.js
680
+ // node_modules/date-fns/max.js
724
681
  var init_max = __esmMin((() => {}));
725
682
 
726
- //#endregion
727
- //#region node_modules/date-fns/min.js
683
+ // node_modules/date-fns/min.js
728
684
  var init_min = __esmMin((() => {}));
729
685
 
730
- //#endregion
731
- //#region node_modules/date-fns/clamp.js
686
+ // node_modules/date-fns/clamp.js
732
687
  var init_clamp = __esmMin((() => {}));
733
688
 
734
- //#endregion
735
- //#region node_modules/date-fns/closestIndexTo.js
689
+ // node_modules/date-fns/closestIndexTo.js
736
690
  var init_closestIndexTo = __esmMin((() => {}));
737
691
 
738
- //#endregion
739
- //#region node_modules/date-fns/closestTo.js
692
+ // node_modules/date-fns/closestTo.js
740
693
  var init_closestTo = __esmMin((() => {}));
741
694
 
742
- //#endregion
743
- //#region node_modules/date-fns/compareAsc.js
695
+ // node_modules/date-fns/compareAsc.js
744
696
  var init_compareAsc = __esmMin((() => {}));
745
697
 
746
- //#endregion
747
- //#region node_modules/date-fns/compareDesc.js
698
+ // node_modules/date-fns/compareDesc.js
748
699
  var init_compareDesc = __esmMin((() => {}));
749
700
 
750
- //#endregion
751
- //#region node_modules/date-fns/constructNow.js
701
+ // node_modules/date-fns/constructNow.js
752
702
  var init_constructNow = __esmMin((() => {}));
753
703
 
754
- //#endregion
755
- //#region node_modules/date-fns/daysToWeeks.js
704
+ // node_modules/date-fns/daysToWeeks.js
756
705
  var init_daysToWeeks = __esmMin((() => {}));
757
706
 
758
- //#endregion
759
- //#region node_modules/date-fns/isSameDay.js
707
+ // node_modules/date-fns/isSameDay.js
760
708
  var init_isSameDay = __esmMin((() => {}));
761
709
 
762
- //#endregion
763
- //#region node_modules/date-fns/isDate.js
710
+ // node_modules/date-fns/isDate.js
764
711
  var init_isDate = __esmMin((() => {}));
765
712
 
766
- //#endregion
767
- //#region node_modules/date-fns/isValid.js
713
+ // node_modules/date-fns/isValid.js
768
714
  var init_isValid = __esmMin((() => {}));
769
715
 
770
- //#endregion
771
- //#region node_modules/date-fns/differenceInBusinessDays.js
716
+ // node_modules/date-fns/differenceInBusinessDays.js
772
717
  var init_differenceInBusinessDays = __esmMin((() => {}));
773
718
 
774
- //#endregion
775
- //#region node_modules/date-fns/differenceInCalendarISOWeekYears.js
719
+ // node_modules/date-fns/differenceInCalendarISOWeekYears.js
776
720
  var init_differenceInCalendarISOWeekYears = __esmMin((() => {}));
777
721
 
778
- //#endregion
779
- //#region node_modules/date-fns/differenceInCalendarISOWeeks.js
722
+ // node_modules/date-fns/differenceInCalendarISOWeeks.js
780
723
  var init_differenceInCalendarISOWeeks = __esmMin((() => {}));
781
724
 
782
- //#endregion
783
- //#region node_modules/date-fns/differenceInCalendarMonths.js
725
+ // node_modules/date-fns/differenceInCalendarMonths.js
784
726
  var init_differenceInCalendarMonths = __esmMin((() => {}));
785
727
 
786
- //#endregion
787
- //#region node_modules/date-fns/getQuarter.js
728
+ // node_modules/date-fns/getQuarter.js
788
729
  var init_getQuarter = __esmMin((() => {}));
789
730
 
790
- //#endregion
791
- //#region node_modules/date-fns/differenceInCalendarQuarters.js
731
+ // node_modules/date-fns/differenceInCalendarQuarters.js
792
732
  var init_differenceInCalendarQuarters = __esmMin((() => {}));
793
733
 
794
- //#endregion
795
- //#region node_modules/date-fns/differenceInCalendarWeeks.js
734
+ // node_modules/date-fns/differenceInCalendarWeeks.js
796
735
  var init_differenceInCalendarWeeks = __esmMin((() => {}));
797
736
 
798
- //#endregion
799
- //#region node_modules/date-fns/differenceInCalendarYears.js
737
+ // node_modules/date-fns/differenceInCalendarYears.js
800
738
  var init_differenceInCalendarYears = __esmMin((() => {}));
801
739
 
802
- //#endregion
803
- //#region node_modules/date-fns/differenceInDays.js
740
+ // node_modules/date-fns/differenceInDays.js
804
741
  var init_differenceInDays = __esmMin((() => {}));
805
742
 
806
- //#endregion
807
- //#region node_modules/date-fns/differenceInHours.js
743
+ // node_modules/date-fns/differenceInHours.js
808
744
  var init_differenceInHours = __esmMin((() => {}));
809
745
 
810
- //#endregion
811
- //#region node_modules/date-fns/subISOWeekYears.js
746
+ // node_modules/date-fns/subISOWeekYears.js
812
747
  var init_subISOWeekYears = __esmMin((() => {}));
813
748
 
814
- //#endregion
815
- //#region node_modules/date-fns/differenceInISOWeekYears.js
749
+ // node_modules/date-fns/differenceInISOWeekYears.js
816
750
  var init_differenceInISOWeekYears = __esmMin((() => {}));
817
751
 
818
- //#endregion
819
- //#region node_modules/date-fns/differenceInMilliseconds.js
752
+ // node_modules/date-fns/differenceInMilliseconds.js
820
753
  var init_differenceInMilliseconds = __esmMin((() => {}));
821
754
 
822
- //#endregion
823
- //#region node_modules/date-fns/differenceInMinutes.js
755
+ // node_modules/date-fns/differenceInMinutes.js
824
756
  var init_differenceInMinutes = __esmMin((() => {}));
825
757
 
826
- //#endregion
827
- //#region node_modules/date-fns/endOfDay.js
758
+ // node_modules/date-fns/endOfDay.js
828
759
  var init_endOfDay = __esmMin((() => {}));
829
760
 
830
- //#endregion
831
- //#region node_modules/date-fns/endOfMonth.js
761
+ // node_modules/date-fns/endOfMonth.js
832
762
  var init_endOfMonth = __esmMin((() => {}));
833
763
 
834
- //#endregion
835
- //#region node_modules/date-fns/isLastDayOfMonth.js
764
+ // node_modules/date-fns/isLastDayOfMonth.js
836
765
  var init_isLastDayOfMonth = __esmMin((() => {}));
837
766
 
838
- //#endregion
839
- //#region node_modules/date-fns/differenceInMonths.js
767
+ // node_modules/date-fns/differenceInMonths.js
840
768
  var init_differenceInMonths = __esmMin((() => {}));
841
769
 
842
- //#endregion
843
- //#region node_modules/date-fns/differenceInQuarters.js
770
+ // node_modules/date-fns/differenceInQuarters.js
844
771
  var init_differenceInQuarters = __esmMin((() => {}));
845
772
 
846
- //#endregion
847
- //#region node_modules/date-fns/differenceInSeconds.js
773
+ // node_modules/date-fns/differenceInSeconds.js
848
774
  var init_differenceInSeconds = __esmMin((() => {}));
849
775
 
850
- //#endregion
851
- //#region node_modules/date-fns/differenceInWeeks.js
776
+ // node_modules/date-fns/differenceInWeeks.js
852
777
  var init_differenceInWeeks = __esmMin((() => {}));
853
778
 
854
- //#endregion
855
- //#region node_modules/date-fns/differenceInYears.js
779
+ // node_modules/date-fns/differenceInYears.js
856
780
  var init_differenceInYears = __esmMin((() => {}));
857
781
 
858
- //#endregion
859
- //#region node_modules/date-fns/eachDayOfInterval.js
782
+ // node_modules/date-fns/eachDayOfInterval.js
860
783
  var init_eachDayOfInterval = __esmMin((() => {}));
861
784
 
862
- //#endregion
863
- //#region node_modules/date-fns/eachHourOfInterval.js
785
+ // node_modules/date-fns/eachHourOfInterval.js
864
786
  var init_eachHourOfInterval = __esmMin((() => {}));
865
787
 
866
- //#endregion
867
- //#region node_modules/date-fns/eachMinuteOfInterval.js
788
+ // node_modules/date-fns/eachMinuteOfInterval.js
868
789
  var init_eachMinuteOfInterval = __esmMin((() => {}));
869
790
 
870
- //#endregion
871
- //#region node_modules/date-fns/eachMonthOfInterval.js
791
+ // node_modules/date-fns/eachMonthOfInterval.js
872
792
  var init_eachMonthOfInterval = __esmMin((() => {}));
873
793
 
874
- //#endregion
875
- //#region node_modules/date-fns/startOfQuarter.js
794
+ // node_modules/date-fns/startOfQuarter.js
876
795
  var init_startOfQuarter = __esmMin((() => {}));
877
796
 
878
- //#endregion
879
- //#region node_modules/date-fns/eachQuarterOfInterval.js
797
+ // node_modules/date-fns/eachQuarterOfInterval.js
880
798
  var init_eachQuarterOfInterval = __esmMin((() => {}));
881
799
 
882
- //#endregion
883
- //#region node_modules/date-fns/eachWeekOfInterval.js
800
+ // node_modules/date-fns/eachWeekOfInterval.js
884
801
  var init_eachWeekOfInterval = __esmMin((() => {}));
885
802
 
886
- //#endregion
887
- //#region node_modules/date-fns/eachWeekendOfInterval.js
803
+ // node_modules/date-fns/eachWeekendOfInterval.js
888
804
  var init_eachWeekendOfInterval = __esmMin((() => {}));
889
805
 
890
- //#endregion
891
- //#region node_modules/date-fns/startOfMonth.js
806
+ // node_modules/date-fns/startOfMonth.js
892
807
  /**
893
808
  * The {@link startOfMonth} function options.
894
809
  */
@@ -925,152 +840,115 @@ var init_startOfMonth = __esmMin((() => {
925
840
  init_toDate();
926
841
  }));
927
842
 
928
- //#endregion
929
- //#region node_modules/date-fns/eachWeekendOfMonth.js
843
+ // node_modules/date-fns/eachWeekendOfMonth.js
930
844
  var init_eachWeekendOfMonth = __esmMin((() => {}));
931
845
 
932
- //#endregion
933
- //#region node_modules/date-fns/endOfYear.js
846
+ // node_modules/date-fns/endOfYear.js
934
847
  var init_endOfYear = __esmMin((() => {}));
935
848
 
936
- //#endregion
937
- //#region node_modules/date-fns/startOfYear.js
849
+ // node_modules/date-fns/startOfYear.js
938
850
  var init_startOfYear = __esmMin((() => {}));
939
851
 
940
- //#endregion
941
- //#region node_modules/date-fns/eachWeekendOfYear.js
852
+ // node_modules/date-fns/eachWeekendOfYear.js
942
853
  var init_eachWeekendOfYear = __esmMin((() => {}));
943
854
 
944
- //#endregion
945
- //#region node_modules/date-fns/eachYearOfInterval.js
855
+ // node_modules/date-fns/eachYearOfInterval.js
946
856
  var init_eachYearOfInterval = __esmMin((() => {}));
947
857
 
948
- //#endregion
949
- //#region node_modules/date-fns/endOfDecade.js
858
+ // node_modules/date-fns/endOfDecade.js
950
859
  var init_endOfDecade = __esmMin((() => {}));
951
860
 
952
- //#endregion
953
- //#region node_modules/date-fns/endOfHour.js
861
+ // node_modules/date-fns/endOfHour.js
954
862
  var init_endOfHour = __esmMin((() => {}));
955
863
 
956
- //#endregion
957
- //#region node_modules/date-fns/endOfWeek.js
864
+ // node_modules/date-fns/endOfWeek.js
958
865
  var init_endOfWeek = __esmMin((() => {}));
959
866
 
960
- //#endregion
961
- //#region node_modules/date-fns/endOfISOWeek.js
867
+ // node_modules/date-fns/endOfISOWeek.js
962
868
  var init_endOfISOWeek = __esmMin((() => {}));
963
869
 
964
- //#endregion
965
- //#region node_modules/date-fns/endOfISOWeekYear.js
870
+ // node_modules/date-fns/endOfISOWeekYear.js
966
871
  var init_endOfISOWeekYear = __esmMin((() => {}));
967
872
 
968
- //#endregion
969
- //#region node_modules/date-fns/endOfMinute.js
873
+ // node_modules/date-fns/endOfMinute.js
970
874
  var init_endOfMinute = __esmMin((() => {}));
971
875
 
972
- //#endregion
973
- //#region node_modules/date-fns/endOfQuarter.js
876
+ // node_modules/date-fns/endOfQuarter.js
974
877
  var init_endOfQuarter = __esmMin((() => {}));
975
878
 
976
- //#endregion
977
- //#region node_modules/date-fns/endOfSecond.js
879
+ // node_modules/date-fns/endOfSecond.js
978
880
  var init_endOfSecond = __esmMin((() => {}));
979
881
 
980
- //#endregion
981
- //#region node_modules/date-fns/endOfToday.js
882
+ // node_modules/date-fns/endOfToday.js
982
883
  var init_endOfToday = __esmMin((() => {}));
983
884
 
984
- //#endregion
985
- //#region node_modules/date-fns/endOfTomorrow.js
885
+ // node_modules/date-fns/endOfTomorrow.js
986
886
  var init_endOfTomorrow = __esmMin((() => {}));
987
887
 
988
- //#endregion
989
- //#region node_modules/date-fns/endOfYesterday.js
888
+ // node_modules/date-fns/endOfYesterday.js
990
889
  var init_endOfYesterday = __esmMin((() => {}));
991
890
 
992
- //#endregion
993
- //#region node_modules/date-fns/getDayOfYear.js
891
+ // node_modules/date-fns/getDayOfYear.js
994
892
  var init_getDayOfYear = __esmMin((() => {}));
995
893
 
996
- //#endregion
997
- //#region node_modules/date-fns/getISOWeek.js
894
+ // node_modules/date-fns/getISOWeek.js
998
895
  var init_getISOWeek = __esmMin((() => {}));
999
896
 
1000
- //#endregion
1001
- //#region node_modules/date-fns/getWeekYear.js
897
+ // node_modules/date-fns/getWeekYear.js
1002
898
  var init_getWeekYear = __esmMin((() => {}));
1003
899
 
1004
- //#endregion
1005
- //#region node_modules/date-fns/startOfWeekYear.js
900
+ // node_modules/date-fns/startOfWeekYear.js
1006
901
  var init_startOfWeekYear = __esmMin((() => {}));
1007
902
 
1008
- //#endregion
1009
- //#region node_modules/date-fns/getWeek.js
903
+ // node_modules/date-fns/getWeek.js
1010
904
  var init_getWeek = __esmMin((() => {}));
1011
905
 
1012
- //#endregion
1013
- //#region node_modules/date-fns/format.js
906
+ // node_modules/date-fns/format.js
1014
907
  var init_format$1 = __esmMin((() => {}));
1015
908
 
1016
- //#endregion
1017
- //#region node_modules/date-fns/formatDistance.js
909
+ // node_modules/date-fns/formatDistance.js
1018
910
  var init_formatDistance = __esmMin((() => {}));
1019
911
 
1020
- //#endregion
1021
- //#region node_modules/date-fns/formatDistanceStrict.js
912
+ // node_modules/date-fns/formatDistanceStrict.js
1022
913
  var init_formatDistanceStrict = __esmMin((() => {}));
1023
914
 
1024
- //#endregion
1025
- //#region node_modules/date-fns/formatDistanceToNow.js
915
+ // node_modules/date-fns/formatDistanceToNow.js
1026
916
  var init_formatDistanceToNow = __esmMin((() => {}));
1027
917
 
1028
- //#endregion
1029
- //#region node_modules/date-fns/formatDistanceToNowStrict.js
918
+ // node_modules/date-fns/formatDistanceToNowStrict.js
1030
919
  var init_formatDistanceToNowStrict = __esmMin((() => {}));
1031
920
 
1032
- //#endregion
1033
- //#region node_modules/date-fns/formatDuration.js
921
+ // node_modules/date-fns/formatDuration.js
1034
922
  var init_formatDuration = __esmMin((() => {}));
1035
923
 
1036
- //#endregion
1037
- //#region node_modules/date-fns/formatISO.js
924
+ // node_modules/date-fns/formatISO.js
1038
925
  var init_formatISO = __esmMin((() => {}));
1039
926
 
1040
- //#endregion
1041
- //#region node_modules/date-fns/formatISO9075.js
927
+ // node_modules/date-fns/formatISO9075.js
1042
928
  var init_formatISO9075 = __esmMin((() => {}));
1043
929
 
1044
- //#endregion
1045
- //#region node_modules/date-fns/formatISODuration.js
930
+ // node_modules/date-fns/formatISODuration.js
1046
931
  var init_formatISODuration = __esmMin((() => {}));
1047
932
 
1048
- //#endregion
1049
- //#region node_modules/date-fns/formatRFC3339.js
933
+ // node_modules/date-fns/formatRFC3339.js
1050
934
  var init_formatRFC3339 = __esmMin((() => {}));
1051
935
 
1052
- //#endregion
1053
- //#region node_modules/date-fns/formatRFC7231.js
936
+ // node_modules/date-fns/formatRFC7231.js
1054
937
  var init_formatRFC7231 = __esmMin((() => {}));
1055
938
 
1056
- //#endregion
1057
- //#region node_modules/date-fns/formatRelative.js
939
+ // node_modules/date-fns/formatRelative.js
1058
940
  var init_formatRelative = __esmMin((() => {}));
1059
941
 
1060
- //#endregion
1061
- //#region node_modules/date-fns/fromUnixTime.js
942
+ // node_modules/date-fns/fromUnixTime.js
1062
943
  var init_fromUnixTime = __esmMin((() => {}));
1063
944
 
1064
- //#endregion
1065
- //#region node_modules/date-fns/getDate.js
945
+ // node_modules/date-fns/getDate.js
1066
946
  var init_getDate = __esmMin((() => {}));
1067
947
 
1068
- //#endregion
1069
- //#region node_modules/date-fns/getDay.js
948
+ // node_modules/date-fns/getDay.js
1070
949
  var init_getDay = __esmMin((() => {}));
1071
950
 
1072
- //#endregion
1073
- //#region node_modules/date-fns/getDaysInMonth.js
951
+ // node_modules/date-fns/getDaysInMonth.js
1074
952
  /**
1075
953
  * The {@link getDaysInMonth} function options.
1076
954
  */
@@ -1106,112 +984,85 @@ var init_getDaysInMonth = __esmMin((() => {
1106
984
  init_toDate();
1107
985
  }));
1108
986
 
1109
- //#endregion
1110
- //#region node_modules/date-fns/isLeapYear.js
987
+ // node_modules/date-fns/isLeapYear.js
1111
988
  var init_isLeapYear = __esmMin((() => {}));
1112
989
 
1113
- //#endregion
1114
- //#region node_modules/date-fns/getDaysInYear.js
990
+ // node_modules/date-fns/getDaysInYear.js
1115
991
  var init_getDaysInYear = __esmMin((() => {}));
1116
992
 
1117
- //#endregion
1118
- //#region node_modules/date-fns/getDecade.js
993
+ // node_modules/date-fns/getDecade.js
1119
994
  var init_getDecade = __esmMin((() => {}));
1120
995
 
1121
- //#endregion
1122
- //#region node_modules/date-fns/getDefaultOptions.js
996
+ // node_modules/date-fns/getDefaultOptions.js
1123
997
  var init_getDefaultOptions = __esmMin((() => {}));
1124
998
 
1125
- //#endregion
1126
- //#region node_modules/date-fns/getHours.js
999
+ // node_modules/date-fns/getHours.js
1127
1000
  var init_getHours = __esmMin((() => {}));
1128
1001
 
1129
- //#endregion
1130
- //#region node_modules/date-fns/getISODay.js
1002
+ // node_modules/date-fns/getISODay.js
1131
1003
  var init_getISODay = __esmMin((() => {}));
1132
1004
 
1133
- //#endregion
1134
- //#region node_modules/date-fns/getISOWeeksInYear.js
1005
+ // node_modules/date-fns/getISOWeeksInYear.js
1135
1006
  var init_getISOWeeksInYear = __esmMin((() => {}));
1136
1007
 
1137
- //#endregion
1138
- //#region node_modules/date-fns/getMilliseconds.js
1008
+ // node_modules/date-fns/getMilliseconds.js
1139
1009
  var init_getMilliseconds = __esmMin((() => {}));
1140
1010
 
1141
- //#endregion
1142
- //#region node_modules/date-fns/getMinutes.js
1011
+ // node_modules/date-fns/getMinutes.js
1143
1012
  var init_getMinutes = __esmMin((() => {}));
1144
1013
 
1145
- //#endregion
1146
- //#region node_modules/date-fns/getMonth.js
1014
+ // node_modules/date-fns/getMonth.js
1147
1015
  var init_getMonth = __esmMin((() => {}));
1148
1016
 
1149
- //#endregion
1150
- //#region node_modules/date-fns/getOverlappingDaysInIntervals.js
1017
+ // node_modules/date-fns/getOverlappingDaysInIntervals.js
1151
1018
  var init_getOverlappingDaysInIntervals = __esmMin((() => {}));
1152
1019
 
1153
- //#endregion
1154
- //#region node_modules/date-fns/getSeconds.js
1020
+ // node_modules/date-fns/getSeconds.js
1155
1021
  var init_getSeconds = __esmMin((() => {}));
1156
1022
 
1157
- //#endregion
1158
- //#region node_modules/date-fns/getTime.js
1023
+ // node_modules/date-fns/getTime.js
1159
1024
  var init_getTime = __esmMin((() => {}));
1160
1025
 
1161
- //#endregion
1162
- //#region node_modules/date-fns/getUnixTime.js
1026
+ // node_modules/date-fns/getUnixTime.js
1163
1027
  var init_getUnixTime = __esmMin((() => {}));
1164
1028
 
1165
- //#endregion
1166
- //#region node_modules/date-fns/getWeekOfMonth.js
1029
+ // node_modules/date-fns/getWeekOfMonth.js
1167
1030
  var init_getWeekOfMonth = __esmMin((() => {}));
1168
1031
 
1169
- //#endregion
1170
- //#region node_modules/date-fns/lastDayOfMonth.js
1032
+ // node_modules/date-fns/lastDayOfMonth.js
1171
1033
  var init_lastDayOfMonth = __esmMin((() => {}));
1172
1034
 
1173
- //#endregion
1174
- //#region node_modules/date-fns/getWeeksInMonth.js
1035
+ // node_modules/date-fns/getWeeksInMonth.js
1175
1036
  var init_getWeeksInMonth = __esmMin((() => {}));
1176
1037
 
1177
- //#endregion
1178
- //#region node_modules/date-fns/getYear.js
1038
+ // node_modules/date-fns/getYear.js
1179
1039
  var init_getYear = __esmMin((() => {}));
1180
1040
 
1181
- //#endregion
1182
- //#region node_modules/date-fns/hoursToMilliseconds.js
1041
+ // node_modules/date-fns/hoursToMilliseconds.js
1183
1042
  var init_hoursToMilliseconds = __esmMin((() => {}));
1184
1043
 
1185
- //#endregion
1186
- //#region node_modules/date-fns/hoursToMinutes.js
1044
+ // node_modules/date-fns/hoursToMinutes.js
1187
1045
  var init_hoursToMinutes = __esmMin((() => {}));
1188
1046
 
1189
- //#endregion
1190
- //#region node_modules/date-fns/hoursToSeconds.js
1047
+ // node_modules/date-fns/hoursToSeconds.js
1191
1048
  var init_hoursToSeconds = __esmMin((() => {}));
1192
1049
 
1193
- //#endregion
1194
- //#region node_modules/date-fns/interval.js
1050
+ // node_modules/date-fns/interval.js
1195
1051
  var init_interval = __esmMin((() => {}));
1196
1052
 
1197
- //#endregion
1198
- //#region node_modules/date-fns/intervalToDuration.js
1053
+ // node_modules/date-fns/intervalToDuration.js
1199
1054
  var init_intervalToDuration = __esmMin((() => {}));
1200
1055
 
1201
- //#endregion
1202
- //#region node_modules/date-fns/intlFormat.js
1056
+ // node_modules/date-fns/intlFormat.js
1203
1057
  var init_intlFormat = __esmMin((() => {}));
1204
1058
 
1205
- //#endregion
1206
- //#region node_modules/date-fns/intlFormatDistance.js
1059
+ // node_modules/date-fns/intlFormatDistance.js
1207
1060
  var init_intlFormatDistance = __esmMin((() => {}));
1208
1061
 
1209
- //#endregion
1210
- //#region node_modules/date-fns/isAfter.js
1062
+ // node_modules/date-fns/isAfter.js
1211
1063
  var init_isAfter = __esmMin((() => {}));
1212
1064
 
1213
- //#endregion
1214
- //#region node_modules/date-fns/isBefore.js
1065
+ // node_modules/date-fns/isBefore.js
1215
1066
  /**
1216
1067
  * @name isBefore
1217
1068
  * @category Common Helpers
@@ -1237,168 +1088,127 @@ var init_isBefore = __esmMin((() => {
1237
1088
  init_toDate();
1238
1089
  }));
1239
1090
 
1240
- //#endregion
1241
- //#region node_modules/date-fns/isEqual.js
1091
+ // node_modules/date-fns/isEqual.js
1242
1092
  var init_isEqual = __esmMin((() => {}));
1243
1093
 
1244
- //#endregion
1245
- //#region node_modules/date-fns/isExists.js
1094
+ // node_modules/date-fns/isExists.js
1246
1095
  var init_isExists = __esmMin((() => {}));
1247
1096
 
1248
- //#endregion
1249
- //#region node_modules/date-fns/isFirstDayOfMonth.js
1097
+ // node_modules/date-fns/isFirstDayOfMonth.js
1250
1098
  var init_isFirstDayOfMonth = __esmMin((() => {}));
1251
1099
 
1252
- //#endregion
1253
- //#region node_modules/date-fns/isFriday.js
1100
+ // node_modules/date-fns/isFriday.js
1254
1101
  var init_isFriday = __esmMin((() => {}));
1255
1102
 
1256
- //#endregion
1257
- //#region node_modules/date-fns/isFuture.js
1103
+ // node_modules/date-fns/isFuture.js
1258
1104
  var init_isFuture = __esmMin((() => {}));
1259
1105
 
1260
- //#endregion
1261
- //#region node_modules/date-fns/transpose.js
1106
+ // node_modules/date-fns/transpose.js
1262
1107
  var init_transpose = __esmMin((() => {}));
1263
1108
 
1264
- //#endregion
1265
- //#region node_modules/date-fns/setWeek.js
1109
+ // node_modules/date-fns/setWeek.js
1266
1110
  var init_setWeek = __esmMin((() => {}));
1267
1111
 
1268
- //#endregion
1269
- //#region node_modules/date-fns/setISOWeek.js
1112
+ // node_modules/date-fns/setISOWeek.js
1270
1113
  var init_setISOWeek = __esmMin((() => {}));
1271
1114
 
1272
- //#endregion
1273
- //#region node_modules/date-fns/setDay.js
1115
+ // node_modules/date-fns/setDay.js
1274
1116
  var init_setDay = __esmMin((() => {}));
1275
1117
 
1276
- //#endregion
1277
- //#region node_modules/date-fns/setISODay.js
1118
+ // node_modules/date-fns/setISODay.js
1278
1119
  var init_setISODay = __esmMin((() => {}));
1279
1120
 
1280
- //#endregion
1281
- //#region node_modules/date-fns/parse.js
1121
+ // node_modules/date-fns/parse.js
1282
1122
  var init_parse = __esmMin((() => {}));
1283
1123
 
1284
- //#endregion
1285
- //#region node_modules/date-fns/isMatch.js
1124
+ // node_modules/date-fns/isMatch.js
1286
1125
  var init_isMatch = __esmMin((() => {}));
1287
1126
 
1288
- //#endregion
1289
- //#region node_modules/date-fns/isMonday.js
1127
+ // node_modules/date-fns/isMonday.js
1290
1128
  var init_isMonday = __esmMin((() => {}));
1291
1129
 
1292
- //#endregion
1293
- //#region node_modules/date-fns/isPast.js
1130
+ // node_modules/date-fns/isPast.js
1294
1131
  var init_isPast = __esmMin((() => {}));
1295
1132
 
1296
- //#endregion
1297
- //#region node_modules/date-fns/startOfHour.js
1133
+ // node_modules/date-fns/startOfHour.js
1298
1134
  var init_startOfHour = __esmMin((() => {}));
1299
1135
 
1300
- //#endregion
1301
- //#region node_modules/date-fns/isSameHour.js
1136
+ // node_modules/date-fns/isSameHour.js
1302
1137
  var init_isSameHour = __esmMin((() => {}));
1303
1138
 
1304
- //#endregion
1305
- //#region node_modules/date-fns/isSameWeek.js
1139
+ // node_modules/date-fns/isSameWeek.js
1306
1140
  var init_isSameWeek = __esmMin((() => {}));
1307
1141
 
1308
- //#endregion
1309
- //#region node_modules/date-fns/isSameISOWeek.js
1142
+ // node_modules/date-fns/isSameISOWeek.js
1310
1143
  var init_isSameISOWeek = __esmMin((() => {}));
1311
1144
 
1312
- //#endregion
1313
- //#region node_modules/date-fns/isSameISOWeekYear.js
1145
+ // node_modules/date-fns/isSameISOWeekYear.js
1314
1146
  var init_isSameISOWeekYear = __esmMin((() => {}));
1315
1147
 
1316
- //#endregion
1317
- //#region node_modules/date-fns/startOfMinute.js
1148
+ // node_modules/date-fns/startOfMinute.js
1318
1149
  var init_startOfMinute = __esmMin((() => {}));
1319
1150
 
1320
- //#endregion
1321
- //#region node_modules/date-fns/isSameMinute.js
1151
+ // node_modules/date-fns/isSameMinute.js
1322
1152
  var init_isSameMinute = __esmMin((() => {}));
1323
1153
 
1324
- //#endregion
1325
- //#region node_modules/date-fns/isSameMonth.js
1154
+ // node_modules/date-fns/isSameMonth.js
1326
1155
  var init_isSameMonth = __esmMin((() => {}));
1327
1156
 
1328
- //#endregion
1329
- //#region node_modules/date-fns/isSameQuarter.js
1157
+ // node_modules/date-fns/isSameQuarter.js
1330
1158
  var init_isSameQuarter = __esmMin((() => {}));
1331
1159
 
1332
- //#endregion
1333
- //#region node_modules/date-fns/startOfSecond.js
1160
+ // node_modules/date-fns/startOfSecond.js
1334
1161
  var init_startOfSecond = __esmMin((() => {}));
1335
1162
 
1336
- //#endregion
1337
- //#region node_modules/date-fns/isSameSecond.js
1163
+ // node_modules/date-fns/isSameSecond.js
1338
1164
  var init_isSameSecond = __esmMin((() => {}));
1339
1165
 
1340
- //#endregion
1341
- //#region node_modules/date-fns/isSameYear.js
1166
+ // node_modules/date-fns/isSameYear.js
1342
1167
  var init_isSameYear = __esmMin((() => {}));
1343
1168
 
1344
- //#endregion
1345
- //#region node_modules/date-fns/isThisHour.js
1169
+ // node_modules/date-fns/isThisHour.js
1346
1170
  var init_isThisHour = __esmMin((() => {}));
1347
1171
 
1348
- //#endregion
1349
- //#region node_modules/date-fns/isThisISOWeek.js
1172
+ // node_modules/date-fns/isThisISOWeek.js
1350
1173
  var init_isThisISOWeek = __esmMin((() => {}));
1351
1174
 
1352
- //#endregion
1353
- //#region node_modules/date-fns/isThisMinute.js
1175
+ // node_modules/date-fns/isThisMinute.js
1354
1176
  var init_isThisMinute = __esmMin((() => {}));
1355
1177
 
1356
- //#endregion
1357
- //#region node_modules/date-fns/isThisMonth.js
1178
+ // node_modules/date-fns/isThisMonth.js
1358
1179
  var init_isThisMonth = __esmMin((() => {}));
1359
1180
 
1360
- //#endregion
1361
- //#region node_modules/date-fns/isThisQuarter.js
1181
+ // node_modules/date-fns/isThisQuarter.js
1362
1182
  var init_isThisQuarter = __esmMin((() => {}));
1363
1183
 
1364
- //#endregion
1365
- //#region node_modules/date-fns/isThisSecond.js
1184
+ // node_modules/date-fns/isThisSecond.js
1366
1185
  var init_isThisSecond = __esmMin((() => {}));
1367
1186
 
1368
- //#endregion
1369
- //#region node_modules/date-fns/isThisWeek.js
1187
+ // node_modules/date-fns/isThisWeek.js
1370
1188
  var init_isThisWeek = __esmMin((() => {}));
1371
1189
 
1372
- //#endregion
1373
- //#region node_modules/date-fns/isThisYear.js
1190
+ // node_modules/date-fns/isThisYear.js
1374
1191
  var init_isThisYear = __esmMin((() => {}));
1375
1192
 
1376
- //#endregion
1377
- //#region node_modules/date-fns/isThursday.js
1193
+ // node_modules/date-fns/isThursday.js
1378
1194
  var init_isThursday = __esmMin((() => {}));
1379
1195
 
1380
- //#endregion
1381
- //#region node_modules/date-fns/isToday.js
1196
+ // node_modules/date-fns/isToday.js
1382
1197
  var init_isToday = __esmMin((() => {}));
1383
1198
 
1384
- //#endregion
1385
- //#region node_modules/date-fns/isTomorrow.js
1199
+ // node_modules/date-fns/isTomorrow.js
1386
1200
  var init_isTomorrow = __esmMin((() => {}));
1387
1201
 
1388
- //#endregion
1389
- //#region node_modules/date-fns/isTuesday.js
1202
+ // node_modules/date-fns/isTuesday.js
1390
1203
  var init_isTuesday = __esmMin((() => {}));
1391
1204
 
1392
- //#endregion
1393
- //#region node_modules/date-fns/isWednesday.js
1205
+ // node_modules/date-fns/isWednesday.js
1394
1206
  var init_isWednesday = __esmMin((() => {}));
1395
1207
 
1396
- //#endregion
1397
- //#region node_modules/date-fns/isWithinInterval.js
1208
+ // node_modules/date-fns/isWithinInterval.js
1398
1209
  var init_isWithinInterval = __esmMin((() => {}));
1399
1210
 
1400
- //#endregion
1401
- //#region node_modules/date-fns/subDays.js
1211
+ // node_modules/date-fns/subDays.js
1402
1212
  /**
1403
1213
  * The {@link subDays} function options.
1404
1214
  */
@@ -1428,296 +1238,223 @@ var init_subDays = __esmMin((() => {
1428
1238
  init_addDays();
1429
1239
  }));
1430
1240
 
1431
- //#endregion
1432
- //#region node_modules/date-fns/isYesterday.js
1241
+ // node_modules/date-fns/isYesterday.js
1433
1242
  var init_isYesterday = __esmMin((() => {}));
1434
1243
 
1435
- //#endregion
1436
- //#region node_modules/date-fns/lastDayOfDecade.js
1244
+ // node_modules/date-fns/lastDayOfDecade.js
1437
1245
  var init_lastDayOfDecade = __esmMin((() => {}));
1438
1246
 
1439
- //#endregion
1440
- //#region node_modules/date-fns/lastDayOfWeek.js
1247
+ // node_modules/date-fns/lastDayOfWeek.js
1441
1248
  var init_lastDayOfWeek = __esmMin((() => {}));
1442
1249
 
1443
- //#endregion
1444
- //#region node_modules/date-fns/lastDayOfISOWeek.js
1250
+ // node_modules/date-fns/lastDayOfISOWeek.js
1445
1251
  var init_lastDayOfISOWeek = __esmMin((() => {}));
1446
1252
 
1447
- //#endregion
1448
- //#region node_modules/date-fns/lastDayOfISOWeekYear.js
1253
+ // node_modules/date-fns/lastDayOfISOWeekYear.js
1449
1254
  var init_lastDayOfISOWeekYear = __esmMin((() => {}));
1450
1255
 
1451
- //#endregion
1452
- //#region node_modules/date-fns/lastDayOfQuarter.js
1256
+ // node_modules/date-fns/lastDayOfQuarter.js
1453
1257
  var init_lastDayOfQuarter = __esmMin((() => {}));
1454
1258
 
1455
- //#endregion
1456
- //#region node_modules/date-fns/lastDayOfYear.js
1259
+ // node_modules/date-fns/lastDayOfYear.js
1457
1260
  var init_lastDayOfYear = __esmMin((() => {}));
1458
1261
 
1459
- //#endregion
1460
- //#region node_modules/date-fns/lightFormat.js
1262
+ // node_modules/date-fns/lightFormat.js
1461
1263
  var init_lightFormat = __esmMin((() => {}));
1462
1264
 
1463
- //#endregion
1464
- //#region node_modules/date-fns/milliseconds.js
1265
+ // node_modules/date-fns/milliseconds.js
1465
1266
  var init_milliseconds = __esmMin((() => {}));
1466
1267
 
1467
- //#endregion
1468
- //#region node_modules/date-fns/millisecondsToHours.js
1268
+ // node_modules/date-fns/millisecondsToHours.js
1469
1269
  var init_millisecondsToHours = __esmMin((() => {}));
1470
1270
 
1471
- //#endregion
1472
- //#region node_modules/date-fns/millisecondsToMinutes.js
1271
+ // node_modules/date-fns/millisecondsToMinutes.js
1473
1272
  var init_millisecondsToMinutes = __esmMin((() => {}));
1474
1273
 
1475
- //#endregion
1476
- //#region node_modules/date-fns/millisecondsToSeconds.js
1274
+ // node_modules/date-fns/millisecondsToSeconds.js
1477
1275
  var init_millisecondsToSeconds = __esmMin((() => {}));
1478
1276
 
1479
- //#endregion
1480
- //#region node_modules/date-fns/minutesToHours.js
1277
+ // node_modules/date-fns/minutesToHours.js
1481
1278
  var init_minutesToHours = __esmMin((() => {}));
1482
1279
 
1483
- //#endregion
1484
- //#region node_modules/date-fns/minutesToMilliseconds.js
1280
+ // node_modules/date-fns/minutesToMilliseconds.js
1485
1281
  var init_minutesToMilliseconds = __esmMin((() => {}));
1486
1282
 
1487
- //#endregion
1488
- //#region node_modules/date-fns/minutesToSeconds.js
1283
+ // node_modules/date-fns/minutesToSeconds.js
1489
1284
  var init_minutesToSeconds = __esmMin((() => {}));
1490
1285
 
1491
- //#endregion
1492
- //#region node_modules/date-fns/monthsToQuarters.js
1286
+ // node_modules/date-fns/monthsToQuarters.js
1493
1287
  var init_monthsToQuarters = __esmMin((() => {}));
1494
1288
 
1495
- //#endregion
1496
- //#region node_modules/date-fns/monthsToYears.js
1289
+ // node_modules/date-fns/monthsToYears.js
1497
1290
  var init_monthsToYears = __esmMin((() => {}));
1498
1291
 
1499
- //#endregion
1500
- //#region node_modules/date-fns/nextDay.js
1292
+ // node_modules/date-fns/nextDay.js
1501
1293
  var init_nextDay = __esmMin((() => {}));
1502
1294
 
1503
- //#endregion
1504
- //#region node_modules/date-fns/nextFriday.js
1295
+ // node_modules/date-fns/nextFriday.js
1505
1296
  var init_nextFriday = __esmMin((() => {}));
1506
1297
 
1507
- //#endregion
1508
- //#region node_modules/date-fns/nextMonday.js
1298
+ // node_modules/date-fns/nextMonday.js
1509
1299
  var init_nextMonday = __esmMin((() => {}));
1510
1300
 
1511
- //#endregion
1512
- //#region node_modules/date-fns/nextSaturday.js
1301
+ // node_modules/date-fns/nextSaturday.js
1513
1302
  var init_nextSaturday = __esmMin((() => {}));
1514
1303
 
1515
- //#endregion
1516
- //#region node_modules/date-fns/nextSunday.js
1304
+ // node_modules/date-fns/nextSunday.js
1517
1305
  var init_nextSunday = __esmMin((() => {}));
1518
1306
 
1519
- //#endregion
1520
- //#region node_modules/date-fns/nextThursday.js
1307
+ // node_modules/date-fns/nextThursday.js
1521
1308
  var init_nextThursday = __esmMin((() => {}));
1522
1309
 
1523
- //#endregion
1524
- //#region node_modules/date-fns/nextTuesday.js
1310
+ // node_modules/date-fns/nextTuesday.js
1525
1311
  var init_nextTuesday = __esmMin((() => {}));
1526
1312
 
1527
- //#endregion
1528
- //#region node_modules/date-fns/nextWednesday.js
1313
+ // node_modules/date-fns/nextWednesday.js
1529
1314
  var init_nextWednesday = __esmMin((() => {}));
1530
1315
 
1531
- //#endregion
1532
- //#region node_modules/date-fns/parseISO.js
1316
+ // node_modules/date-fns/parseISO.js
1533
1317
  var init_parseISO = __esmMin((() => {}));
1534
1318
 
1535
- //#endregion
1536
- //#region node_modules/date-fns/parseJSON.js
1319
+ // node_modules/date-fns/parseJSON.js
1537
1320
  var init_parseJSON = __esmMin((() => {}));
1538
1321
 
1539
- //#endregion
1540
- //#region node_modules/date-fns/previousDay.js
1322
+ // node_modules/date-fns/previousDay.js
1541
1323
  var init_previousDay = __esmMin((() => {}));
1542
1324
 
1543
- //#endregion
1544
- //#region node_modules/date-fns/previousFriday.js
1325
+ // node_modules/date-fns/previousFriday.js
1545
1326
  var init_previousFriday = __esmMin((() => {}));
1546
1327
 
1547
- //#endregion
1548
- //#region node_modules/date-fns/previousMonday.js
1328
+ // node_modules/date-fns/previousMonday.js
1549
1329
  var init_previousMonday = __esmMin((() => {}));
1550
1330
 
1551
- //#endregion
1552
- //#region node_modules/date-fns/previousSaturday.js
1331
+ // node_modules/date-fns/previousSaturday.js
1553
1332
  var init_previousSaturday = __esmMin((() => {}));
1554
1333
 
1555
- //#endregion
1556
- //#region node_modules/date-fns/previousSunday.js
1334
+ // node_modules/date-fns/previousSunday.js
1557
1335
  var init_previousSunday = __esmMin((() => {}));
1558
1336
 
1559
- //#endregion
1560
- //#region node_modules/date-fns/previousThursday.js
1337
+ // node_modules/date-fns/previousThursday.js
1561
1338
  var init_previousThursday = __esmMin((() => {}));
1562
1339
 
1563
- //#endregion
1564
- //#region node_modules/date-fns/previousTuesday.js
1340
+ // node_modules/date-fns/previousTuesday.js
1565
1341
  var init_previousTuesday = __esmMin((() => {}));
1566
1342
 
1567
- //#endregion
1568
- //#region node_modules/date-fns/previousWednesday.js
1343
+ // node_modules/date-fns/previousWednesday.js
1569
1344
  var init_previousWednesday = __esmMin((() => {}));
1570
1345
 
1571
- //#endregion
1572
- //#region node_modules/date-fns/quartersToMonths.js
1346
+ // node_modules/date-fns/quartersToMonths.js
1573
1347
  var init_quartersToMonths = __esmMin((() => {}));
1574
1348
 
1575
- //#endregion
1576
- //#region node_modules/date-fns/quartersToYears.js
1349
+ // node_modules/date-fns/quartersToYears.js
1577
1350
  var init_quartersToYears = __esmMin((() => {}));
1578
1351
 
1579
- //#endregion
1580
- //#region node_modules/date-fns/roundToNearestHours.js
1352
+ // node_modules/date-fns/roundToNearestHours.js
1581
1353
  var init_roundToNearestHours = __esmMin((() => {}));
1582
1354
 
1583
- //#endregion
1584
- //#region node_modules/date-fns/roundToNearestMinutes.js
1355
+ // node_modules/date-fns/roundToNearestMinutes.js
1585
1356
  var init_roundToNearestMinutes = __esmMin((() => {}));
1586
1357
 
1587
- //#endregion
1588
- //#region node_modules/date-fns/secondsToHours.js
1358
+ // node_modules/date-fns/secondsToHours.js
1589
1359
  var init_secondsToHours = __esmMin((() => {}));
1590
1360
 
1591
- //#endregion
1592
- //#region node_modules/date-fns/secondsToMilliseconds.js
1361
+ // node_modules/date-fns/secondsToMilliseconds.js
1593
1362
  var init_secondsToMilliseconds = __esmMin((() => {}));
1594
1363
 
1595
- //#endregion
1596
- //#region node_modules/date-fns/secondsToMinutes.js
1364
+ // node_modules/date-fns/secondsToMinutes.js
1597
1365
  var init_secondsToMinutes = __esmMin((() => {}));
1598
1366
 
1599
- //#endregion
1600
- //#region node_modules/date-fns/setMonth.js
1367
+ // node_modules/date-fns/setMonth.js
1601
1368
  var init_setMonth = __esmMin((() => {}));
1602
1369
 
1603
- //#endregion
1604
- //#region node_modules/date-fns/set.js
1370
+ // node_modules/date-fns/set.js
1605
1371
  var init_set = __esmMin((() => {}));
1606
1372
 
1607
- //#endregion
1608
- //#region node_modules/date-fns/setDate.js
1373
+ // node_modules/date-fns/setDate.js
1609
1374
  var init_setDate = __esmMin((() => {}));
1610
1375
 
1611
- //#endregion
1612
- //#region node_modules/date-fns/setDayOfYear.js
1376
+ // node_modules/date-fns/setDayOfYear.js
1613
1377
  var init_setDayOfYear = __esmMin((() => {}));
1614
1378
 
1615
- //#endregion
1616
- //#region node_modules/date-fns/setDefaultOptions.js
1379
+ // node_modules/date-fns/setDefaultOptions.js
1617
1380
  var init_setDefaultOptions = __esmMin((() => {}));
1618
1381
 
1619
- //#endregion
1620
- //#region node_modules/date-fns/setHours.js
1382
+ // node_modules/date-fns/setHours.js
1621
1383
  var init_setHours = __esmMin((() => {}));
1622
1384
 
1623
- //#endregion
1624
- //#region node_modules/date-fns/setMilliseconds.js
1385
+ // node_modules/date-fns/setMilliseconds.js
1625
1386
  var init_setMilliseconds = __esmMin((() => {}));
1626
1387
 
1627
- //#endregion
1628
- //#region node_modules/date-fns/setMinutes.js
1388
+ // node_modules/date-fns/setMinutes.js
1629
1389
  var init_setMinutes = __esmMin((() => {}));
1630
1390
 
1631
- //#endregion
1632
- //#region node_modules/date-fns/setQuarter.js
1391
+ // node_modules/date-fns/setQuarter.js
1633
1392
  var init_setQuarter = __esmMin((() => {}));
1634
1393
 
1635
- //#endregion
1636
- //#region node_modules/date-fns/setSeconds.js
1394
+ // node_modules/date-fns/setSeconds.js
1637
1395
  var init_setSeconds = __esmMin((() => {}));
1638
1396
 
1639
- //#endregion
1640
- //#region node_modules/date-fns/setWeekYear.js
1397
+ // node_modules/date-fns/setWeekYear.js
1641
1398
  var init_setWeekYear = __esmMin((() => {}));
1642
1399
 
1643
- //#endregion
1644
- //#region node_modules/date-fns/setYear.js
1400
+ // node_modules/date-fns/setYear.js
1645
1401
  var init_setYear = __esmMin((() => {}));
1646
1402
 
1647
- //#endregion
1648
- //#region node_modules/date-fns/startOfDecade.js
1403
+ // node_modules/date-fns/startOfDecade.js
1649
1404
  var init_startOfDecade = __esmMin((() => {}));
1650
1405
 
1651
- //#endregion
1652
- //#region node_modules/date-fns/startOfToday.js
1406
+ // node_modules/date-fns/startOfToday.js
1653
1407
  var init_startOfToday = __esmMin((() => {}));
1654
1408
 
1655
- //#endregion
1656
- //#region node_modules/date-fns/startOfTomorrow.js
1409
+ // node_modules/date-fns/startOfTomorrow.js
1657
1410
  var init_startOfTomorrow = __esmMin((() => {}));
1658
1411
 
1659
- //#endregion
1660
- //#region node_modules/date-fns/startOfYesterday.js
1412
+ // node_modules/date-fns/startOfYesterday.js
1661
1413
  var init_startOfYesterday = __esmMin((() => {}));
1662
1414
 
1663
- //#endregion
1664
- //#region node_modules/date-fns/subMonths.js
1415
+ // node_modules/date-fns/subMonths.js
1665
1416
  var init_subMonths = __esmMin((() => {}));
1666
1417
 
1667
- //#endregion
1668
- //#region node_modules/date-fns/sub.js
1418
+ // node_modules/date-fns/sub.js
1669
1419
  var init_sub = __esmMin((() => {}));
1670
1420
 
1671
- //#endregion
1672
- //#region node_modules/date-fns/subBusinessDays.js
1421
+ // node_modules/date-fns/subBusinessDays.js
1673
1422
  var init_subBusinessDays = __esmMin((() => {}));
1674
1423
 
1675
- //#endregion
1676
- //#region node_modules/date-fns/subHours.js
1424
+ // node_modules/date-fns/subHours.js
1677
1425
  var init_subHours = __esmMin((() => {}));
1678
1426
 
1679
- //#endregion
1680
- //#region node_modules/date-fns/subMilliseconds.js
1427
+ // node_modules/date-fns/subMilliseconds.js
1681
1428
  var init_subMilliseconds = __esmMin((() => {}));
1682
1429
 
1683
- //#endregion
1684
- //#region node_modules/date-fns/subMinutes.js
1430
+ // node_modules/date-fns/subMinutes.js
1685
1431
  var init_subMinutes = __esmMin((() => {}));
1686
1432
 
1687
- //#endregion
1688
- //#region node_modules/date-fns/subQuarters.js
1433
+ // node_modules/date-fns/subQuarters.js
1689
1434
  var init_subQuarters = __esmMin((() => {}));
1690
1435
 
1691
- //#endregion
1692
- //#region node_modules/date-fns/subSeconds.js
1436
+ // node_modules/date-fns/subSeconds.js
1693
1437
  var init_subSeconds = __esmMin((() => {}));
1694
1438
 
1695
- //#endregion
1696
- //#region node_modules/date-fns/subWeeks.js
1439
+ // node_modules/date-fns/subWeeks.js
1697
1440
  var init_subWeeks = __esmMin((() => {}));
1698
1441
 
1699
- //#endregion
1700
- //#region node_modules/date-fns/subYears.js
1442
+ // node_modules/date-fns/subYears.js
1701
1443
  var init_subYears = __esmMin((() => {}));
1702
1444
 
1703
- //#endregion
1704
- //#region node_modules/date-fns/weeksToDays.js
1445
+ // node_modules/date-fns/weeksToDays.js
1705
1446
  var init_weeksToDays = __esmMin((() => {}));
1706
1447
 
1707
- //#endregion
1708
- //#region node_modules/date-fns/yearsToDays.js
1448
+ // node_modules/date-fns/yearsToDays.js
1709
1449
  var init_yearsToDays = __esmMin((() => {}));
1710
1450
 
1711
- //#endregion
1712
- //#region node_modules/date-fns/yearsToMonths.js
1451
+ // node_modules/date-fns/yearsToMonths.js
1713
1452
  var init_yearsToMonths = __esmMin((() => {}));
1714
1453
 
1715
- //#endregion
1716
- //#region node_modules/date-fns/yearsToQuarters.js
1454
+ // node_modules/date-fns/yearsToQuarters.js
1717
1455
  var init_yearsToQuarters = __esmMin((() => {}));
1718
1456
 
1719
- //#endregion
1720
- //#region node_modules/date-fns/index.js
1457
+ // node_modules/date-fns/index.js
1721
1458
  var init_date_fns = __esmMin((() => {
1722
1459
  init_add();
1723
1460
  init_addBusinessDays();
@@ -1966,8 +1703,7 @@ var init_date_fns = __esmMin((() => {
1966
1703
  init_yearsToQuarters();
1967
1704
  }));
1968
1705
 
1969
- //#endregion
1970
- //#region src/lib/format.ts
1706
+ // src/lib/format.ts
1971
1707
  function parseDate$1(value) {
1972
1708
  const raw = value.trim();
1973
1709
  if (!raw) return /* @__PURE__ */ new Date(NaN);
@@ -2006,8 +1742,7 @@ var init_format = __esmMin((() => {
2006
1742
  init_clock();
2007
1743
  }));
2008
1744
 
2009
- //#endregion
2010
- //#region src/lib/dates.ts
1745
+ // src/lib/dates.ts
2011
1746
  init_date_fns();
2012
1747
  /** A sensible default end for a new child: the usual horizon, but never past the parent's end when that is still ahead. */
2013
1748
  function clampEndToParent(proposedEnd, parentEnd, today) {
@@ -2042,8 +1777,7 @@ function workingDaysBetween(from, to) {
2042
1777
  return count;
2043
1778
  }
2044
1779
 
2045
- //#endregion
2046
- //#region src/lib/blockers.ts
1780
+ // src/lib/blockers.ts
2047
1781
  /** Every id this item waits on, without duplicates or itself. */
2048
1782
  function blockerIds(item) {
2049
1783
  const list = Array.isArray(item.blockedByIds) ? item.blockedByIds : item.blockedById ? [item.blockedById] : [];
@@ -2104,8 +1838,7 @@ var init_blockers = __esmMin((() => {
2104
1838
  lookups = /* @__PURE__ */ new WeakMap();
2105
1839
  }));
2106
1840
 
2107
- //#endregion
2108
- //#region src/lib/indexes.ts
1841
+ // src/lib/indexes.ts
2109
1842
  function cached$1(store, items, build) {
2110
1843
  const hit = store.get(items);
2111
1844
  if (hit && hit.size === items.length) return hit.value;
@@ -2175,8 +1908,7 @@ var init_indexes = __esmMin((() => {
2175
1908
  positions = /* @__PURE__ */ new WeakMap();
2176
1909
  }));
2177
1910
 
2178
- //#endregion
2179
- //#region src/lib/premortem.ts
1911
+ // src/lib/premortem.ts
2180
1912
  function premortemPhase(project, now) {
2181
1913
  const pm = project.premortem;
2182
1914
  if (!pm) return "none";
@@ -2306,8 +2038,7 @@ var init_premortem = __esmMin((() => {
2306
2038
  STOP = new Set("the a an and or but of to in on for with at by from into onto was were be been being is are it its this that these those we our us they them their he she his her i my me you your had has have did do does not no so too very just than then there here what which who because about after before over under again more most some any all each other only own same can could would should will got get project failed happened went".split(" "));
2307
2039
  }));
2308
2040
 
2309
- //#endregion
2310
- //#region src/lib/soundings.ts
2041
+ // src/lib/soundings.ts
2311
2042
  /** Why a number can't be an answer, or null when it can: half days up to SOUNDING_MAX_DAYS. */
2312
2043
  function daysProblem(days) {
2313
2044
  if (!Number.isFinite(days) || days <= 0) return "Give a number of days above 0, like 3 or 0.5.";
@@ -2445,8 +2176,7 @@ var init_soundings = __esmMin((() => {
2445
2176
  SOUNDING_MAX_DAYS = 250;
2446
2177
  }));
2447
2178
 
2448
- //#endregion
2449
- //#region src/lib/countries.ts
2179
+ // src/lib/countries.ts
2450
2180
  /** A country code Harbor has holidays for, upper-cased; null otherwise. */
2451
2181
  function countryCode(text) {
2452
2182
  if (!text) return null;
@@ -2517,8 +2247,7 @@ var init_countries = __esmMin((() => {
2517
2247
  countryName = (code) => COUNTRIES.find((c) => c.code === code)?.name ?? code;
2518
2248
  }));
2519
2249
 
2520
- //#endregion
2521
- //#region src/lib/holidays.ts
2250
+ // src/lib/holidays.ts
2522
2251
  /** Easter Sunday (the anonymous Gregorian algorithm). */
2523
2252
  function easter(year) {
2524
2253
  const a = year % 19;
@@ -2942,8 +2671,7 @@ var init_holidays = __esmMin((() => {
2942
2671
  PLAIN_CALENDAR = workCalendar({ people: [] });
2943
2672
  }));
2944
2673
 
2945
- //#endregion
2946
- //#region src/lib/tide.ts
2674
+ // src/lib/tide.ts
2947
2675
  /** Tasks finished in each of the last weeks, oldest first. Done tasks without a date, or dated after now, count as finished now. */
2948
2676
  function weeklyFinished(tasks, startDate, now, weeks = 6) {
2949
2677
  const today = noon$3(todayISO(now));
@@ -3222,8 +2950,7 @@ var init_tide = __esmMin((() => {
3222
2950
  noon$3 = (iso) => /* @__PURE__ */ new Date(`${iso.slice(0, 10)}T12:00:00`);
3223
2951
  }));
3224
2952
 
3225
- //#endregion
3226
- //#region src/lib/barnacles.ts
2953
+ // src/lib/barnacles.ts
3227
2954
  /**
3228
2955
  * When the plan was set: when the baseline was set, else a week after the
3229
2956
  * project's first task was made (the first week is the plan being written).
@@ -3358,8 +3085,7 @@ var init_barnacles = __esmMin((() => {
3358
3085
  plural$7 = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
3359
3086
  }));
3360
3087
 
3361
- //#endregion
3362
- //#region src/lib/task-keys.ts
3088
+ // src/lib/task-keys.ts
3363
3089
  /** "Ridge Runner" → "RR", "Website" → "WEB", "Q4 launch plan" → "QLP". */
3364
3090
  function baseKey(name) {
3365
3091
  const words = name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^A-Za-z0-9 ]+/g, " ").split(/\s+/).filter((w) => /[A-Za-z]/.test(w));
@@ -3533,8 +3259,7 @@ var init_task_keys = __esmMin((() => {
3533
3259
  KEY_TEXT = /^([A-Za-z][A-Za-z0-9]{0,9})-(\d{1,7})$/;
3534
3260
  }));
3535
3261
 
3536
- //#endregion
3537
- //#region src/lib/thanks.ts
3262
+ // src/lib/thanks.ts
3538
3263
  /** What a thanks is for, read from the harbor; null once that's gone. */
3539
3264
  function thanksTarget(doc, on) {
3540
3265
  if (on.kind === "task") {
@@ -3604,8 +3329,7 @@ var init_thanks = __esmMin((() => {
3604
3329
  first$2 = (doc, id) => doc.people.find((p) => p.id === id)?.name.split(" ")[0] ?? "Someone";
3605
3330
  }));
3606
3331
 
3607
- //#endregion
3608
- //#region src/lib/charter-lines.ts
3332
+ // src/lib/charter-lines.ts
3609
3333
  /** Nothing written on any of the five lines. */
3610
3334
  function charterEmpty(charter) {
3611
3335
  return !charter || CHARTER_FIELDS.every((f) => !clean(charter[f]));
@@ -3640,8 +3364,7 @@ var init_charter_lines = __esmMin((() => {
3640
3364
  clean = (s) => (s ?? "").replace(/\s+/g, " ").trim();
3641
3365
  }));
3642
3366
 
3643
- //#endregion
3644
- //#region src/lib/charter.ts
3367
+ // src/lib/charter.ts
3645
3368
  init_barnacles();
3646
3369
  init_thanks();
3647
3370
  init_date_fns();
@@ -3759,8 +3482,7 @@ function charterSentence(check) {
3759
3482
  return `Against the charter: ${bits.join("; ")}.`;
3760
3483
  }
3761
3484
 
3762
- //#endregion
3763
- //#region src/lib/voyage-log.ts
3485
+ // src/lib/voyage-log.ts
3764
3486
  init_date_fns();
3765
3487
  init_blockers();
3766
3488
  init_date_text();
@@ -3902,8 +3624,7 @@ function voyageStory(log) {
3902
3624
  return out;
3903
3625
  }
3904
3626
 
3905
- //#endregion
3906
- //#region src/lib/dead-reckoning.ts
3627
+ // src/lib/dead-reckoning.ts
3907
3628
  init_date_fns();
3908
3629
  init_date_text();
3909
3630
  init_format();
@@ -4032,8 +3753,7 @@ function applyReckoning(actions, projectId, r, startDate) {
4032
3753
  };
4033
3754
  }
4034
3755
 
4035
- //#endregion
4036
- //#region src/lib/raid.ts
3756
+ // src/lib/raid.ts
4037
3757
  /** Still needs someone's attention: not closed, resolved, decided or superseded. */
4038
3758
  function isActive(item) {
4039
3759
  return item.status === "open" || item.status === "watching" || item.status === "mitigated" || item.status === "proposed";
@@ -4243,8 +3963,7 @@ var init_raid = __esmMin((() => {
4243
3963
  ids = (v) => Array.isArray(v) ? [...new Set(v.filter((x) => typeof x === "string" && !!x))] : [];
4244
3964
  }));
4245
3965
 
4246
- //#endregion
4247
- //#region src/lib/swatches.ts
3966
+ // src/lib/swatches.ts
4248
3967
  var SWATCHES, HEALTH_LABEL$1, TASK_COLUMNS, TASK_STATUS_LABEL, PRIORITY_LABEL, CONSTRAINT_KIND_LABEL, CONSTRAINT_KIND_HINT;
4249
3968
  var init_swatches = __esmMin((() => {
4250
3969
  SWATCHES = [
@@ -4298,8 +4017,7 @@ var init_swatches = __esmMin((() => {
4298
4017
  };
4299
4018
  }));
4300
4019
 
4301
- //#endregion
4302
- //#region src/tui/create.ts
4020
+ // src/tui/create.ts
4303
4021
  init_date_fns();
4304
4022
  init_format();
4305
4023
  init_indexes();
@@ -4627,8 +4345,80 @@ function commitCreate(store, kind, v, ctx, today) {
4627
4345
  }
4628
4346
  }
4629
4347
 
4630
- //#endregion
4631
- //#region src/lib/board.ts
4348
+ // src/lib/agents.ts
4349
+ /** What an agent should work on: its open tasks not yet waiting on review, in progress first, then most urgent and soonest. */
4350
+ function agentQueue(data, agentId) {
4351
+ return data.tasks.filter((t) => t.assigneeId === agentId && (t.status === "todo" || t.status === "doing" || t.status === "backlog")).sort((a, b) => Number(b.status === "doing") - Number(a.status === "doing") || Number(a.status === "backlog") - Number(b.status === "backlog") || RANK[a.priority] - RANK[b.priority] || (a.dueDate ?? "9999").localeCompare(b.dueDate ?? "9999"));
4352
+ }
4353
+ /** The agent an app means: the one named, else the only one on the crew. */
4354
+ function pickAgent(people, key) {
4355
+ const agents = people.filter(isAgent);
4356
+ if (agents.length === 0) return "There are no agents on this harbor's crew yet. Someone adds one on People with Add an agent.";
4357
+ if (!key) {
4358
+ if (agents.length === 1) return agents[0];
4359
+ return `This harbor has ${agents.length} agents (${agents.map((a) => a.name).join(", ")}). Say which with agent.`;
4360
+ }
4361
+ const k = key.trim().toLowerCase();
4362
+ return agents.find((a) => a.id === key.trim() || a.name.trim().toLowerCase() === k) ?? `No agent called "${key}". The crew's agents: ${agents.map((a) => a.name).join(", ")}.`;
4363
+ }
4364
+ var isAgent, RANK;
4365
+ var init_agents = __esmMin((() => {
4366
+ isAgent = (p) => p?.kind === "agent";
4367
+ RANK = {
4368
+ urgent: 0,
4369
+ high: 1,
4370
+ medium: 2,
4371
+ low: 3
4372
+ };
4373
+ }));
4374
+
4375
+ // src/lib/task-people.ts
4376
+ /** Everyone also on a task, owner left out, each once, in the order they were added. */
4377
+ function alsoOnIds(task) {
4378
+ const out = [];
4379
+ for (const id of task.followerIds ?? []) if (id && id !== task.assigneeId && !out.includes(id)) out.push(id);
4380
+ return out;
4381
+ }
4382
+ /** Whether a person owns the task or is also on it. */
4383
+ function isOnTask(task, personId) {
4384
+ return task.assigneeId === personId || (task.followerIds ?? []).includes(personId);
4385
+ }
4386
+ /** The patch that sets who else is on a task: the owner and duplicates dropped, [] clears it. */
4387
+ function alsoOnPatch(task, ids) {
4388
+ return { followerIds: alsoOnIds({
4389
+ assigneeId: task.assigneeId,
4390
+ followerIds: [...ids]
4391
+ }) };
4392
+ }
4393
+ /** Who can be put on a task alongside its owner: people (not agents) who aren't on it yet. */
4394
+ function alsoOnChoices(task, people) {
4395
+ const on = /* @__PURE__ */ new Set([task.assigneeId, ...alsoOnIds(task)]);
4396
+ return people.filter((p) => !isAgent(p) && !on.has(p.id));
4397
+ }
4398
+ /** Open tasks someone is also on but doesn't own: the ones they help with. */
4399
+ function tasksAlsoOn(data, personId) {
4400
+ return data.tasks.filter((t) => t.status !== "done" && t.assigneeId !== personId && (t.followerIds ?? []).includes(personId));
4401
+ }
4402
+ /** Every file on a project's tasks, newest first; `kind` keeps one sort (images, docs or links). */
4403
+ function projectFiles(data, projectId, kind) {
4404
+ const tasks = byId(tasksOf(data.tasks, projectId));
4405
+ const out = [];
4406
+ for (const file of data.attachments ?? []) {
4407
+ const task = tasks.get(file.taskId);
4408
+ if (!task || kind && file.kind !== kind) continue;
4409
+ out.push({
4410
+ file,
4411
+ task
4412
+ });
4413
+ }
4414
+ return out.sort((a, b) => b.file.addedAt.localeCompare(a.file.addedAt));
4415
+ }
4416
+ var init_task_people = __esmMin((() => {
4417
+ init_indexes();
4418
+ init_agents();
4419
+ }));
4420
+
4421
+ // src/lib/board.ts
4632
4422
  /** The column's cap after "No cap" (`uncapped`) or a number is picked. */
4633
4423
  function withWipLimit(col, limit) {
4634
4424
  const { uncapped: _drop, ...rest } = col;
@@ -4858,8 +4648,7 @@ var init_board = __esmMin((() => {
4858
4648
  ];
4859
4649
  }));
4860
4650
 
4861
- //#endregion
4862
- //#region src/lib/first-voyage.ts
4651
+ // src/lib/first-voyage.ts
4863
4652
  function isVoyageProject(projectId) {
4864
4653
  return projectId === VOYAGE_PROJECT_ID;
4865
4654
  }
@@ -4907,8 +4696,7 @@ var init_first_voyage = __esmMin((() => {
4907
4696
  SEEDED = new Set(STEPS.map((s) => voyageTaskId(s.step)));
4908
4697
  }));
4909
4698
 
4910
- //#endregion
4911
- //#region src/lib/passage.ts
4699
+ // src/lib/passage.ts
4912
4700
  /** Hours as a person would say them: "2h", "1.5h", "30m". */
4913
4701
  function hoursText(h) {
4914
4702
  if (h > 0 && h < 1) return `${Math.round(h * 60)}m`;
@@ -5064,8 +4852,8 @@ var init_passage = __esmMin((() => {
5064
4852
  ];
5065
4853
  }));
5066
4854
 
5067
- //#endregion
5068
- //#region src/lib/keep.ts
4855
+ // src/lib/keep.ts
4856
+ init_task_people();
5069
4857
  init_board();
5070
4858
  init_passage();
5071
4859
  /** Whole days left in the trial, rounded up: 30 on the first day, 1 on the last. 0 once it's over. */
@@ -5076,8 +4864,7 @@ function trialDaysLeft(trialEndsAt, now = /* @__PURE__ */ new Date()) {
5076
4864
  return Math.ceil(ms / 864e5);
5077
4865
  }
5078
4866
 
5079
- //#endregion
5080
- //#region src/lib/cascade.ts
4867
+ // src/lib/cascade.ts
5081
4868
  /** What deleting a portfolio, program, or project takes with it, and the data left behind. Pure. */
5082
4869
  function cascadeDelete(data, kind, id) {
5083
4870
  const portfolioIds = new Set(kind === "portfolio" ? [id] : []);
@@ -5136,8 +4923,7 @@ var init_cascade = __esmMin((() => {
5136
4923
  init_blockers();
5137
4924
  }));
5138
4925
 
5139
- //#endregion
5140
- //#region src/lib/forecast.ts
4926
+ // src/lib/forecast.ts
5141
4927
  init_cascade();
5142
4928
  init_date_fns();
5143
4929
  const day$7 = (iso) => /* @__PURE__ */ new Date(`${iso}T12:00:00`);
@@ -5174,8 +4960,7 @@ function forecastRollup(items, budget, now) {
5174
4960
  };
5175
4961
  }
5176
4962
 
5177
- //#endregion
5178
- //#region src/lib/flow.ts
4963
+ // src/lib/flow.ts
5179
4964
  function parse$1(value) {
5180
4965
  return parseIso(value.length === 10 ? `${value}T12:00:00` : value);
5181
4966
  }
@@ -5269,8 +5054,7 @@ var init_flow = __esmMin((() => {
5269
5054
  FLOW_MIN_HISTORY_DAYS = 7;
5270
5055
  }));
5271
5056
 
5272
- //#endregion
5273
- //#region src/lib/phasing.ts
5057
+ // src/lib/phasing.ts
5274
5058
  init_flow();
5275
5059
  init_date_fns();
5276
5060
  const day$6 = (iso) => /* @__PURE__ */ new Date(`${iso}T12:00:00`);
@@ -5338,8 +5122,7 @@ function withMonth(project, key, amount) {
5338
5122
  return next;
5339
5123
  }
5340
5124
 
5341
- //#endregion
5342
- //#region src/lib/spend.ts
5125
+ // src/lib/spend.ts
5343
5126
  function spendEntriesOf(data, projectId) {
5344
5127
  return (data.spendEntries ?? []).filter((e) => e.projectId === projectId).sort((a, b) => a.date.localeCompare(b.date));
5345
5128
  }
@@ -5360,8 +5143,7 @@ function adjustmentEntry(projectId, oldSpent, newSpent, date, id) {
5360
5143
  }
5361
5144
  var init_spend = __esmMin((() => {}));
5362
5145
 
5363
- //#endregion
5364
- //#region src/lib/selectors.ts
5146
+ // src/lib/selectors.ts
5365
5147
  init_indexes();
5366
5148
  function programsIn(data, portfolioId) {
5367
5149
  return data.programs.filter((p) => p.portfolioId === portfolioId);
@@ -5409,8 +5191,7 @@ function portfolioRaidItems(data, portfolioId) {
5409
5191
  return data.raidItems.filter((r) => r.portfolioId === portfolioId || r.programId != null && programIds.has(r.programId) || r.projectId != null && projectIds.has(r.projectId));
5410
5192
  }
5411
5193
 
5412
- //#endregion
5413
- //#region src/lib/baseline.ts
5194
+ // src/lib/baseline.ts
5414
5195
  function hasBaseline(p) {
5415
5196
  return Boolean(p.baselineStart && p.baselineEnd);
5416
5197
  }
@@ -5445,8 +5226,7 @@ var init_baseline = __esmMin((() => {
5445
5226
  day$5 = (iso) => /* @__PURE__ */ new Date(`${iso}T12:00:00`);
5446
5227
  }));
5447
5228
 
5448
- //#endregion
5449
- //#region src/lib/roadmap.ts
5229
+ // src/lib/roadmap.ts
5450
5230
  init_date_fns();
5451
5231
  init_date_text();
5452
5232
  init_blockers();
@@ -5589,8 +5369,7 @@ function roadmapRows(data, portfolioId, filter, collapsed, today) {
5589
5369
  return out;
5590
5370
  }
5591
5371
 
5592
- //#endregion
5593
- //#region src/lib/search.ts
5372
+ // src/lib/search.ts
5594
5373
  function tokensOf(query) {
5595
5374
  return query.toLowerCase().split(/\s+/).filter(Boolean);
5596
5375
  }
@@ -5657,8 +5436,7 @@ var init_search = __esmMin((() => {
5657
5436
  };
5658
5437
  }));
5659
5438
 
5660
- //#endregion
5661
- //#region src/lib/slip-cost.ts
5439
+ // src/lib/slip-cost.ts
5662
5440
  init_search();
5663
5441
  init_date_fns();
5664
5442
  init_format();
@@ -5743,8 +5521,7 @@ function programSlipCost(data, programId, now) {
5743
5521
  return sum;
5744
5522
  }
5745
5523
 
5746
- //#endregion
5747
- //#region src/lib/work.ts
5524
+ // src/lib/work.ts
5748
5525
  /** Every task this one waits on that still exists, done or not. */
5749
5526
  function blockersOf(task, tasks) {
5750
5527
  return blockersIn(task, tasks);
@@ -5785,8 +5562,11 @@ var init_work = __esmMin((() => {
5785
5562
  escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5786
5563
  }));
5787
5564
 
5788
- //#endregion
5789
- //#region src/tui/model.ts
5565
+ // src/tui/model.ts
5566
+ /**
5567
+ * What the terminal app's screens show, worked out from the harbor: kept
5568
+ * here, away from Ink, so it is tested like the rest of src/lib.
5569
+ */
5790
5570
  init_date_fns();
5791
5571
  init_date_text();
5792
5572
  init_first_voyage();
@@ -6012,7 +5792,7 @@ const NO_FILTER = {
6012
5792
  };
6013
5793
  function filterTasks(tasks, f) {
6014
5794
  if (f.who === "any" && f.priority === "any") return tasks;
6015
- return tasks.filter((t) => (f.who === "any" || (f.who === "none" ? t.assigneeId === null : t.assigneeId === f.who)) && (f.priority === "any" || t.priority === f.priority));
5795
+ return tasks.filter((t) => (f.who === "any" || (f.who === "none" ? t.assigneeId === null : isOnTask(t, f.who))) && (f.priority === "any" || t.priority === f.priority));
6016
5796
  }
6017
5797
  /**
6018
5798
  * When the project will likely finish at its crew's recent pace, in one
@@ -6489,8 +6269,7 @@ function weekReviewLines(data, me, monday) {
6489
6269
  return out;
6490
6270
  }
6491
6271
 
6492
- //#endregion
6493
- //#region src/tui/theme.ts
6272
+ // src/tui/theme.ts
6494
6273
  /**
6495
6274
  * Dark: Harbor's teal and coral lifted so they read on black, and status in
6496
6275
  * softened hues rather than the terminal's own loud green and yellow (a
@@ -6549,8 +6328,7 @@ function applyTheme(name) {
6549
6328
  }
6550
6329
  applyTheme("dark");
6551
6330
 
6552
- //#endregion
6553
- //#region src/tui/ui.tsx
6331
+ // src/tui/ui.tsx
6554
6332
  /**
6555
6333
  * The terminal app's small parts: a one-line text field, a list to pick
6556
6334
  * from, the key hints along the bottom, health and priority marks.
@@ -6735,8 +6513,7 @@ function Heading({ children, right }) {
6735
6513
  });
6736
6514
  }
6737
6515
 
6738
- //#endregion
6739
- //#region src/tui/forms.tsx
6516
+ // src/tui/forms.tsx
6740
6517
  /**
6741
6518
  * Two shapes most screens use: a panel of fields where Enter changes the
6742
6519
  * one picked (DetailPanel), and a few questions in a row to make something
@@ -6946,8 +6723,7 @@ function Stepper({ title, steps, width, onDone, onCancel }) {
6946
6723
  });
6947
6724
  }
6948
6725
 
6949
- //#endregion
6950
- //#region src/lib/health-history.ts
6726
+ // src/lib/health-history.ts
6951
6727
  /** The history with one more line when `health` differs from the last recorded one. Same array otherwise. */
6952
6728
  function recordHealth(history, health, at, override, note) {
6953
6729
  const last = history?.[history.length - 1];
@@ -6961,8 +6737,7 @@ function recordHealth(history, health, at, override, note) {
6961
6737
  }
6962
6738
  var init_health_history = __esmMin((() => {}));
6963
6739
 
6964
- //#endregion
6965
- //#region src/lib/derived-health.ts
6740
+ // src/lib/derived-health.ts
6966
6741
  function parseDate(value) {
6967
6742
  return parseIso(value.length === 10 ? `${value}T12:00:00` : value);
6968
6743
  }
@@ -7225,8 +7000,7 @@ var init_derived_health = __esmMin((() => {
7225
7000
  untilByDate = /* @__PURE__ */ new Map();
7226
7001
  }));
7227
7002
 
7228
- //#endregion
7229
- //#region src/lib/bottle-rules.ts
7003
+ // src/lib/bottle-rules.ts
7230
7004
  /**
7231
7005
  * Why a new note can't be sealed, or null when it can: nothing written, a
7232
7006
  * date that isn't after today (it would open at once), or a milestone that
@@ -7251,8 +7025,7 @@ var init_bottle_rules = __esmMin((() => {
7251
7025
  BOTTLE_MAX = 1e3;
7252
7026
  }));
7253
7027
 
7254
- //#endregion
7255
- //#region src/lib/bottle.ts
7028
+ // src/lib/bottle.ts
7256
7029
  /** This project's notes, oldest first. */
7257
7030
  function bottlesOf(reflections, projectId) {
7258
7031
  return (reflections ?? []).filter((r) => r.projectId === projectId && isBottle(r)).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
@@ -7350,8 +7123,7 @@ var init_bottle = __esmMin((() => {
7350
7123
  day$3 = (iso) => format(parseIso(iso.slice(0, 10)), "MMM d");
7351
7124
  }));
7352
7125
 
7353
- //#endregion
7354
- //#region src/lib/decisions.ts
7126
+ // src/lib/decisions.ts
7355
7127
  /** A risk counts as come true when someone said so, or when it was turned into an issue. */
7356
7128
  function cameTrue(risk) {
7357
7129
  return risk.happened === true || risk.kind === "issue";
@@ -7429,8 +7201,7 @@ var init_decisions = __esmMin((() => {
7429
7201
  md$1 = (iso) => format(parseIso(iso.slice(0, 10)), "MMM d");
7430
7202
  }));
7431
7203
 
7432
- //#endregion
7433
- //#region src/lib/brief.ts
7204
+ // src/lib/brief.ts
7434
7205
  /**
7435
7206
  * Open projects whose plan has grown enough since the baseline to mention
7436
7207
  * (barnacles.ts), most grown first.
@@ -7907,8 +7678,7 @@ var init_brief = __esmMin((() => {
7907
7678
  BRIEF_LATE_SHOWN = 8;
7908
7679
  }));
7909
7680
 
7910
- //#endregion
7911
- //#region src/lib/shipping-forecast.ts
7681
+ // src/lib/shipping-forecast.ts
7912
7682
  /** Small numbers as words, which a voice reads better and the forecast always uses. */
7913
7683
  function spoken(n) {
7914
7684
  return n >= 0 && n < WORDS.length ? WORDS[n] : String(n);
@@ -8077,8 +7847,7 @@ var init_shipping_forecast = __esmMin((() => {
8077
7847
  };
8078
7848
  }));
8079
7849
 
8080
- //#endregion
8081
- //#region src/tui/views/letter.tsx
7850
+ // src/tui/views/letter.tsx
8082
7851
  init_shipping_forecast();
8083
7852
  /**
8084
7853
  * A letter Harbor wrote (the brief, a status report) to read in the
@@ -8132,8 +7901,7 @@ function Letter({ title, text, hints, width, height, active, keys = {}, onClose
8132
7901
  });
8133
7902
  }
8134
7903
 
8135
- //#endregion
8136
- //#region src/tui/views/brief.tsx
7904
+ // src/tui/views/brief.tsx
8137
7905
  init_brief();
8138
7906
  init_swatches();
8139
7907
  /**
@@ -8258,8 +8026,7 @@ function BriefView({ active, width, height, go }) {
8258
8026
  });
8259
8027
  }
8260
8028
 
8261
- //#endregion
8262
- //#region src/lib/bridge.ts
8029
+ // src/lib/bridge.ts
8263
8030
  init_date_fns();
8264
8031
  init_indexes();
8265
8032
  init_raid();
@@ -8472,8 +8239,7 @@ function reviewedPrograms(slides, quiet) {
8472
8239
  return [.../* @__PURE__ */ new Set([...slides.map((s) => s.program.id), ...quiet.map((q) => q.program.id)])];
8473
8240
  }
8474
8241
 
8475
- //#endregion
8476
- //#region src/tui/views/bridge.tsx
8242
+ // src/tui/views/bridge.tsx
8477
8243
  init_date_fns();
8478
8244
  init_date_text();
8479
8245
  const WORD = {
@@ -8753,8 +8519,7 @@ function BridgeView({ active, width, height, go, programIds, onBack }) {
8753
8519
  });
8754
8520
  }
8755
8521
 
8756
- //#endregion
8757
- //#region src/lib/review.ts
8522
+ // src/lib/review.ts
8758
8523
  init_indexes();
8759
8524
  init_derived_health();
8760
8525
  /** A program is someone's when they lead it, lead one of its projects or hold a task in one. */
@@ -8790,8 +8555,7 @@ function blankCharters(data, programs, today) {
8790
8555
  return out.sort((a, b) => b.days - a.days || a.project.name.localeCompare(b.project.name));
8791
8556
  }
8792
8557
 
8793
- //#endregion
8794
- //#region src/tui/moves.ts
8558
+ // src/tui/moves.ts
8795
8559
  init_board();
8796
8560
  function moveTask(store, go, task, status) {
8797
8561
  const s = store.getState();
@@ -8814,8 +8578,7 @@ function roomFor(store, projectId, status) {
8814
8578
  return null;
8815
8579
  }
8816
8580
 
8817
- //#endregion
8818
- //#region src/tui/views/common.tsx
8581
+ // src/tui/views/common.tsx
8819
8582
  /** One task on one line: key, title, due, priority, and where it lives. */
8820
8583
  function TaskLine({ task, projects, people, today, selected, picked = false, width, showProject = true, showAssignee = false, blocked = false }) {
8821
8584
  const late = isLate(task, today);
@@ -8873,8 +8636,7 @@ function step(at, delta, length) {
8873
8636
  return Math.max(0, Math.min(length - 1, at + delta));
8874
8637
  }
8875
8638
 
8876
- //#endregion
8877
- //#region src/tui/views/calendar.tsx
8639
+ // src/tui/views/calendar.tsx
8878
8640
  init_date_fns();
8879
8641
  init_date_text();
8880
8642
  const WEEKDAYS$1 = [
@@ -9020,8 +8782,7 @@ function CalendarView({ active, width, height, go }) {
9020
8782
  });
9021
8783
  }
9022
8784
 
9023
- //#endregion
9024
- //#region src/tui/views/crew.tsx
8785
+ // src/tui/views/crew.tsx
9025
8786
  /**
9026
8787
  * The Crew screen: who's aboard and what they can do, and for the owner the
9027
8788
  * letters still out, share links (with their Monday update) and intake
@@ -9303,8 +9064,7 @@ function CrewView({ active, width, height, go }) {
9303
9064
  });
9304
9065
  }
9305
9066
 
9306
- //#endregion
9307
- //#region src/lib/hill.ts
9067
+ // src/lib/hill.ts
9308
9068
  /** A position kept on the scale, in whole steps. */
9309
9069
  function clampHill(at) {
9310
9070
  if (!Number.isFinite(at)) return 0;
@@ -9340,8 +9100,7 @@ var init_hill = __esmMin((() => {
9340
9100
  };
9341
9101
  }));
9342
9102
 
9343
- //#endregion
9344
- //#region src/lib/history-copy.ts
9103
+ // src/lib/history-copy.ts
9345
9104
  init_blockers();
9346
9105
  init_format();
9347
9106
  init_hill();
@@ -9531,6 +9290,16 @@ function describeEvent(e, names) {
9531
9290
  detail: null
9532
9291
  };
9533
9292
  }
9293
+ case "followerIds": {
9294
+ const ids = to ? to.split(",") : [];
9295
+ return ids.length ? {
9296
+ action: "set who else is on",
9297
+ detail: `to ${nameList(ids.map((id) => nameOf$3(names, id, "someone")))}`
9298
+ } : {
9299
+ action: "took everyone but the owner off",
9300
+ detail: null
9301
+ };
9302
+ }
9534
9303
  default: return {
9535
9304
  action: `changed ${e.field ?? "something on"}`,
9536
9305
  detail: null
@@ -9544,8 +9313,7 @@ function actorOf(row, people) {
9544
9313
  return row.via ? `${who} via ${row.via}` : who;
9545
9314
  }
9546
9315
 
9547
- //#endregion
9548
- //#region src/tui/views/history.tsx
9316
+ // src/tui/views/history.tsx
9549
9317
  init_date_text();
9550
9318
  /**
9551
9319
  * Who changed what, newest first, for a portfolio, program or project (s
@@ -9735,8 +9503,7 @@ function HistoryView({ active, width, height, go }) {
9735
9503
  });
9736
9504
  }
9737
9505
 
9738
- //#endregion
9739
- //#region src/lib/inbox.ts
9506
+ // src/lib/inbox.ts
9740
9507
  init_date_fns();
9741
9508
  init_indexes();
9742
9509
  init_flow();
@@ -9929,8 +9696,7 @@ function inboxOf(data, personId, now = clockNow()) {
9929
9696
  });
9930
9697
  }
9931
9698
 
9932
- //#endregion
9933
- //#region src/tui/views/inbox.tsx
9699
+ // src/tui/views/inbox.tsx
9934
9700
  init_date_text();
9935
9701
  /** What's asking for you, the same pings as the website's Inbox: Enter opens one, space marks it read. */
9936
9702
  function InboxView({ active, width, height, go }) {
@@ -10019,8 +9785,7 @@ function InboxView({ active, width, height, go }) {
10019
9785
  });
10020
9786
  }
10021
9787
 
10022
- //#endregion
10023
- //#region src/lib/load.ts
9788
+ // src/lib/load.ts
10024
9789
  /** Open tasks for one person, bucketed by the week they are due, plus what is already late or has no date. */
10025
9790
  function weeklyLoad(tasks, personId, now, weeks = 6, calendar) {
10026
9791
  const mine = tasks.filter((t) => t.assigneeId === personId && t.status !== "done");
@@ -10073,8 +9838,7 @@ var init_load = __esmMin((() => {
10073
9838
  };
10074
9839
  }));
10075
9840
 
10076
- //#endregion
10077
- //#region src/lib/handover.ts
9841
+ // src/lib/handover.ts
10078
9842
  /** Everything a person carries that someone else would have to pick up, grouped in KIND_ORDER. */
10079
9843
  function handoverItems(data, personId) {
10080
9844
  const projects = byId(data.projects);
@@ -10296,8 +10060,7 @@ var init_handover = __esmMin((() => {
10296
10060
  itemKey = (item) => `${item.kind}:${item.id}`;
10297
10061
  }));
10298
10062
 
10299
- //#endregion
10300
- //#region src/lib/lifeboats.ts
10063
+ // src/lib/lifeboats.ts
10301
10064
  init_date_fns();
10302
10065
  init_indexes();
10303
10066
  init_raid();
@@ -10540,8 +10303,7 @@ function awayNote(data, lines, today) {
10540
10303
  return notes;
10541
10304
  }
10542
10305
 
10543
- //#endregion
10544
- //#region src/lib/priority.ts
10306
+ // src/lib/priority.ts
10545
10307
  /** Rules with anything missing or out of range brought back to the defaults. */
10546
10308
  function normalizeRules(rules) {
10547
10309
  const impactThreshold = Number(rules?.impactThreshold);
@@ -10575,8 +10337,7 @@ var init_priority = __esmMin((() => {
10575
10337
  };
10576
10338
  }));
10577
10339
 
10578
- //#endregion
10579
- //#region src/tui/views/heat.tsx
10340
+ // src/tui/views/heat.tsx
10580
10341
  init_priority();
10581
10342
  init_raid();
10582
10343
  const CELL = 7;
@@ -10633,8 +10394,7 @@ function cellWords(cell) {
10633
10394
  return `${PROBABILITY_LABEL[cell.probability].toLowerCase()}, ${IMPACT_LABEL[cell.impact].toLowerCase()} impact`;
10634
10395
  }
10635
10396
 
10636
- //#endregion
10637
- //#region src/lib/deps.ts
10397
+ // src/lib/deps.ts
10638
10398
  init_blockers();
10639
10399
  /** True when making `id` wait on `candidate` would close a loop (or is `id` itself). */
10640
10400
  function wouldCycle(id, candidate, items) {
@@ -10679,8 +10439,7 @@ function blockerOptions(items, id) {
10679
10439
  return items.filter((n) => n.id !== id && !loops.has(n.id));
10680
10440
  }
10681
10441
 
10682
- //#endregion
10683
- //#region src/lib/status-report.ts
10442
+ // src/lib/status-report.ts
10684
10443
  init_derived_health();
10685
10444
  init_flow();
10686
10445
  init_format();
@@ -10752,8 +10511,7 @@ function composeStatusReport(data, program, now = /* @__PURE__ */ new Date()) {
10752
10511
  return lines.join("\n");
10753
10512
  }
10754
10513
 
10755
- //#endregion
10756
- //#region src/tui/views/decision-fields.ts
10514
+ // src/tui/views/decision-fields.ts
10757
10515
  init_date_fns();
10758
10516
  init_decisions();
10759
10517
  init_date_text();
@@ -10922,8 +10680,7 @@ function decisionFields(item, store, go, today) {
10922
10680
  return fields;
10923
10681
  }
10924
10682
 
10925
- //#endregion
10926
- //#region src/tui/views/panels.tsx
10683
+ // src/tui/views/panels.tsx
10927
10684
  /**
10928
10685
  * The panels that change one thing in place: a program, a portfolio, a
10929
10686
  * project's details, a milestone, a risk (issue, decision), a person. Each
@@ -11017,7 +10774,7 @@ const movesRows = (history, today) => {
11017
10774
  function HealthMoves({ history, today }) {
11018
10775
  const moves = healthMoves(history, today);
11019
10776
  if (!moves.length) return null;
11020
- return /* @__PURE__ */ jsxs(Fragment, { children: [
10777
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
11021
10778
  /* @__PURE__ */ jsx(Text, { children: " " }),
11022
10779
  /* @__PURE__ */ jsxs(Text, {
11023
10780
  color: theme.muted,
@@ -11620,7 +11377,7 @@ function MilestonePanel({ id, width, height, go, active, onClose }) {
11620
11377
  }, "Delete")
11621
11378
  },
11622
11379
  belowRows: risks.length ? risks.length + 1 : 0,
11623
- below: risks.length ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), risks.map((r) => /* @__PURE__ */ jsxs(Text, {
11380
+ below: risks.length ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), risks.map((r) => /* @__PURE__ */ jsxs(Text, {
11624
11381
  color: theme.bad,
11625
11382
  wrap: "truncate-end",
11626
11383
  children: [
@@ -11849,7 +11606,7 @@ function RaidPanel({ id, width, height, go, active, onClose }) {
11849
11606
  width,
11850
11607
  height,
11851
11608
  hints: "c add an update · d delete",
11852
- below: updates.length ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Text, {
11609
+ below: updates.length ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Text, {
11853
11610
  color: theme.muted,
11854
11611
  children: ["Updates", earlier ? ` · the last ${updates.length} of ${item.updates.length}` : ""]
11855
11612
  }), updates.map((u) => /* @__PURE__ */ jsxs(Text, {
@@ -11944,7 +11701,7 @@ function PersonPanel({ id, width, height, go, active, onClose }) {
11944
11701
  if (!Number.isFinite(n) || n < 0 || n > 100) return go.notify("A percent from 0 to 100.");
11945
11702
  store.getState().setAllocation(id, programId, n || null);
11946
11703
  })) },
11947
- below: allocations.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
11704
+ below: allocations.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
11948
11705
  /* @__PURE__ */ jsx(Text, { children: " " }),
11949
11706
  /* @__PURE__ */ jsxs(Text, {
11950
11707
  color: theme.muted,
@@ -11968,8 +11725,7 @@ function PersonPanel({ id, width, height, go, active, onClose }) {
11968
11725
  });
11969
11726
  }
11970
11727
 
11971
- //#endregion
11972
- //#region src/tui/views/lists.tsx
11728
+ // src/tui/views/lists.tsx
11973
11729
  init_indexes();
11974
11730
  init_load();
11975
11731
  init_raid();
@@ -12013,7 +11769,7 @@ function RowList({ title, right, rows, empty, active, width, height, onOpen, key
12013
11769
  children: [
12014
11770
  on ? "› " : " ",
12015
11771
  " ".repeat(r.depth),
12016
- r.health ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HealthMark, { health: r.health }), " "] }) : null,
11772
+ r.health ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HealthMark, { health: r.health }), " "] }) : null,
12017
11773
  r.title,
12018
11774
  r.detail ? /* @__PURE__ */ jsxs(Text, {
12019
11775
  color: theme.muted,
@@ -12440,8 +12196,7 @@ function PeopleView({ active, width, height, go }) {
12440
12196
  });
12441
12197
  }
12442
12198
 
12443
- //#endregion
12444
- //#region cli/lib/logo.mjs
12199
+ // cli/lib/logo.mjs
12445
12200
  /**
12446
12201
  * Harbor's mark for the terminal: the favicon (public/favicon.svg) as
12447
12202
  * pixels, a teal tile with the white H and three coral boats. Each
@@ -12556,8 +12311,7 @@ function logoRows(pixels = LOGO) {
12556
12311
  return rows;
12557
12312
  }
12558
12313
 
12559
- //#endregion
12560
- //#region src/tui/logo.tsx
12314
+ // src/tui/logo.tsx
12561
12315
  /** Harbor's mark in half blocks (cli/lib/logo.mjs holds the pixels). */
12562
12316
  function Logo({ pixels = LOGO }) {
12563
12317
  return /* @__PURE__ */ jsx(Box, {
@@ -12599,8 +12353,7 @@ function Splash({ opening }) {
12599
12353
  });
12600
12354
  }
12601
12355
 
12602
- //#endregion
12603
- //#region src/tui/views/overlays.tsx
12356
+ // src/tui/views/overlays.tsx
12604
12357
  init_search();
12605
12358
  /** Find a task by key or words; Enter opens it. */
12606
12359
  function SearchBox({ width, onOpen, onClose }) {
@@ -12825,8 +12578,7 @@ function Help({ width, onClose }) {
12825
12578
  });
12826
12579
  }
12827
12580
 
12828
- //#endregion
12829
- //#region src/tui/views/palette.tsx
12581
+ // src/tui/views/palette.tsx
12830
12582
  /**
12831
12583
  * `:` — everything in one list: screens, making things, every project and
12832
12584
  * program by name, other harbors. Type to narrow, Enter to run.
@@ -12932,8 +12684,7 @@ function Palette({ width, base, open, onClose }) {
12932
12684
  });
12933
12685
  }
12934
12686
 
12935
- //#endregion
12936
- //#region src/tui/views/premortem.tsx
12687
+ // src/tui/views/premortem.tsx
12937
12688
  /**
12938
12689
  * A project's pre-mortem in the terminal, as the website's card runs it:
12939
12690
  * start one, answer alone while the clock runs, then turn each answer into
@@ -13031,7 +12782,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13031
12782
  });
13032
12783
  if (pm.phase === "none") {
13033
12784
  const ends = project.endDate ? `after ${shortDay(project.endDate, today())}` : "three months from now";
13034
- return frame(/* @__PURE__ */ jsxs(Fragment, { children: [
12785
+ return frame(/* @__PURE__ */ jsxs(Fragment$1, { children: [
13035
12786
  /* @__PURE__ */ jsxs(Text, {
13036
12787
  wrap: "wrap",
13037
12788
  children: [
@@ -13066,7 +12817,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13066
12817
  viewOnly ? null : "a another answer",
13067
12818
  "Esc close"
13068
12819
  ];
13069
- return frame(/* @__PURE__ */ jsxs(Fragment, { children: [
12820
+ return frame(/* @__PURE__ */ jsxs(Fragment$1, { children: [
13070
12821
  /* @__PURE__ */ jsx(Text, {
13071
12822
  bold: true,
13072
12823
  wrap: "truncate-end",
@@ -13110,7 +12861,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13110
12861
  ]
13111
12862
  }, r.answer.id);
13112
12863
  }),
13113
- row ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(Box, {
12864
+ row ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(Box, {
13114
12865
  height: fullRows,
13115
12866
  overflow: "hidden",
13116
12867
  children: /* @__PURE__ */ jsx(Text, {
@@ -13121,8 +12872,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13121
12872
  ] }), hints.filter(Boolean).join(" · "));
13122
12873
  }
13123
12874
 
13124
- //#endregion
13125
- //#region src/lib/command-line.ts
12875
+ // src/lib/command-line.ts
13126
12876
  init_date_fns();
13127
12877
  init_format();
13128
12878
  const PAGES = {
@@ -13177,8 +12927,7 @@ function dueFrom(value, now) {
13177
12927
  throw new CommandError(`Can't read the date "${value}". Try today, fri, +3 or 2026-11-02.`);
13178
12928
  }
13179
12929
 
13180
- //#endregion
13181
- //#region src/lib/dry-dock.ts
12930
+ // src/lib/dry-dock.ts
13182
12931
  init_date_fns();
13183
12932
  init_format();
13184
12933
  init_indexes();
@@ -13549,8 +13298,7 @@ function applyDock(actions, projectId, changes) {
13549
13298
  return made;
13550
13299
  }
13551
13300
 
13552
- //#endregion
13553
- //#region node_modules/zod/v4/core/util.js
13301
+ // node_modules/zod/v4/core/util.js
13554
13302
  function getEnumValues(entries) {
13555
13303
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
13556
13304
  return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -13960,6 +13708,7 @@ function hide(inst, key, value) {
13960
13708
  return own(inst, key, value, false);
13961
13709
  }
13962
13710
  /** Adds members a table derives from the instance: each builds on first read and shadows as own data, and assignment shadows the same way, as when these were own properties. */
13711
+ /* @__NO_SIDE_EFFECTS__ */
13963
13712
  function derived(computes, table) {
13964
13713
  for (const key in computes) {
13965
13714
  const compute = computes[key];
@@ -14084,8 +13833,7 @@ function constantCatch(value) {
14084
13833
  return fn;
14085
13834
  }
14086
13835
 
14087
- //#endregion
14088
- //#region node_modules/zod/v4/core/core.js
13836
+ // node_modules/zod/v4/core/core.js
14089
13837
  var _a$1;
14090
13838
  const _zodDesc = {
14091
13839
  value: void 0,
@@ -14112,6 +13860,7 @@ function newError(Definition) {
14112
13860
  }
14113
13861
  return new Definition();
14114
13862
  }
13863
+ /* @__NO_SIDE_EFFECTS__ */
14115
13864
  function $constructor(name, initializer, proto, params) {
14116
13865
  const zodProto = {};
14117
13866
  function Internals(def) {
@@ -14191,8 +13940,7 @@ function config(newConfig) {
14191
13940
  return globalConfig;
14192
13941
  }
14193
13942
 
14194
- //#endregion
14195
- //#region node_modules/zod/v4/core/errors.js
13943
+ // node_modules/zod/v4/core/errors.js
14196
13944
  function _getMessage() {
14197
13945
  const internals = this._zod;
14198
13946
  internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
@@ -14243,8 +13991,7 @@ const initializer$1 = (inst, def) => {
14243
13991
  });
14244
13992
  }
14245
13993
  };
14246
- const $ZodError = $constructor("$ZodError", initializer$1);
14247
- const $ZodRealError = $constructor("$ZodError", initializer$1, void 0, { Parent: Error });
13994
+ const $ZodError = /* @__PURE__ */ $constructor("$ZodError", initializer$1);
14248
13995
  /** Get-or-create `obj[key]` as an own data property. A path segment naming an inherited member
14249
13996
  * ("toString", "constructor") would otherwise read through to the prototype, and assigning
14250
13997
  * "__proto__" would hit the setter instead of creating a key. */
@@ -14308,8 +14055,7 @@ function formatError(error, mapper = (issue) => issue.message) {
14308
14055
  return fieldErrors;
14309
14056
  }
14310
14057
 
14311
- //#endregion
14312
- //#region node_modules/zod/v4/core/parse.js
14058
+ // node_modules/zod/v4/core/parse.js
14313
14059
  function finalizeParams(callee, params) {
14314
14060
  return {
14315
14061
  callee: params?.callee ?? callee,
@@ -14512,8 +14258,7 @@ const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
14512
14258
  return _safeParseAsync(_Err)(schema, value, _ctx);
14513
14259
  };
14514
14260
 
14515
- //#endregion
14516
- //#region node_modules/zod/v4/core/regexes.js
14261
+ // node_modules/zod/v4/core/regexes.js
14517
14262
  /**
14518
14263
  * @deprecated CUID v1 is deprecated by its authors due to information leakage
14519
14264
  * (timestamps embedded in the id). Use {@link cuid2} instead.
@@ -14584,8 +14329,7 @@ const boolean$1 = /^(?:true|false)$/i;
14584
14329
  const lowercase = /^[^A-Z]*$/;
14585
14330
  const uppercase = /^[^a-z]*$/;
14586
14331
 
14587
- //#endregion
14588
- //#region node_modules/zod/v4/core/checks.js
14332
+ // node_modules/zod/v4/core/checks.js
14589
14333
  const $ZodCheck = /*@__PURE__*/ $constructor("$ZodCheck", (inst, def) => {
14590
14334
  var _a;
14591
14335
  inst._zod ?? (inst._zod = {});
@@ -14881,8 +14625,7 @@ const $ZodCheckOverwrite = /*@__PURE__*/ $constructor("$ZodCheckOverwrite", (ins
14881
14625
  };
14882
14626
  });
14883
14627
 
14884
- //#endregion
14885
- //#region node_modules/zod/v4/core/doc.js
14628
+ // node_modules/zod/v4/core/doc.js
14886
14629
  var Doc = class {
14887
14630
  constructor(args = [], closed = {}) {
14888
14631
  this.content = [];
@@ -14916,16 +14659,14 @@ var Doc = class {
14916
14659
  }
14917
14660
  };
14918
14661
 
14919
- //#endregion
14920
- //#region node_modules/zod/v4/core/versions.js
14662
+ // node_modules/zod/v4/core/versions.js
14921
14663
  const version = {
14922
14664
  major: 4,
14923
14665
  minor: 6,
14924
14666
  patch: 7
14925
14667
  };
14926
14668
 
14927
- //#endregion
14928
- //#region node_modules/zod/v4/core/schemas.js
14669
+ // node_modules/zod/v4/core/schemas.js
14929
14670
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
14930
14671
  var _a;
14931
14672
  inst ?? (inst = {});
@@ -16169,8 +15910,7 @@ function handleRefineResult(result, payload, input, inst) {
16169
15910
  }
16170
15911
  }
16171
15912
 
16172
- //#endregion
16173
- //#region node_modules/zod/v4/core/memoizer.js
15913
+ // node_modules/zod/v4/core/memoizer.js
16174
15914
  var $ZodCyclicError = class extends Error {
16175
15915
  constructor() {
16176
15916
  super(`Cannot parse a reference cycle that closes through a transform`);
@@ -16423,8 +16163,7 @@ function isBackEdge(ctx, value) {
16423
16163
  return backEdges !== void 0 && isRef(value) && backEdges.has(value);
16424
16164
  }
16425
16165
 
16426
- //#endregion
16427
- //#region node_modules/zod/v4/locales/en.js
16166
+ // node_modules/zod/v4/locales/en.js
16428
16167
  const error = () => {
16429
16168
  const Sizable = {
16430
16169
  string: {
@@ -16532,8 +16271,7 @@ function en_default() {
16532
16271
  return { localeError: error() };
16533
16272
  }
16534
16273
 
16535
- //#endregion
16536
- //#region node_modules/zod/v4/core/registries.js
16274
+ // node_modules/zod/v4/core/registries.js
16537
16275
  var _a;
16538
16276
  var $ZodRegistry = class {
16539
16277
  constructor() {
@@ -16580,8 +16318,7 @@ function registry() {
16580
16318
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
16581
16319
  const globalRegistry = globalThis.__zod_globalRegistry;
16582
16320
 
16583
- //#endregion
16584
- //#region node_modules/zod/v4/core/api.js
16321
+ // node_modules/zod/v4/core/api.js
16585
16322
  function snapshotChecks(def) {
16586
16323
  if (def.checks) def.checks = [...def.checks];
16587
16324
  return def;
@@ -17090,8 +16827,7 @@ function _check(fn, params) {
17090
16827
  return ch;
17091
16828
  }
17092
16829
 
17093
- //#endregion
17094
- //#region node_modules/zod/v4/core/to-json-schema.js
16830
+ // node_modules/zod/v4/core/to-json-schema.js
17095
16831
  function assignProps(target, ...sources) {
17096
16832
  for (const source of sources) for (const key of Reflect.ownKeys(source)) if (Object.prototype.propertyIsEnumerable.call(source, key)) assignProp(target, key, source[key]);
17097
16833
  return target;
@@ -17536,8 +17272,7 @@ const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params)
17536
17272
  return finalize(ctx, schema);
17537
17273
  };
17538
17274
 
17539
- //#endregion
17540
- //#region node_modules/zod/v4/core/json-schema-processors.js
17275
+ // node_modules/zod/v4/core/json-schema-processors.js
17541
17276
  const narrowMin = (agg, key, value) => {
17542
17277
  if (agg[key] === void 0 || value > agg[key]) agg[key] = value;
17543
17278
  };
@@ -17859,8 +17594,7 @@ const optionalProcessor = (schema, ctx, _json, params) => {
17859
17594
  seen.ref = def.innerType;
17860
17595
  };
17861
17596
 
17862
- //#endregion
17863
- //#region node_modules/zod/v4/classic/errors.js
17597
+ // node_modules/zod/v4/classic/errors.js
17864
17598
  const _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
17865
17599
  function _lazyMethod(proto, key, make) {
17866
17600
  Object.defineProperty(proto, key, {
@@ -17910,8 +17644,7 @@ const initializer = (inst, issues) => {
17910
17644
  };
17911
17645
  const ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, void 0, { Parent: Error });
17912
17646
 
17913
- //#endregion
17914
- //#region node_modules/zod/v4/classic/parse.js
17647
+ // node_modules/zod/v4/classic/parse.js
17915
17648
  const parse = /* @__PURE__ */ _parse(ZodRealError);
17916
17649
  const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
17917
17650
  const safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -17925,8 +17658,7 @@ const safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
17925
17658
  const safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
17926
17659
  const safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
17927
17660
 
17928
- //#endregion
17929
- //#region node_modules/zod/v4/classic/schemas.js
17661
+ // node_modules/zod/v4/classic/schemas.js
17930
17662
  function _ensureDefaultLocale() {
17931
17663
  if (!globalConfig.localeError) config(en_default());
17932
17664
  }
@@ -18757,8 +18489,7 @@ function superRefine(fn, params) {
18757
18489
  return _superRefine(fn, params);
18758
18490
  }
18759
18491
 
18760
- //#endregion
18761
- //#region src/lib/long-pole.ts
18492
+ // src/lib/long-pole.ts
18762
18493
  init_date_fns();
18763
18494
  init_blockers();
18764
18495
  init_format();
@@ -18972,8 +18703,7 @@ function undatedText(pole) {
18972
18703
  return n === 1 ? "1 open task has no due date, so it can't hold the date." : `${n} open tasks have no due date, so they can't hold the date.`;
18973
18704
  }
18974
18705
 
18975
- //#endregion
18976
- //#region src/lib/csv.ts
18706
+ // src/lib/csv.ts
18977
18707
  /**
18978
18708
  * Text a spreadsheet would run as a formula: a title from an intake form
18979
18709
  * could read =HYPERLINK(…). Exports put an apostrophe in front, which
@@ -18992,8 +18722,7 @@ function toCsv(headers, rows) {
18992
18722
  return [headers, ...rows].map((r) => r.map(cell).join(",")).join("\r\n");
18993
18723
  }
18994
18724
 
18995
- //#endregion
18996
- //#region src/lib/exports.ts
18725
+ // src/lib/exports.ts
18997
18726
  /**
18998
18727
  * The spreadsheets Harbor hands out: a project's tasks, the risk register and
18999
18728
  * the review. The website downloads them, agents and the terminal get the
@@ -19108,8 +18837,7 @@ function reviewCsv(data, programs, now) {
19108
18837
  ]));
19109
18838
  }
19110
18839
 
19111
- //#endregion
19112
- //#region src/lib/crew-clocks.ts
18840
+ // src/lib/crew-clocks.ts
19113
18841
  /** Working hours when only a time zone is set. */
19114
18842
  const DEFAULT_HOURS = {
19115
18843
  start: "09:00",
@@ -19238,8 +18966,7 @@ function todayFor(person, at, fallback) {
19238
18966
  return isZone(person?.timeZone) ? wallIn(person.timeZone, at).date : fallback;
19239
18967
  }
19240
18968
 
19241
- //#endregion
19242
- //#region src/lib/pilot.ts
18969
+ // src/lib/pilot.ts
19243
18970
  init_load();
19244
18971
  init_format();
19245
18972
  init_handover();
@@ -19390,8 +19117,7 @@ function pilotReasons(p, you = false) {
19390
19117
  return out;
19391
19118
  }
19392
19119
 
19393
- //#endregion
19394
- //#region src/lib/seen-mark.ts
19120
+ // src/lib/seen-mark.ts
19395
19121
  /** Days without opening Harbor before the catch-up shows. */
19396
19122
  const UNSEEN_DAYS = 3;
19397
19123
  /** Calendar days from one ISO day (or moment) to another, by their dates alone. */
@@ -19427,8 +19153,7 @@ function welcomeWhen(person, lastSeen, today) {
19427
19153
  } : null;
19428
19154
  }
19429
19155
 
19430
- //#endregion
19431
- //#region src/lib/welcome-back.ts
19156
+ // src/lib/welcome-back.ts
19432
19157
  init_date_text();
19433
19158
  init_indexes();
19434
19159
  init_task_keys();
@@ -19553,33 +19278,7 @@ function movedText(m, healthLabel) {
19553
19278
  return `${m.project.name}: ${bits.join(", ")}`;
19554
19279
  }
19555
19280
 
19556
- //#endregion
19557
- //#region src/lib/agents.ts
19558
- const isAgent = (p) => p?.kind === "agent";
19559
- const RANK = {
19560
- urgent: 0,
19561
- high: 1,
19562
- medium: 2,
19563
- low: 3
19564
- };
19565
- /** What an agent should work on: its open tasks not yet waiting on review, in progress first, then most urgent and soonest. */
19566
- function agentQueue(data, agentId) {
19567
- return data.tasks.filter((t) => t.assigneeId === agentId && (t.status === "todo" || t.status === "doing" || t.status === "backlog")).sort((a, b) => Number(b.status === "doing") - Number(a.status === "doing") || Number(a.status === "backlog") - Number(b.status === "backlog") || RANK[a.priority] - RANK[b.priority] || (a.dueDate ?? "9999").localeCompare(b.dueDate ?? "9999"));
19568
- }
19569
- /** The agent an app means: the one named, else the only one on the crew. */
19570
- function pickAgent(people, key) {
19571
- const agents = people.filter(isAgent);
19572
- if (agents.length === 0) return "There are no agents on this harbor's crew yet. Someone adds one on People with Add an agent.";
19573
- if (!key) {
19574
- if (agents.length === 1) return agents[0];
19575
- return `This harbor has ${agents.length} agents (${agents.map((a) => a.name).join(", ")}). Say which with agent.`;
19576
- }
19577
- const k = key.trim().toLowerCase();
19578
- return agents.find((a) => a.id === key.trim() || a.name.trim().toLowerCase() === k) ?? `No agent called "${key}". The crew's agents: ${agents.map((a) => a.name).join(", ")}.`;
19579
- }
19580
-
19581
- //#endregion
19582
- //#region src/lib/fog.ts
19281
+ // src/lib/fog.ts
19583
19282
  function latestBy(cache, items, key, at) {
19584
19283
  const hit = cache.get(items);
19585
19284
  if (hit && hit.size === items.length) return hit.value;
@@ -19668,8 +19367,7 @@ var init_fog = __esmMin((() => {
19668
19367
  fileCache = /* @__PURE__ */ new WeakMap();
19669
19368
  }));
19670
19369
 
19671
- //#endregion
19672
- //#region src/lib/mcp/tools.ts
19370
+ // src/lib/mcp/tools.ts
19673
19371
  init_thanks();
19674
19372
  init_task_keys();
19675
19373
  init_brief();
@@ -19691,7 +19389,9 @@ init_date_text();
19691
19389
  init_date_fns();
19692
19390
  init_shipping_forecast();
19693
19391
  init_handover();
19392
+ init_agents();
19694
19393
  init_work();
19394
+ init_task_people();
19695
19395
  init_fog();
19696
19396
  init_passage();
19697
19397
  init_board();
@@ -19941,10 +19641,27 @@ function taskLine(t, people, projects, all) {
19941
19641
  priority: t.priority,
19942
19642
  due: dayOf(t.dueDate),
19943
19643
  assignee: nameOf$2(people, t.assigneeId),
19644
+ ...alsoOnOf(t, people),
19944
19645
  project: project?.name ?? null,
19945
19646
  ...waitingOn ? { waitingOn } : {}
19946
19647
  };
19947
19648
  }
19649
+ /** Everyone also on a task beside its owner, by name; nothing when it's the owner's alone. */
19650
+ function alsoOnOf(t, people) {
19651
+ const names = alsoOnIds(t).map((id) => nameOf$2(people, id) ?? "someone");
19652
+ return names.length ? { alsoOn: names } : {};
19653
+ }
19654
+ /** A file as agents see it: a link's address, never a stored file's bytes or a pasted image's data. */
19655
+ function fileOut(a, people) {
19656
+ return {
19657
+ id: a.id,
19658
+ name: a.name,
19659
+ kind: a.kind,
19660
+ ...a.kind === "link" && a.url ? { url: a.url } : {},
19661
+ addedBy: nameOf$2(people, a.addedBy),
19662
+ added: dayOf(a.addedAt)
19663
+ };
19664
+ }
19948
19665
  /** One person's week plan as the agent tools give it (get_week, plan_week). */
19949
19666
  /** Most of the tasks not on a day that get_week lists; the count says how many there are. */
19950
19667
  const UNPLANNED_MAX = 200;
@@ -20379,7 +20096,7 @@ const HARBOR_TOOLS = [
20379
20096
  tool({
20380
20097
  name: "get_task",
20381
20098
  title: "Task details",
20382
- description: "One task: notes, checklist, what it waits on, what waits on it, its latest comments, the earliest due date its owner's queue suggests (pilotDue: fits says whether the due date holds; absent with no owner, an agent owner, or once done), its place in its board column (`position`, from 1 at the top), and its url on the website." + DATA_NOTE,
20099
+ description: "One task: its owner (assignee) and anyone also on it (alsoOn), notes, checklist, its files, what it waits on, what waits on it, its latest comments, the earliest due date its owner's queue suggests (pilotDue: fits says whether the due date holds; absent with no owner, an agent owner, or once done), its place in its board column (`position`, from 1 at the top), and its url on the website." + DATA_NOTE,
20383
20100
  input: object({
20384
20101
  harbor: harborArg,
20385
20102
  task: string().min(1).max(100).describe("Task id or key (\"RR-42\"), from search_tasks or my_work.")
@@ -20418,6 +20135,7 @@ const HARBOR_TOOLS = [
20418
20135
  priority: t.priority,
20419
20136
  due: dayOf(t.dueDate),
20420
20137
  assignee: nameOf$2(people, t.assigneeId),
20138
+ ...alsoOnOf(t, people),
20421
20139
  project: project?.name ?? null,
20422
20140
  projectId: t.projectId,
20423
20141
  created: dayOf(t.createdAt),
@@ -20436,15 +20154,54 @@ const HARBOR_TOOLS = [
20436
20154
  says: pilotHeadline(pilot, t.dueDate, you),
20437
20155
  why: pilotReasons(pilot, you)
20438
20156
  } } : {},
20157
+ files: (data.attachments ?? []).filter((a) => a.taskId === t.id).map((a) => fileOut(a, people)),
20439
20158
  comments,
20440
20159
  ...webLink(ctx, { task: t.id })
20441
20160
  };
20442
20161
  }
20443
20162
  }),
20163
+ tool({
20164
+ name: "list_files",
20165
+ title: "A project's files",
20166
+ description: "Every file attached to a project's tasks, newest first: its name, kind (image, doc or link), the link for a link, who added it and when, and the task it's on. Files are added from a task on the website." + DATA_NOTE,
20167
+ input: object({
20168
+ harbor: harborArg,
20169
+ project: string().min(1).max(200).describe("Project id or name."),
20170
+ kind: _enum([
20171
+ "image",
20172
+ "doc",
20173
+ "link"
20174
+ ]).optional().describe("Only this kind."),
20175
+ limit: limitArg(200, 50),
20176
+ offset: offsetArg
20177
+ }),
20178
+ run: (ctx, input) => {
20179
+ const { data } = ctx;
20180
+ const p = findOne(data.projects, input.project, "project");
20181
+ const people = byId(data.people);
20182
+ const files = projectFiles(data, p.id, input.kind);
20183
+ return {
20184
+ project: p.name,
20185
+ total: files.length,
20186
+ files: files.slice(input.offset, input.offset + input.limit).map(({ file, task }) => {
20187
+ const key = taskKey(task, p);
20188
+ return {
20189
+ ...fileOut(file, people),
20190
+ task: {
20191
+ id: task.id,
20192
+ ...key ? { key } : {},
20193
+ title: task.title
20194
+ }
20195
+ };
20196
+ }),
20197
+ ...webLink(ctx, { project: p.id })
20198
+ };
20199
+ }
20200
+ }),
20444
20201
  tool({
20445
20202
  name: "my_work",
20446
20203
  title: "My work",
20447
- description: "What's yours in a harbor: your open tasks (late first), what others are waiting on you for, and the risks you own." + DATA_NOTE,
20204
+ description: "What's yours in a harbor: your open tasks (late first), open tasks others own that you're also on (alsoOn), what others are waiting on you for, and the risks you own." + DATA_NOTE,
20448
20205
  input: object({
20449
20206
  harbor: harborArg,
20450
20207
  limit: limitArg(50, 25)
@@ -20483,6 +20240,7 @@ const HARBOR_TOOLS = [
20483
20240
  openTasks: open.length,
20484
20241
  late: open.filter((t) => overdue(t, today)).length,
20485
20242
  tasks: open.slice(0, input.limit).map((t) => taskLine(t, people, projects, data.tasks)),
20243
+ alsoOn: tasksAlsoOn(data, mine.id).sort((a, b) => (a.dueDate ?? "9999").localeCompare(b.dueDate ?? "9999")).slice(0, input.limit).map((t) => taskLine(t, people, projects, data.tasks)),
20486
20244
  waitingOnYou: waitingOnYou.slice(0, 20),
20487
20245
  raid,
20488
20246
  soundingsToAnswer: soundingsWaitingOn(data, mine.id, ctx.now).map((t) => ({
@@ -21396,8 +21154,7 @@ const LIST_HARBORS = {
21396
21154
  input: object({})
21397
21155
  };
21398
21156
 
21399
- //#endregion
21400
- //#region src/lib/payload.ts
21157
+ // src/lib/payload.ts
21401
21158
  /**
21402
21159
  * The document fields of a store state, by reference, with stable empties for
21403
21160
  * anything missing. Cheap enough to run on every render; feeds `useHarborData`.
@@ -21447,8 +21204,7 @@ var init_payload = __esmMin((() => {
21447
21204
  NO_CONFIGS = {};
21448
21205
  }));
21449
21206
 
21450
- //#endregion
21451
- //#region src/lib/view-only.ts
21207
+ // src/lib/view-only.ts
21452
21208
  function isDocumentKey(key, state) {
21453
21209
  documentKeys ??= new Set(Object.keys(pickData(state)));
21454
21210
  return documentKeys.has(key);
@@ -21487,8 +21243,7 @@ var init_view_only = __esmMin((() => {
21487
21243
  documentKeys = null;
21488
21244
  }));
21489
21245
 
21490
- //#endregion
21491
- //#region cli/lib/errors.mjs
21246
+ // cli/lib/errors.mjs
21492
21247
  var HarborError;
21493
21248
  var init_errors = __esmMin((() => {
21494
21249
  HarborError = class extends Error {
@@ -21496,8 +21251,7 @@ var init_errors = __esmMin((() => {
21496
21251
  };
21497
21252
  }));
21498
21253
 
21499
- //#endregion
21500
- //#region src/lib/empty.ts
21254
+ // src/lib/empty.ts
21501
21255
  function addMonths(iso, months) {
21502
21256
  const [y, m, d] = iso.split("-").map(Number);
21503
21257
  const dt = new Date(y, (m ?? 1) - 1, d ?? 1);
@@ -21580,8 +21334,7 @@ var init_empty = __esmMin((() => {
21580
21334
  STARTER_PROGRAM = "The work";
21581
21335
  }));
21582
21336
 
21583
- //#endregion
21584
- //#region src/lib/deep-equal.ts
21337
+ // src/lib/deep-equal.ts
21585
21338
  /**
21586
21339
  * Structural equality, key-order independent, treating `undefined` and a
21587
21340
  * missing key as the same as `null` (matches how optional fields like
@@ -21605,8 +21358,7 @@ function deepEqual(a, b) {
21605
21358
  }
21606
21359
  var init_deep_equal = __esmMin((() => {}));
21607
21360
 
21608
- //#endregion
21609
- //#region src/lib/row-changes.ts
21361
+ // src/lib/row-changes.ts
21610
21362
  /**
21611
21363
  * The changes that turn `before` into `after`. Rows the store left alone
21612
21364
  * keep their object, so most of the work is an identity check.
@@ -21742,8 +21494,7 @@ var init_row_changes = __esmMin((() => {
21742
21494
  LATEST_WINS = /* @__PURE__ */ new Set(["touchedAt"]);
21743
21495
  }));
21744
21496
 
21745
- //#endregion
21746
- //#region src/lib/undo.ts
21497
+ // src/lib/undo.ts
21747
21498
  function nameOf$1(row) {
21748
21499
  const text = row?.title ?? row?.name;
21749
21500
  return text ? `“${text.length > 40 ? `${text.slice(0, 39)}…` : text}”` : null;
@@ -21857,8 +21608,7 @@ var init_undo = __esmMin((() => {
21857
21608
  ];
21858
21609
  }));
21859
21610
 
21860
- //#endregion
21861
- //#region src/lib/demo-seed.ts
21611
+ // src/lib/demo-seed.ts
21862
21612
  /** Whether createSeedNow can answer without waiting. */
21863
21613
  function seedReady() {
21864
21614
  return create !== null;
@@ -21887,15 +21637,13 @@ var init_demo_seed = __esmMin((() => {
21887
21637
  anchor = null;
21888
21638
  }));
21889
21639
 
21890
- //#endregion
21891
- //#region src/lib/utils.ts
21640
+ // src/lib/utils.ts
21892
21641
  function uid(prefix = "id") {
21893
21642
  return `${prefix}-${Math.random().toString(36).slice(2, 9)}`;
21894
21643
  }
21895
21644
  var init_utils = __esmMin((() => {}));
21896
21645
 
21897
- //#endregion
21898
- //#region src/lib/slices/shared.ts
21646
+ // src/lib/slices/shared.ts
21899
21647
  function stamp() {
21900
21648
  return (/* @__PURE__ */ new Date()).toISOString();
21901
21649
  }
@@ -21915,8 +21663,7 @@ function withStatus(task, status) {
21915
21663
  }
21916
21664
  var init_shared = __esmMin((() => {}));
21917
21665
 
21918
- //#endregion
21919
- //#region src/lib/undo-state.ts
21666
+ // src/lib/undo-state.ts
21920
21667
  function clearUndo() {
21921
21668
  useUndo.setState({
21922
21669
  step: null,
@@ -21932,8 +21679,7 @@ var init_undo_state = __esmMin((() => {
21932
21679
  }));
21933
21680
  }));
21934
21681
 
21935
- //#endregion
21936
- //#region src/lib/slices/session.ts
21682
+ // src/lib/slices/session.ts
21937
21683
  function sessionSlice({ set, get, write }) {
21938
21684
  return {
21939
21685
  setHydrated: (v) => set({ hydrated: v }),
@@ -22084,8 +21830,7 @@ var init_session = __esmMin((() => {
22084
21830
  init_format();
22085
21831
  }));
22086
21832
 
22087
- //#endregion
22088
- //#region src/lib/first-week.ts
21833
+ // src/lib/first-week.ts
22089
21834
  /** The program launch named for you, when nobody has renamed it yet. */
22090
21835
  function starterProgram(data) {
22091
21836
  return data.programs.find((p) => p.name.trim() === "The work") ?? null;
@@ -22094,8 +21839,7 @@ var init_first_week = __esmMin((() => {
22094
21839
  init_empty();
22095
21840
  }));
22096
21841
 
22097
- //#endregion
22098
- //#region src/lib/slices/hierarchy.ts
21842
+ // src/lib/slices/hierarchy.ts
22099
21843
  function hierarchySlice({ get, write }) {
22100
21844
  return {
22101
21845
  addPortfolio: (p) => {
@@ -22532,8 +22276,7 @@ var init_hierarchy = __esmMin((() => {
22532
22276
  init_first_week();
22533
22277
  }));
22534
22278
 
22535
- //#endregion
22536
- //#region src/lib/github-refs.ts
22279
+ // src/lib/github-refs.ts
22537
22280
  /** The task's list with this pull request or commit added, or updated in place, newest first. */
22538
22281
  function withRef(list, ref) {
22539
22282
  const same = (r) => r.kind === ref.kind && r.repo === ref.repo && r.ref === ref.ref;
@@ -22544,8 +22287,7 @@ var init_github_refs = __esmMin((() => {
22544
22287
  REFS_KEPT = 20;
22545
22288
  }));
22546
22289
 
22547
- //#endregion
22548
- //#region src/lib/automations.ts
22290
+ // src/lib/automations.ts
22549
22291
  /**
22550
22292
  * Checked once, against the (before, after) pair of a single user-driven
22551
22293
  * mutation — never re-checked against an automation's own effect. That's the
@@ -22617,8 +22359,7 @@ function applyAutomations(project, prev, next, opts) {
22617
22359
  }
22618
22360
  var init_automations = __esmMin((() => {}));
22619
22361
 
22620
- //#endregion
22621
- //#region src/lib/focus.ts
22362
+ // src/lib/focus.ts
22622
22363
  function focusIdsOf(data, personId, date = todayISO()) {
22623
22364
  return (data.ropes ?? []).find((r) => r.personId === personId && r.date === date)?.taskIds ?? [];
22624
22365
  }
@@ -22641,8 +22382,7 @@ var init_focus = __esmMin((() => {
22641
22382
  CHECK_IN_QUESTION = "On the blocker, or on something else?";
22642
22383
  }));
22643
22384
 
22644
- //#endregion
22645
- //#region src/lib/recurrence.ts
22385
+ // src/lib/recurrence.ts
22646
22386
  /** The due date one interval after `from`. */
22647
22387
  function nextDueDate(from, repeat) {
22648
22388
  const d = /* @__PURE__ */ new Date(`${from}T12:00:00`);
@@ -22687,8 +22427,7 @@ var init_recurrence = __esmMin((() => {
22687
22427
  };
22688
22428
  }));
22689
22429
 
22690
- //#endregion
22691
- //#region src/lib/assignment.ts
22430
+ // src/lib/assignment.ts
22692
22431
  /**
22693
22432
  * Record who set a task's assignee and when. Only a change of assignee
22694
22433
  * stamps; clearing the assignee clears the stamp.
@@ -22708,8 +22447,7 @@ function stampAssignment(before, next, by, at) {
22708
22447
  }
22709
22448
  var init_assignment = __esmMin((() => {}));
22710
22449
 
22711
- //#endregion
22712
- //#region src/lib/bulk.ts
22450
+ // src/lib/bulk.ts
22713
22451
  /** A task's due date moved by `days`, or null when it has none. */
22714
22452
  function shiftedDue(due, days) {
22715
22453
  if (!due) return null;
@@ -22763,8 +22501,7 @@ var init_bulk = __esmMin((() => {
22763
22501
  plural$2 = (n) => `${n} ${n === 1 ? "task" : "tasks"}`;
22764
22502
  }));
22765
22503
 
22766
- //#endregion
22767
- //#region src/lib/slices/tasks.ts
22504
+ // src/lib/slices/tasks.ts
22768
22505
  function tasksSlice({ set, get, write }) {
22769
22506
  return {
22770
22507
  followWork: (personId, taskIds, raidIds = []) => {
@@ -22846,6 +22583,7 @@ function tasksSlice({ set, get, write }) {
22846
22583
  ...patch,
22847
22584
  touchedAt: stamp()
22848
22585
  };
22586
+ if (next.assigneeId && next.followerIds?.includes(next.assigneeId)) next.followerIds = alsoOnIds(next);
22849
22587
  if (patch.status && patch.status !== row.status) {
22850
22588
  if (patch.status === "done" && !patch.completedAt) next.completedAt = stamp();
22851
22589
  else if (row.status === "done" && patch.status !== "done") next.completedAt = null;
@@ -23252,10 +22990,10 @@ var init_tasks = __esmMin((() => {
23252
22990
  init_recurrence();
23253
22991
  init_assignment();
23254
22992
  init_bulk();
22993
+ init_task_people();
23255
22994
  }));
23256
22995
 
23257
- //#endregion
23258
- //#region src/lib/raid-history.ts
22996
+ // src/lib/raid-history.ts
23259
22997
  /**
23260
22998
  * The score history after applying `patch`: a new entry when the rating
23261
22999
  * moved, the same array otherwise. The first change also records where the
@@ -23277,8 +23015,7 @@ function recordScoreChange(item, patch, at) {
23277
23015
  }
23278
23016
  var init_raid_history = __esmMin((() => {}));
23279
23017
 
23280
- //#endregion
23281
- //#region src/lib/slices/milestones-raid.ts
23018
+ // src/lib/slices/milestones-raid.ts
23282
23019
  function milestonesRaidSlice({ set, get, write }) {
23283
23020
  return {
23284
23021
  toggleMilestone: (id) => {
@@ -23661,8 +23398,7 @@ var init_milestones_raid = __esmMin((() => {
23661
23398
  init_shared();
23662
23399
  }));
23663
23400
 
23664
- //#endregion
23665
- //#region src/lib/allocation.ts
23401
+ // src/lib/allocation.ts
23666
23402
  /** Allocations with `programId` set to `percent`; 0 or null removes the line. */
23667
23403
  function withAllocation(allocations, programId, percent) {
23668
23404
  const rest = (allocations ?? []).filter((a) => a.programId !== programId);
@@ -23674,8 +23410,7 @@ function withAllocation(allocations, programId, percent) {
23674
23410
  }
23675
23411
  var init_allocation = __esmMin((() => {}));
23676
23412
 
23677
- //#endregion
23678
- //#region src/lib/slices/people-spend.ts
23413
+ // src/lib/slices/people-spend.ts
23679
23414
  function peopleSpendSlice({ set, get, write }) {
23680
23415
  return {
23681
23416
  setAllocation: (personId, programId, percent) => {
@@ -23959,8 +23694,7 @@ var init_people_spend = __esmMin((() => {
23959
23694
  init_allocation();
23960
23695
  }));
23961
23696
 
23962
- //#endregion
23963
- //#region src/tui/engine/store.ts
23697
+ // src/tui/engine/store.ts
23964
23698
  /** An empty harbor: what the store holds before one loads. */
23965
23699
  function blank() {
23966
23700
  return pickData({ currentUserId: "" });
@@ -24064,8 +23798,7 @@ var init_store = __esmMin((() => {
24064
23798
  PAUSED_NOTICE = "This harbor's free trial has ended, so that wasn't changed. Its owner can subscribe at harborppm.com/keep.";
24065
23799
  }));
24066
23800
 
24067
- //#endregion
24068
- //#region src/lib/changes.ts
23801
+ // src/lib/changes.ts
24069
23802
  /** Keys whose value differs between the last saved document and the current one. */
24070
23803
  function changedCollections(base, current) {
24071
23804
  return COLLECTIONS.filter((key) => !deepEqual(base[key], current[key]));
@@ -24234,8 +23967,7 @@ var init_changes = __esmMin((() => {
24234
23967
  isRowKey = (key) => ROW_COLLECTIONS.includes(key);
24235
23968
  }));
24236
23969
 
24237
- //#endregion
24238
- //#region src/lib/clash-copy.ts
23970
+ // src/lib/clash-copy.ts
24239
23971
  /** A field's value as a person would read it. Long or structured values aren't spelled out. */
24240
23972
  function clashValue(field, value, people, collection = "tasks") {
24241
23973
  if (field === "done") return value ? "done" : "not done";
@@ -24339,8 +24071,7 @@ var init_clash_copy = __esmMin((() => {
24339
24071
  };
24340
24072
  }));
24341
24073
 
24342
- //#endregion
24343
- //#region src/lib/catch-up.ts
24074
+ // src/lib/catch-up.ts
24344
24075
  /**
24345
24076
  * The collections that differ in the server's newer document, or null when
24346
24077
  * none do; `currentUserId` stays this tab's own. An item that didn't change
@@ -24373,8 +24104,7 @@ var init_catch_up = __esmMin((() => {
24373
24104
  hasId = (v) => typeof v === "object" && v !== null && typeof v.id === "string";
24374
24105
  }));
24375
24106
 
24376
- //#endregion
24377
- //#region src/lib/live-changes.ts
24107
+ // src/lib/live-changes.ts
24378
24108
  /** What turned `before` into `after`, for the change log. */
24379
24109
  function changeRecord(before, after) {
24380
24110
  const rows = emptyRows();
@@ -24416,16 +24146,14 @@ var init_live_changes = __esmMin((() => {
24416
24146
  NOT_WHOLE = [...ROW_COLLECTIONS, "currentUserId"];
24417
24147
  }));
24418
24148
 
24419
- //#endregion
24420
- //#region src/lib/roles.ts
24149
+ // src/lib/roles.ts
24421
24150
  /** Anything stored that is not a known role reads as a member, as before roles existed. */
24422
24151
  function normalizeRole(raw) {
24423
24152
  return raw === "owner" || raw === "viewer" ? raw : "member";
24424
24153
  }
24425
24154
  var init_roles = __esmMin((() => {}));
24426
24155
 
24427
- //#endregion
24428
- //#region src/lib/sync-state.ts
24156
+ // src/lib/sync-state.ts
24429
24157
  /** Wait before the nth retry (0-based): 2 s, 4 s, 8 s, 16 s, then every 30 s. */
24430
24158
  function retryDelay(attempt) {
24431
24159
  return Math.min(3e4, 2e3 * 2 ** Math.max(0, attempt));
@@ -24439,8 +24167,7 @@ var init_sync_state = __esmMin((() => {
24439
24167
  }));
24440
24168
  }));
24441
24169
 
24442
- //#endregion
24443
- //#region cli/lib/plain.mjs
24170
+ // cli/lib/plain.mjs
24444
24171
  /** @param {string} text */
24445
24172
  function plain(text) {
24446
24173
  return text.replace(UNSAFE, "");
@@ -24468,8 +24195,7 @@ var init_plain = __esmMin((() => {
24468
24195
  UNSAFE = /[\u0000-\u0008\u000b-\u001f\u007f-\u009f‪-‮⁦-⁩]/g;
24469
24196
  }));
24470
24197
 
24471
- //#endregion
24472
- //#region src/tui/engine/transport.ts
24198
+ // src/tui/engine/transport.ts
24473
24199
  /**
24474
24200
  * The same transport with every answer made plain (cli/lib/plain.mjs):
24475
24201
  * titles, names and notes can come from intake forms, GitHub or anyone in
@@ -24577,8 +24303,7 @@ var init_transport = __esmMin((() => {
24577
24303
  };
24578
24304
  }));
24579
24305
 
24580
- //#endregion
24581
- //#region src/tui/engine/sync.ts
24306
+ // src/tui/engine/sync.ts
24582
24307
  function createSync(opts) {
24583
24308
  const { store, transport } = opts;
24584
24309
  const delay = opts.saveDelayMs ?? 600;
@@ -24797,8 +24522,7 @@ var init_sync = __esmMin((() => {
24797
24522
  init_transport();
24798
24523
  }));
24799
24524
 
24800
- //#endregion
24801
- //#region src/tui/engine/memory-crew.ts
24525
+ // src/tui/engine/memory-crew.ts
24802
24526
  function memoryCrew(account, harbor) {
24803
24527
  let n = 0;
24804
24528
  const token = () => `t${++n}`;
@@ -24975,8 +24699,7 @@ var init_memory_crew = __esmMin((() => {
24975
24699
  ORIGIN = "https://harborppm.com";
24976
24700
  }));
24977
24701
 
24978
- //#endregion
24979
- //#region src/lib/shore.ts
24702
+ // src/lib/shore.ts
24980
24703
  /**
24981
24704
  * Which service an address belongs to, or null when it isn't an incoming
24982
24705
  * webhook Harbor posts to. Only these hosts are allowed, over https, so the
@@ -25035,8 +24758,7 @@ var init_shore = __esmMin((() => {
25035
24758
  ];
25036
24759
  }));
25037
24760
 
25038
- //#endregion
25039
- //#region src/tui/engine/memory.ts
24761
+ // src/tui/engine/memory.ts
25040
24762
  function memoryHarbor(start, opts) {
25041
24763
  const { id, name } = opts.harbor ?? {
25042
24764
  id: "w1",
@@ -25283,8 +25005,7 @@ var init_memory = __esmMin((() => {
25283
25005
  init_transport();
25284
25006
  }));
25285
25007
 
25286
- //#endregion
25287
- //#region src/repo/plan-files.ts
25008
+ // src/repo/plan-files.ts
25288
25009
  /** "RR-42.md" → "RR-42"; a file named anything else is a new task. */
25289
25010
  function keyOfFile(name) {
25290
25011
  return KEY_NAME.exec(name)?.[1] ?? null;
@@ -25566,8 +25287,7 @@ var init_plan_files = __esmMin((() => {
25566
25287
  shown = (v) => Array.isArray(v) ? v.join(", ") || "nothing" : v === null || v === "" ? "nothing" : String(v);
25567
25288
  }));
25568
25289
 
25569
- //#endregion
25570
- //#region src/repo/repo-sync.ts
25290
+ // src/repo/repo-sync.ts
25571
25291
  async function readConfig(folder) {
25572
25292
  const text = await folder.read(CONFIG_FILE);
25573
25293
  if (text === null) return null;
@@ -26085,8 +25805,7 @@ var init_repo_sync = __esmMin((() => {
26085
25805
  };
26086
25806
  }));
26087
25807
 
26088
- //#endregion
26089
- //#region src/tui/try.ts
25808
+ // src/tui/try.ts
26090
25809
  init_format();
26091
25810
  init_task_keys();
26092
25811
  init_tide();
@@ -26280,8 +25999,7 @@ async function saved(sync) {
26280
25999
  if (sync.state !== "saved") throw new HarborError(sync.state === "offline" ? "Can't reach Harbor, so nothing was changed." : "Harbor didn't take the changes. Try again.");
26281
26000
  }
26282
26001
 
26283
- //#endregion
26284
- //#region src/tui/views/dock.tsx
26002
+ // src/tui/views/dock.tsx
26285
26003
  /**
26286
26004
  * Dry dock in the full-screen app, as the website's Try a change runs it
26287
26005
  * (src/lib/dry-dock.ts): changes tried on a copy of the project's plan, the
@@ -26562,8 +26280,7 @@ function DockPanel({ id, width, height, go, active, onClose }) {
26562
26280
  });
26563
26281
  }
26564
26282
 
26565
- //#endregion
26566
- //#region src/tui/views/lifeboats.tsx
26283
+ // src/tui/views/lifeboats.tsx
26567
26284
  /**
26568
26285
  * Lifeboats in the full-screen app, as People and the review list them
26569
26286
  * (src/lib/lifeboats.ts): work only one person has touched, each with a
@@ -26727,8 +26444,7 @@ function LifeboatsPanel({ id, width, height, go, active, onClose }) {
26727
26444
  });
26728
26445
  }
26729
26446
 
26730
- //#endregion
26731
- //#region src/tui/views/shore.tsx
26447
+ // src/tui/views/shore.tsx
26732
26448
  /**
26733
26449
  * Ship to shore in the terminal: a program's Slack, Discord or Teams channel
26734
26450
  * and which posts go there, as the website's dialog sets it (shore.ts). The
@@ -26842,7 +26558,7 @@ function ShorePanel({ id, width, height, go, active, onClose }) {
26842
26558
  }) : !hook ? /* @__PURE__ */ jsxs(Text, {
26843
26559
  wrap: "wrap",
26844
26560
  children: ["No channel yet.", viewOnly ? " An editor can add one." : " Make an incoming webhook in the channel's settings, then p pastes its address."]
26845
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
26561
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
26846
26562
  /* @__PURE__ */ jsxs(Text, {
26847
26563
  wrap: "truncate-end",
26848
26564
  children: [
@@ -26894,8 +26610,7 @@ function ShorePanel({ id, width, height, go, active, onClose }) {
26894
26610
  });
26895
26611
  }
26896
26612
 
26897
- //#endregion
26898
- //#region src/tui/views/welcome.tsx
26613
+ // src/tui/views/welcome.tsx
26899
26614
  init_swatches();
26900
26615
  const TAG = {
26901
26616
  handed: "Handed to you",
@@ -27017,8 +26732,7 @@ function WelcomeView({ when, active, width, height, go, onDone }) {
27017
26732
  });
27018
26733
  }
27019
26734
 
27020
- //#endregion
27021
- //#region src/tui/views/bands.tsx
26735
+ // src/tui/views/bands.tsx
27022
26736
  /**
27023
26737
  * The website's band layouts in the terminal: a portfolio read program by
27024
26738
  * program, a program read project by project. Each band is a few lines; the
@@ -27298,8 +27012,7 @@ function ProjectBands({ bands, at, active, width, height, w, today }) {
27298
27012
  });
27299
27013
  }
27300
27014
 
27301
- //#endregion
27302
- //#region src/tui/views/program.tsx
27015
+ // src/tui/views/program.tsx
27303
27016
  init_raid();
27304
27017
  init_format();
27305
27018
  init_derived_health();
@@ -27430,7 +27143,7 @@ function ProgramView({ programId, active, width, height, go, onBack }) {
27430
27143
  children: ["Next move: ", program.nextMove || "none written yet (e to write one)"]
27431
27144
  }),
27432
27145
  /* @__PURE__ */ jsx(Text, { children: " " }),
27433
- layout === "bands" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Heading, {
27146
+ layout === "bands" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Heading, {
27434
27147
  right: `${mine.length}${split.done.length > 0 ? ` · ${split.done.length} done ${showDone ? "shown" : "hidden"} (D)` : ""} · v board`,
27435
27148
  children: "By project"
27436
27149
  }), mine.length === 0 ? /* @__PURE__ */ jsx(Text, {
@@ -27757,8 +27470,7 @@ function PortfolioView({ portfolioId, active, width, height, go, onBack }) {
27757
27470
  });
27758
27471
  }
27759
27472
 
27760
- //#endregion
27761
- //#region src/tui/bulk.ts
27473
+ // src/tui/bulk.ts
27762
27474
  init_bulk();
27763
27475
  init_board();
27764
27476
  init_swatches();
@@ -27868,10 +27580,10 @@ function bulkMenu(store, go, ids, today, clear) {
27868
27580
  });
27869
27581
  }
27870
27582
 
27871
- //#endregion
27872
- //#region src/tui/views/project.tsx
27583
+ // src/tui/views/project.tsx
27873
27584
  init_swatches();
27874
27585
  init_format();
27586
+ init_task_people();
27875
27587
  init_hill();
27876
27588
  init_bottle();
27877
27589
  init_clock();
@@ -27916,6 +27628,15 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
27916
27628
  filter
27917
27629
  ]);
27918
27630
  const [mode, setMode] = useState("board");
27631
+ const [fileAt, setFileAt] = useState(0);
27632
+ const files = useMemo(() => projectFiles({
27633
+ tasks,
27634
+ attachments
27635
+ }, projectId), [
27636
+ tasks,
27637
+ attachments,
27638
+ projectId
27639
+ ]);
27919
27640
  const [spendAt, setSpendAt] = useState(0);
27920
27641
  const spendEntries = useHarbor((s) => s.spendEntries) ?? [];
27921
27642
  const [col, setCol] = useState(() => Math.max(0, columns.findIndex((c) => c.tasks.length > 0)));
@@ -27955,9 +27676,16 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
27955
27676
  useInput((input, key) => {
27956
27677
  if (key.escape && picked.length) return setPicked([]);
27957
27678
  if (key.escape || key.backspace) return onBack();
27958
- if (input === " " && selected && mode !== "budget") return setPicked((ids) => ids.includes(selected.id) ? ids.filter((x) => x !== selected.id) : [...ids, selected.id]);
27959
- if (input === "m" && picked.length && mode !== "budget") return bulkMenu(store, go, picked, day, () => setPicked([]));
27960
- if (input === "v") return setMode((m) => m === "board" ? "list" : m === "list" ? "budget" : "board");
27679
+ if (input === " " && selected && !(mode === "budget" || mode === "files")) return setPicked((ids) => ids.includes(selected.id) ? ids.filter((x) => x !== selected.id) : [...ids, selected.id]);
27680
+ if (input === "m" && picked.length && !(mode === "budget" || mode === "files")) return bulkMenu(store, go, picked, day, () => setPicked([]));
27681
+ if (input === "v") return setMode((m) => m === "board" ? "list" : m === "list" ? "budget" : m === "budget" ? "files" : "board");
27682
+ if (mode === "files") {
27683
+ const f = files[Math.min(fileAt, files.length - 1)];
27684
+ if (key.upArrow || input === "k") setFileAt((i) => step(i, -1, files.length));
27685
+ else if (key.downArrow || input === "j") setFileAt((i) => step(i, 1, files.length));
27686
+ else if (key.return && f) go.openTask(f.task.id);
27687
+ return;
27688
+ }
27961
27689
  if (input === "e") return go.openPanel("project", projectId);
27962
27690
  if (input === "b") return go.openPanel("board", projectId);
27963
27691
  if (input === "R") return go.create("raid", { projectId });
@@ -28103,7 +27831,7 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
28103
27831
  lead ? ` · ${lead.name}` : "",
28104
27832
  " · ",
28105
27833
  mode,
28106
- filtered.length && mode !== "budget" ? /* @__PURE__ */ jsxs(Text, {
27834
+ filtered.length && !(mode === "budget" || mode === "files") ? /* @__PURE__ */ jsxs(Text, {
28107
27835
  color: theme.warn,
28108
27836
  children: [
28109
27837
  " · only ",
@@ -28112,7 +27840,7 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
28112
27840
  ]
28113
27841
  }) : null,
28114
27842
  " ",
28115
- picked.length && mode !== "budget" ? /* @__PURE__ */ jsxs(Text, {
27843
+ picked.length && !(mode === "budget" || mode === "files") ? /* @__PURE__ */ jsxs(Text, {
28116
27844
  color: theme.accent,
28117
27845
  children: [
28118
27846
  " ",
@@ -28171,7 +27899,16 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
28171
27899
  ] })
28172
27900
  ]
28173
27901
  }),
28174
- mode === "budget" ? /* @__PURE__ */ jsx(BudgetPane, {
27902
+ mode === "files" ? /* @__PURE__ */ jsx(FilesPane, {
27903
+ files,
27904
+ projects,
27905
+ people,
27906
+ at: fileAt,
27907
+ active,
27908
+ height: body,
27909
+ width: width - 2,
27910
+ today: day
27911
+ }) : mode === "budget" ? /* @__PURE__ */ jsx(BudgetPane, {
28175
27912
  project,
28176
27913
  spendEntries,
28177
27914
  at: spendAt,
@@ -28425,9 +28162,67 @@ function BudgetPane({ project, spendEntries, at, active, height, today }) {
28425
28162
  ]
28426
28163
  });
28427
28164
  }
28165
+ /** Every file on the project's tasks, newest first; Enter opens the task it's on. */
28166
+ function FilesPane({ files, projects, people, at, active, height, width, today }) {
28167
+ const sel = Math.min(at, files.length - 1);
28168
+ return /* @__PURE__ */ jsxs(Box, {
28169
+ flexDirection: "column",
28170
+ height,
28171
+ width,
28172
+ children: [
28173
+ /* @__PURE__ */ jsx(Heading, {
28174
+ right: "↑↓ pick · Enter opens its task · added on the website",
28175
+ children: `Files ${files.length}`
28176
+ }),
28177
+ files.length === 0 ? /* @__PURE__ */ jsx(Text, {
28178
+ color: theme.muted,
28179
+ children: "No files yet. Attach images, PDFs and links to a task on the website."
28180
+ }) : null,
28181
+ windowOf(files, sel, Math.max(1, height - 1)).items.map(({ file, task }) => {
28182
+ const on = active && file.id === files[sel]?.file.id;
28183
+ const who = people.find((p) => p.id === file.addedBy)?.name.split(" ")[0] ?? "someone";
28184
+ return /* @__PURE__ */ jsxs(Text, {
28185
+ color: on ? theme.selected : void 0,
28186
+ bold: on,
28187
+ wrap: "truncate-end",
28188
+ children: [
28189
+ on ? "› " : " ",
28190
+ /* @__PURE__ */ jsx(Text, {
28191
+ color: theme.muted,
28192
+ children: FILE_KIND[file.kind].padEnd(5)
28193
+ }),
28194
+ " ",
28195
+ file.name,
28196
+ " ",
28197
+ /* @__PURE__ */ jsxs(Text, {
28198
+ color: theme.muted,
28199
+ children: [
28200
+ who,
28201
+ ", ",
28202
+ shortDay(file.addedAt.slice(0, 10), today),
28203
+ " · on"
28204
+ ]
28205
+ }),
28206
+ " ",
28207
+ /* @__PURE__ */ jsx(Text, {
28208
+ color: on ? void 0 : theme.accent,
28209
+ children: keyOf$1({ projects }, task)
28210
+ }),
28211
+ " ",
28212
+ task.title
28213
+ ]
28214
+ }, file.id);
28215
+ })
28216
+ ]
28217
+ });
28218
+ }
28219
+ const FILE_KIND = {
28220
+ image: "image",
28221
+ doc: "doc",
28222
+ link: "link"
28223
+ };
28428
28224
 
28429
- //#endregion
28430
- //#region src/tui/views/roadmap.tsx
28225
+ // src/tui/views/roadmap.tsx
28431
28226
  const NAME = 26;
28432
28227
  /**
28433
28228
  * A portfolio's programs and projects across the months, as on the
@@ -28535,8 +28330,7 @@ function RoadmapView({ active, width, height, go }) {
28535
28330
  });
28536
28331
  }
28537
28332
 
28538
- //#endregion
28539
- //#region src/lib/automation-text.ts
28333
+ // src/lib/automation-text.ts
28540
28334
  init_swatches();
28541
28335
  const TRIGGER_LABEL = {
28542
28336
  task_created: "A task is created",
@@ -28588,8 +28382,7 @@ function defaultAction(type) {
28588
28382
  };
28589
28383
  }
28590
28384
 
28591
- //#endregion
28592
- //#region src/lib/custom-field-text.ts
28385
+ // src/lib/custom-field-text.ts
28593
28386
  const FIELD_TYPE_LABEL = {
28594
28387
  text: "Text",
28595
28388
  number: "Number",
@@ -28616,8 +28409,7 @@ function readFieldValue(def, text) {
28616
28409
  return Number.isFinite(n) ? n : void 0;
28617
28410
  }
28618
28411
 
28619
- //#endregion
28620
- //#region src/tui/views/setup.tsx
28412
+ // src/tui/views/setup.tsx
28621
28413
  /**
28622
28414
  * A project's board setup, as the website's board settings have it: where it
28623
28415
  * starts from, each column (name, shown, cap, place), lanes and what cards
@@ -28964,8 +28756,7 @@ function BoardPanel({ id, width, height, go, active, onClose }) {
28964
28756
  });
28965
28757
  }
28966
28758
 
28967
- //#endregion
28968
- //#region src/tui/views/sounding.ts
28759
+ // src/tui/views/sounding.ts
28969
28760
  init_soundings();
28970
28761
  const nameOf = (people, id) => people.find((p) => p.id === id)?.name ?? "someone";
28971
28762
  /** The lines under a task: who's been asked, what's in, and the verdict once shown. */
@@ -29093,13 +28884,13 @@ function days(go, label, initial, then) {
29093
28884
  }, initial == null ? "" : String(initial));
29094
28885
  }
29095
28886
 
29096
- //#endregion
29097
- //#region src/tui/views/task.tsx
28887
+ // src/tui/views/task.tsx
29098
28888
  init_clock();
29099
28889
  init_date_text();
29100
28890
  init_work();
29101
28891
  init_blockers();
29102
28892
  init_recurrence();
28893
+ init_task_people();
29103
28894
  init_search();
29104
28895
  init_swatches();
29105
28896
  const FIELDS = [
@@ -29189,6 +28980,14 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29189
28980
  const item = task.checklist[at - stepsFrom];
29190
28981
  if (item && (input === " " || key.return)) return store.getState().toggleChecklistItem(task.id, item.id);
29191
28982
  if (item && input === "-") return store.getState().removeChecklistItem(task.id, item.id);
28983
+ if (input === "o") {
28984
+ if (viewOnly) return go.notify("You can only view this harbor.");
28985
+ if (alsoOnIds(task).length === 0 && alsoOnChoices(task, people).length === 0) return go.notify("Nobody else to put on it yet. Invite your crew first.");
28986
+ return setEditing({
28987
+ kind: "field",
28988
+ field: "also"
28989
+ });
28990
+ }
29192
28991
  if (key.return && FIELDS[at]) return setEditing({
29193
28992
  kind: "field",
29194
28993
  field: FIELDS[at].field
@@ -29223,6 +29022,7 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29223
29022
  title: task.title,
29224
29023
  status: STATUS_LABEL[task.status],
29225
29024
  assignee: owner?.name ?? "Nobody yet",
29025
+ also: alsoOnIds(task).map((id) => people.find((p) => p.id === id)?.name ?? "someone").join(", ") || "Only the owner",
29226
29026
  due: task.dueDate ? `${shortDay(task.dueDate, day)}${isLate(task, day) ? " (late)" : ""}` : "None",
29227
29027
  priority: PRIORITY_LABEL[task.priority],
29228
29028
  project: project ? `${project.name}${project.key ? ` (${project.key})` : ""}` : "",
@@ -29364,6 +29164,25 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29364
29164
  done();
29365
29165
  }
29366
29166
  });
29167
+ } else if (f === "also") {
29168
+ const on = alsoOnIds(task);
29169
+ const choices = [...on.map((id) => ({
29170
+ label: `Take off ${people.find((p) => p.id === id)?.name ?? "someone"}`,
29171
+ value: id
29172
+ })), ...alsoOnChoices(task, people).map((p) => ({
29173
+ label: `Put on ${p.name}`,
29174
+ value: p.id,
29175
+ hint: p.role
29176
+ }))];
29177
+ editor = /* @__PURE__ */ jsx(Picker, {
29178
+ title: "Also on it, beside the owner",
29179
+ choices,
29180
+ onCancel: done,
29181
+ onPick: (id) => {
29182
+ store.getState().updateTask(task.id, alsoOnPatch(task, on.includes(id) ? on.filter((x) => x !== id) : [...on, id]));
29183
+ done();
29184
+ }
29185
+ });
29367
29186
  } else if (f === "repeat") editor = /* @__PURE__ */ jsx(Picker, {
29368
29187
  title: "Repeats (finishing it queues the next one)",
29369
29188
  choices: REPEATS.map((r) => ({
@@ -29427,7 +29246,7 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29427
29246
  ]
29428
29247
  }),
29429
29248
  /* @__PURE__ */ jsx(Text, { children: " " }),
29430
- FIELDS.map((f, i) => /* @__PURE__ */ jsxs(Text, {
29249
+ FIELDS.map((f, i) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Text, {
29431
29250
  wrap: "truncate-end",
29432
29251
  color: at === i ? theme.selected : void 0,
29433
29252
  bold: at === i,
@@ -29439,7 +29258,21 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29439
29258
  }),
29440
29259
  value[f.field]
29441
29260
  ]
29442
- }, f.field)),
29261
+ }), f.field === "assignee" ? /* @__PURE__ */ jsxs(Text, {
29262
+ wrap: "truncate-end",
29263
+ children: [
29264
+ " ",
29265
+ /* @__PURE__ */ jsx(Text, {
29266
+ color: theme.muted,
29267
+ children: "Also on".padEnd(9)
29268
+ }),
29269
+ value.also,
29270
+ /* @__PURE__ */ jsx(Text, {
29271
+ color: theme.muted,
29272
+ children: " · o changes"
29273
+ })
29274
+ ]
29275
+ }) : null] }, f.field)),
29443
29276
  own.map((f, n) => {
29444
29277
  const on = at === FIELDS.length + n;
29445
29278
  return /* @__PURE__ */ jsxs(Text, {
@@ -29538,7 +29371,7 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29538
29371
  editor ?? /* @__PURE__ */ jsx(Text, {
29539
29372
  color: theme.muted,
29540
29373
  wrap: "truncate-end",
29541
- children: "↑↓ field · Enter change · c comment · C yours · a add step · space tick · x done · S sounding · d delete · Esc close"
29374
+ children: "↑↓ field · Enter change · o who's on it · c comment · C yours · a add step · space tick · x done · S sounding · d delete · Esc close"
29542
29375
  })
29543
29376
  ]
29544
29377
  });
@@ -29674,9 +29507,9 @@ function WaitsEditor({ task, onDone }) {
29674
29507
  });
29675
29508
  }
29676
29509
 
29677
- //#endregion
29678
- //#region src/tui/views/today.tsx
29510
+ // src/tui/views/today.tsx
29679
29511
  init_focus();
29512
+ init_task_people();
29680
29513
  /**
29681
29514
  * What's on you: today's focus and check-in, your open tasks, late first;
29682
29515
  * who waits on you; your risks and issues.
@@ -29708,6 +29541,8 @@ function TodayView({ active, width, height, go }) {
29708
29541
  ]);
29709
29542
  const waits = useMemo(() => waitingOnMe(data, me), [data, me]);
29710
29543
  const risks = useMemo(() => myRaid(data, me), [data, me]);
29544
+ const people = useHarbor((s) => s.people);
29545
+ const alsoOn = useMemo(() => tasksAlsoOn(data, me), [data, me]);
29711
29546
  const [at, setAt] = useState(0);
29712
29547
  const selected = mine[Math.min(at, mine.length - 1)];
29713
29548
  const late = mine.filter((t) => isLate(t, day)).length;
@@ -29737,7 +29572,7 @@ function TodayView({ active, width, height, go }) {
29737
29572
  });
29738
29573
  }, said?.body);
29739
29574
  }, { isActive: active });
29740
- const extra = (focus.length ? focus.length + 2 : 0) + 1 + (waits.length ? waits.length + 2 : 0) + (risks.length ? Math.min(risks.length, 5) + 2 : 0);
29575
+ const extra = (focus.length ? focus.length + 2 : 0) + 1 + (waits.length ? waits.length + 2 : 0) + (alsoOn.length ? Math.min(alsoOn.length, 5) + 2 : 0) + (risks.length ? Math.min(risks.length, 5) + 2 : 0);
29741
29576
  const rows = Math.max(3, height - 2 - extra);
29742
29577
  const view = windowOf(mine, at, rows);
29743
29578
  return /* @__PURE__ */ jsxs(Box, {
@@ -29802,6 +29637,30 @@ function TodayView({ active, width, height, go }) {
29802
29637
  ]
29803
29638
  }, theirs.id + blocker.id))]
29804
29639
  }),
29640
+ alsoOn.length > 0 && /* @__PURE__ */ jsxs(Box, {
29641
+ flexDirection: "column",
29642
+ marginTop: 1,
29643
+ children: [/* @__PURE__ */ jsx(Heading, {
29644
+ right: alsoOn.length > 5 ? `${alsoOn.length - 5} more` : void 0,
29645
+ children: "Also on (others own these)"
29646
+ }), alsoOn.slice(0, 5).map((t) => /* @__PURE__ */ jsxs(Text, {
29647
+ wrap: "truncate-end",
29648
+ children: [
29649
+ " ",
29650
+ /* @__PURE__ */ jsx(Text, {
29651
+ color: theme.accent,
29652
+ children: keyOf$1({ projects }, t)
29653
+ }),
29654
+ " ",
29655
+ t.title,
29656
+ " ",
29657
+ /* @__PURE__ */ jsx(Text, {
29658
+ color: theme.muted,
29659
+ children: people.find((p) => p.id === t.assigneeId)?.name ?? "nobody's yet"
29660
+ })
29661
+ ]
29662
+ }, t.id))]
29663
+ }),
29805
29664
  risks.length > 0 && /* @__PURE__ */ jsxs(Box, {
29806
29665
  flexDirection: "column",
29807
29666
  marginTop: 1,
@@ -29822,8 +29681,7 @@ function TodayView({ active, width, height, go }) {
29822
29681
  });
29823
29682
  }
29824
29683
 
29825
- //#endregion
29826
- //#region src/tui/views/week.tsx
29684
+ // src/tui/views/week.tsx
29827
29685
  init_date_text();
29828
29686
  init_passage();
29829
29687
  const dayName = (date) => format(parseIso(`${date}T12:00:00`), "EEEE");
@@ -30005,8 +29863,7 @@ function WeekView({ active, width, height, go }) {
30005
29863
  });
30006
29864
  }
30007
29865
 
30008
- //#endregion
30009
- //#region src/tui/app.tsx
29866
+ // src/tui/app.tsx
30010
29867
  /**
30011
29868
  * The terminal app's shell: a header (harbor, save state), a sidebar, the
30012
29869
  * screen, and the keys along the bottom. Opening a portfolio, program or
@@ -30688,8 +30545,7 @@ function App({ ui, startIn }) {
30688
30545
  });
30689
30546
  }
30690
30547
 
30691
- //#endregion
30692
- //#region src/tui/theme-detect.ts
30548
+ // src/tui/theme-detect.ts
30693
30549
  const isThemeSetting = (v) => v === "auto" || v === "light" || v === "dark";
30694
30550
  /** COLORFGBG is "fg;bg" (sometimes "fg;x;bg"): background 7 or 15 is a light terminal. */
30695
30551
  function themeFromColorFgBg(value) {
@@ -30735,8 +30591,7 @@ async function pickTheme(setting, env = process.env, ask = () => askBackground(p
30735
30591
  return themeFromColorFgBg(env.COLORFGBG) ?? await ask() ?? "dark";
30736
30592
  }
30737
30593
 
30738
- //#endregion
30739
- //#region src/tui/ui-state.ts
30594
+ // src/tui/ui-state.ts
30740
30595
  init_vanilla();
30741
30596
  function createUiStore() {
30742
30597
  return createStore()(() => ({
@@ -30745,8 +30600,7 @@ function createUiStore() {
30745
30600
  }));
30746
30601
  }
30747
30602
 
30748
- //#endregion
30749
- //#region src/tui/first-run.ts
30603
+ // src/tui/first-run.ts
30750
30604
  init_empty();
30751
30605
  async function firstHarbor(deps) {
30752
30606
  const fallback = suggestedHarborName(deps.account.name, deps.account.email);
@@ -30792,8 +30646,7 @@ async function pickHarbor(deps) {
30792
30646
  }
30793
30647
  }
30794
30648
 
30795
- //#endregion
30796
- //#region src/tui/fog-sweep.ts
30649
+ // src/tui/fog-sweep.ts
30797
30650
  /**
30798
30651
  * `harbor fog --sweep` in a terminal: the tasks nobody has touched for three weeks
30799
30652
  * (lib/fog.ts), one at a time, on the store's own actions. k keeps it
@@ -30882,8 +30735,7 @@ function fogSummary(t) {
30882
30735
  return parts.length ? `${parts.join(", ")}.` : "Nothing changed.";
30883
30736
  }
30884
30737
 
30885
- //#endregion
30886
- //#region src/tui/watch.ts
30738
+ // src/tui/watch.ts
30887
30739
  init_clock();
30888
30740
  init_date_text();
30889
30741
  init_format();
@@ -31060,8 +30912,7 @@ function sinceText(iso, now) {
31060
30912
  return wall.slice(0, 10) === wallClock(now).slice(0, 10) ? time : `${shortDate(wall.slice(0, 10))}, ${time}`;
31061
30913
  }
31062
30914
 
31063
- //#endregion
31064
- //#region src/tui/watch-run.ts
30915
+ // src/tui/watch-run.ts
31065
30916
  init_clock();
31066
30917
  init_plain();
31067
30918
  init_repo_sync();
@@ -31151,8 +31002,7 @@ async function watchOn(opts) {
31151
31002
  }
31152
31003
  }
31153
31004
 
31154
- //#endregion
31155
- //#region src/repo/folder.ts
31005
+ // src/repo/folder.ts
31156
31006
  /**
31157
31007
  * The `.harbor/` folder on disk, and finding it: like git, `harbor sync`
31158
31008
  * works from anywhere inside the repository.
@@ -31220,8 +31070,7 @@ var init_folder = __esmMin((() => {
31220
31070
  PLAN_DIR = ".harbor";
31221
31071
  }));
31222
31072
 
31223
- //#endregion
31224
- //#region src/repo/commands.ts
31073
+ // src/repo/commands.ts
31225
31074
  /**
31226
31075
  * `harbor init` and `harbor sync` as the CLI runs them (cli/lib/cli.mjs,
31227
31076
  * through the bundled app): the folder on disk, the signed-in transport, and
@@ -31373,8 +31222,7 @@ var init_commands = __esmMin((() => {
31373
31222
  HOOK = "harbor sync --quiet || true";
31374
31223
  }));
31375
31224
 
31376
- //#endregion
31377
- //#region src/tui/main.tsx
31225
+ // src/tui/main.tsx
31378
31226
  /**
31379
31227
  * The Harbor terminal app, started by `harbor` with no arguments (cli/).
31380
31228
  * Bundled into cli/dist/app.mjs by cli/build.mjs; Ink and React stay the
@@ -31662,5 +31510,4 @@ function planTransport(source, fetcher) {
31662
31510
  return httpTransport(source, fetcher);
31663
31511
  }
31664
31512
 
31665
- //#endregion
31666
31513
  export { SPLASH_MS, TransportError, firstHarbor, fogHere, harborNamed, httpTransport, initHere, initLocalHere, localPlanAt, planTransport, runApp, runLocalApp, startApp, syncHere, tryHere, watchHere, watchSince };