@harborppm/cli 0.71.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();
@@ -5879,6 +5659,14 @@ function neighbourStatus(data, projectId, status, step) {
5879
5659
  function projectTasks(data, projectId) {
5880
5660
  return [...tasksOf(data.tasks, projectId)].sort((a, b) => STATUS_ORDER.indexOf(a.status) - STATUS_ORDER.indexOf(b.status) || (a.number ?? 0) - (b.number ?? 0));
5881
5661
  }
5662
+ /**
5663
+ * The project a new task goes in when none was picked: the only open one,
5664
+ * First voyage aside, as harbor add does. Null when there's a choice to make.
5665
+ */
5666
+ function soleOpenProject(projects) {
5667
+ const open = projects.filter((p) => p.health !== "done" && !isVoyageProject(p.id));
5668
+ return open.length === 1 ? open[0].id : null;
5669
+ }
5882
5670
  function blocked(data, task) {
5883
5671
  return isBlocked$1(task, data.tasks);
5884
5672
  }
@@ -6004,7 +5792,7 @@ const NO_FILTER = {
6004
5792
  };
6005
5793
  function filterTasks(tasks, f) {
6006
5794
  if (f.who === "any" && f.priority === "any") return tasks;
6007
- 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));
6008
5796
  }
6009
5797
  /**
6010
5798
  * When the project will likely finish at its crew's recent pace, in one
@@ -6481,8 +6269,7 @@ function weekReviewLines(data, me, monday) {
6481
6269
  return out;
6482
6270
  }
6483
6271
 
6484
- //#endregion
6485
- //#region src/tui/theme.ts
6272
+ // src/tui/theme.ts
6486
6273
  /**
6487
6274
  * Dark: Harbor's teal and coral lifted so they read on black, and status in
6488
6275
  * softened hues rather than the terminal's own loud green and yellow (a
@@ -6541,8 +6328,7 @@ function applyTheme(name) {
6541
6328
  }
6542
6329
  applyTheme("dark");
6543
6330
 
6544
- //#endregion
6545
- //#region src/tui/ui.tsx
6331
+ // src/tui/ui.tsx
6546
6332
  /**
6547
6333
  * The terminal app's small parts: a one-line text field, a list to pick
6548
6334
  * from, the key hints along the bottom, health and priority marks.
@@ -6727,8 +6513,7 @@ function Heading({ children, right }) {
6727
6513
  });
6728
6514
  }
6729
6515
 
6730
- //#endregion
6731
- //#region src/tui/forms.tsx
6516
+ // src/tui/forms.tsx
6732
6517
  /**
6733
6518
  * Two shapes most screens use: a panel of fields where Enter changes the
6734
6519
  * one picked (DetailPanel), and a few questions in a row to make something
@@ -6938,8 +6723,7 @@ function Stepper({ title, steps, width, onDone, onCancel }) {
6938
6723
  });
6939
6724
  }
6940
6725
 
6941
- //#endregion
6942
- //#region src/lib/health-history.ts
6726
+ // src/lib/health-history.ts
6943
6727
  /** The history with one more line when `health` differs from the last recorded one. Same array otherwise. */
6944
6728
  function recordHealth(history, health, at, override, note) {
6945
6729
  const last = history?.[history.length - 1];
@@ -6953,8 +6737,7 @@ function recordHealth(history, health, at, override, note) {
6953
6737
  }
6954
6738
  var init_health_history = __esmMin((() => {}));
6955
6739
 
6956
- //#endregion
6957
- //#region src/lib/derived-health.ts
6740
+ // src/lib/derived-health.ts
6958
6741
  function parseDate(value) {
6959
6742
  return parseIso(value.length === 10 ? `${value}T12:00:00` : value);
6960
6743
  }
@@ -7217,8 +7000,7 @@ var init_derived_health = __esmMin((() => {
7217
7000
  untilByDate = /* @__PURE__ */ new Map();
7218
7001
  }));
7219
7002
 
7220
- //#endregion
7221
- //#region src/lib/bottle-rules.ts
7003
+ // src/lib/bottle-rules.ts
7222
7004
  /**
7223
7005
  * Why a new note can't be sealed, or null when it can: nothing written, a
7224
7006
  * date that isn't after today (it would open at once), or a milestone that
@@ -7243,8 +7025,7 @@ var init_bottle_rules = __esmMin((() => {
7243
7025
  BOTTLE_MAX = 1e3;
7244
7026
  }));
7245
7027
 
7246
- //#endregion
7247
- //#region src/lib/bottle.ts
7028
+ // src/lib/bottle.ts
7248
7029
  /** This project's notes, oldest first. */
7249
7030
  function bottlesOf(reflections, projectId) {
7250
7031
  return (reflections ?? []).filter((r) => r.projectId === projectId && isBottle(r)).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
@@ -7342,8 +7123,7 @@ var init_bottle = __esmMin((() => {
7342
7123
  day$3 = (iso) => format(parseIso(iso.slice(0, 10)), "MMM d");
7343
7124
  }));
7344
7125
 
7345
- //#endregion
7346
- //#region src/lib/decisions.ts
7126
+ // src/lib/decisions.ts
7347
7127
  /** A risk counts as come true when someone said so, or when it was turned into an issue. */
7348
7128
  function cameTrue(risk) {
7349
7129
  return risk.happened === true || risk.kind === "issue";
@@ -7421,8 +7201,7 @@ var init_decisions = __esmMin((() => {
7421
7201
  md$1 = (iso) => format(parseIso(iso.slice(0, 10)), "MMM d");
7422
7202
  }));
7423
7203
 
7424
- //#endregion
7425
- //#region src/lib/brief.ts
7204
+ // src/lib/brief.ts
7426
7205
  /**
7427
7206
  * Open projects whose plan has grown enough since the baseline to mention
7428
7207
  * (barnacles.ts), most grown first.
@@ -7899,8 +7678,7 @@ var init_brief = __esmMin((() => {
7899
7678
  BRIEF_LATE_SHOWN = 8;
7900
7679
  }));
7901
7680
 
7902
- //#endregion
7903
- //#region src/lib/shipping-forecast.ts
7681
+ // src/lib/shipping-forecast.ts
7904
7682
  /** Small numbers as words, which a voice reads better and the forecast always uses. */
7905
7683
  function spoken(n) {
7906
7684
  return n >= 0 && n < WORDS.length ? WORDS[n] : String(n);
@@ -8069,8 +7847,7 @@ var init_shipping_forecast = __esmMin((() => {
8069
7847
  };
8070
7848
  }));
8071
7849
 
8072
- //#endregion
8073
- //#region src/tui/views/letter.tsx
7850
+ // src/tui/views/letter.tsx
8074
7851
  init_shipping_forecast();
8075
7852
  /**
8076
7853
  * A letter Harbor wrote (the brief, a status report) to read in the
@@ -8124,8 +7901,7 @@ function Letter({ title, text, hints, width, height, active, keys = {}, onClose
8124
7901
  });
8125
7902
  }
8126
7903
 
8127
- //#endregion
8128
- //#region src/tui/views/brief.tsx
7904
+ // src/tui/views/brief.tsx
8129
7905
  init_brief();
8130
7906
  init_swatches();
8131
7907
  /**
@@ -8250,8 +8026,7 @@ function BriefView({ active, width, height, go }) {
8250
8026
  });
8251
8027
  }
8252
8028
 
8253
- //#endregion
8254
- //#region src/lib/bridge.ts
8029
+ // src/lib/bridge.ts
8255
8030
  init_date_fns();
8256
8031
  init_indexes();
8257
8032
  init_raid();
@@ -8464,8 +8239,7 @@ function reviewedPrograms(slides, quiet) {
8464
8239
  return [.../* @__PURE__ */ new Set([...slides.map((s) => s.program.id), ...quiet.map((q) => q.program.id)])];
8465
8240
  }
8466
8241
 
8467
- //#endregion
8468
- //#region src/tui/views/bridge.tsx
8242
+ // src/tui/views/bridge.tsx
8469
8243
  init_date_fns();
8470
8244
  init_date_text();
8471
8245
  const WORD = {
@@ -8745,8 +8519,7 @@ function BridgeView({ active, width, height, go, programIds, onBack }) {
8745
8519
  });
8746
8520
  }
8747
8521
 
8748
- //#endregion
8749
- //#region src/lib/review.ts
8522
+ // src/lib/review.ts
8750
8523
  init_indexes();
8751
8524
  init_derived_health();
8752
8525
  /** A program is someone's when they lead it, lead one of its projects or hold a task in one. */
@@ -8782,8 +8555,7 @@ function blankCharters(data, programs, today) {
8782
8555
  return out.sort((a, b) => b.days - a.days || a.project.name.localeCompare(b.project.name));
8783
8556
  }
8784
8557
 
8785
- //#endregion
8786
- //#region src/tui/moves.ts
8558
+ // src/tui/moves.ts
8787
8559
  init_board();
8788
8560
  function moveTask(store, go, task, status) {
8789
8561
  const s = store.getState();
@@ -8806,8 +8578,7 @@ function roomFor(store, projectId, status) {
8806
8578
  return null;
8807
8579
  }
8808
8580
 
8809
- //#endregion
8810
- //#region src/tui/views/common.tsx
8581
+ // src/tui/views/common.tsx
8811
8582
  /** One task on one line: key, title, due, priority, and where it lives. */
8812
8583
  function TaskLine({ task, projects, people, today, selected, picked = false, width, showProject = true, showAssignee = false, blocked = false }) {
8813
8584
  const late = isLate(task, today);
@@ -8865,8 +8636,7 @@ function step(at, delta, length) {
8865
8636
  return Math.max(0, Math.min(length - 1, at + delta));
8866
8637
  }
8867
8638
 
8868
- //#endregion
8869
- //#region src/tui/views/calendar.tsx
8639
+ // src/tui/views/calendar.tsx
8870
8640
  init_date_fns();
8871
8641
  init_date_text();
8872
8642
  const WEEKDAYS$1 = [
@@ -9012,8 +8782,7 @@ function CalendarView({ active, width, height, go }) {
9012
8782
  });
9013
8783
  }
9014
8784
 
9015
- //#endregion
9016
- //#region src/tui/views/crew.tsx
8785
+ // src/tui/views/crew.tsx
9017
8786
  /**
9018
8787
  * The Crew screen: who's aboard and what they can do, and for the owner the
9019
8788
  * letters still out, share links (with their Monday update) and intake
@@ -9295,8 +9064,7 @@ function CrewView({ active, width, height, go }) {
9295
9064
  });
9296
9065
  }
9297
9066
 
9298
- //#endregion
9299
- //#region src/lib/hill.ts
9067
+ // src/lib/hill.ts
9300
9068
  /** A position kept on the scale, in whole steps. */
9301
9069
  function clampHill(at) {
9302
9070
  if (!Number.isFinite(at)) return 0;
@@ -9332,8 +9100,7 @@ var init_hill = __esmMin((() => {
9332
9100
  };
9333
9101
  }));
9334
9102
 
9335
- //#endregion
9336
- //#region src/lib/history-copy.ts
9103
+ // src/lib/history-copy.ts
9337
9104
  init_blockers();
9338
9105
  init_format();
9339
9106
  init_hill();
@@ -9523,6 +9290,16 @@ function describeEvent(e, names) {
9523
9290
  detail: null
9524
9291
  };
9525
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
+ }
9526
9303
  default: return {
9527
9304
  action: `changed ${e.field ?? "something on"}`,
9528
9305
  detail: null
@@ -9536,8 +9313,7 @@ function actorOf(row, people) {
9536
9313
  return row.via ? `${who} via ${row.via}` : who;
9537
9314
  }
9538
9315
 
9539
- //#endregion
9540
- //#region src/tui/views/history.tsx
9316
+ // src/tui/views/history.tsx
9541
9317
  init_date_text();
9542
9318
  /**
9543
9319
  * Who changed what, newest first, for a portfolio, program or project (s
@@ -9727,8 +9503,7 @@ function HistoryView({ active, width, height, go }) {
9727
9503
  });
9728
9504
  }
9729
9505
 
9730
- //#endregion
9731
- //#region src/lib/inbox.ts
9506
+ // src/lib/inbox.ts
9732
9507
  init_date_fns();
9733
9508
  init_indexes();
9734
9509
  init_flow();
@@ -9921,8 +9696,7 @@ function inboxOf(data, personId, now = clockNow()) {
9921
9696
  });
9922
9697
  }
9923
9698
 
9924
- //#endregion
9925
- //#region src/tui/views/inbox.tsx
9699
+ // src/tui/views/inbox.tsx
9926
9700
  init_date_text();
9927
9701
  /** What's asking for you, the same pings as the website's Inbox: Enter opens one, space marks it read. */
9928
9702
  function InboxView({ active, width, height, go }) {
@@ -10011,8 +9785,7 @@ function InboxView({ active, width, height, go }) {
10011
9785
  });
10012
9786
  }
10013
9787
 
10014
- //#endregion
10015
- //#region src/lib/load.ts
9788
+ // src/lib/load.ts
10016
9789
  /** Open tasks for one person, bucketed by the week they are due, plus what is already late or has no date. */
10017
9790
  function weeklyLoad(tasks, personId, now, weeks = 6, calendar) {
10018
9791
  const mine = tasks.filter((t) => t.assigneeId === personId && t.status !== "done");
@@ -10065,8 +9838,7 @@ var init_load = __esmMin((() => {
10065
9838
  };
10066
9839
  }));
10067
9840
 
10068
- //#endregion
10069
- //#region src/lib/handover.ts
9841
+ // src/lib/handover.ts
10070
9842
  /** Everything a person carries that someone else would have to pick up, grouped in KIND_ORDER. */
10071
9843
  function handoverItems(data, personId) {
10072
9844
  const projects = byId(data.projects);
@@ -10288,8 +10060,7 @@ var init_handover = __esmMin((() => {
10288
10060
  itemKey = (item) => `${item.kind}:${item.id}`;
10289
10061
  }));
10290
10062
 
10291
- //#endregion
10292
- //#region src/lib/lifeboats.ts
10063
+ // src/lib/lifeboats.ts
10293
10064
  init_date_fns();
10294
10065
  init_indexes();
10295
10066
  init_raid();
@@ -10532,8 +10303,7 @@ function awayNote(data, lines, today) {
10532
10303
  return notes;
10533
10304
  }
10534
10305
 
10535
- //#endregion
10536
- //#region src/lib/priority.ts
10306
+ // src/lib/priority.ts
10537
10307
  /** Rules with anything missing or out of range brought back to the defaults. */
10538
10308
  function normalizeRules(rules) {
10539
10309
  const impactThreshold = Number(rules?.impactThreshold);
@@ -10567,8 +10337,7 @@ var init_priority = __esmMin((() => {
10567
10337
  };
10568
10338
  }));
10569
10339
 
10570
- //#endregion
10571
- //#region src/tui/views/heat.tsx
10340
+ // src/tui/views/heat.tsx
10572
10341
  init_priority();
10573
10342
  init_raid();
10574
10343
  const CELL = 7;
@@ -10625,8 +10394,7 @@ function cellWords(cell) {
10625
10394
  return `${PROBABILITY_LABEL[cell.probability].toLowerCase()}, ${IMPACT_LABEL[cell.impact].toLowerCase()} impact`;
10626
10395
  }
10627
10396
 
10628
- //#endregion
10629
- //#region src/lib/deps.ts
10397
+ // src/lib/deps.ts
10630
10398
  init_blockers();
10631
10399
  /** True when making `id` wait on `candidate` would close a loop (or is `id` itself). */
10632
10400
  function wouldCycle(id, candidate, items) {
@@ -10671,8 +10439,7 @@ function blockerOptions(items, id) {
10671
10439
  return items.filter((n) => n.id !== id && !loops.has(n.id));
10672
10440
  }
10673
10441
 
10674
- //#endregion
10675
- //#region src/lib/status-report.ts
10442
+ // src/lib/status-report.ts
10676
10443
  init_derived_health();
10677
10444
  init_flow();
10678
10445
  init_format();
@@ -10744,8 +10511,7 @@ function composeStatusReport(data, program, now = /* @__PURE__ */ new Date()) {
10744
10511
  return lines.join("\n");
10745
10512
  }
10746
10513
 
10747
- //#endregion
10748
- //#region src/tui/views/decision-fields.ts
10514
+ // src/tui/views/decision-fields.ts
10749
10515
  init_date_fns();
10750
10516
  init_decisions();
10751
10517
  init_date_text();
@@ -10914,8 +10680,7 @@ function decisionFields(item, store, go, today) {
10914
10680
  return fields;
10915
10681
  }
10916
10682
 
10917
- //#endregion
10918
- //#region src/tui/views/panels.tsx
10683
+ // src/tui/views/panels.tsx
10919
10684
  /**
10920
10685
  * The panels that change one thing in place: a program, a portfolio, a
10921
10686
  * project's details, a milestone, a risk (issue, decision), a person. Each
@@ -11009,7 +10774,7 @@ const movesRows = (history, today) => {
11009
10774
  function HealthMoves({ history, today }) {
11010
10775
  const moves = healthMoves(history, today);
11011
10776
  if (!moves.length) return null;
11012
- return /* @__PURE__ */ jsxs(Fragment, { children: [
10777
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
11013
10778
  /* @__PURE__ */ jsx(Text, { children: " " }),
11014
10779
  /* @__PURE__ */ jsxs(Text, {
11015
10780
  color: theme.muted,
@@ -11612,7 +11377,7 @@ function MilestonePanel({ id, width, height, go, active, onClose }) {
11612
11377
  }, "Delete")
11613
11378
  },
11614
11379
  belowRows: risks.length ? risks.length + 1 : 0,
11615
- 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, {
11616
11381
  color: theme.bad,
11617
11382
  wrap: "truncate-end",
11618
11383
  children: [
@@ -11841,7 +11606,7 @@ function RaidPanel({ id, width, height, go, active, onClose }) {
11841
11606
  width,
11842
11607
  height,
11843
11608
  hints: "c add an update · d delete",
11844
- below: updates.length ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Text, {
11609
+ below: updates.length ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Text, {
11845
11610
  color: theme.muted,
11846
11611
  children: ["Updates", earlier ? ` · the last ${updates.length} of ${item.updates.length}` : ""]
11847
11612
  }), updates.map((u) => /* @__PURE__ */ jsxs(Text, {
@@ -11936,7 +11701,7 @@ function PersonPanel({ id, width, height, go, active, onClose }) {
11936
11701
  if (!Number.isFinite(n) || n < 0 || n > 100) return go.notify("A percent from 0 to 100.");
11937
11702
  store.getState().setAllocation(id, programId, n || null);
11938
11703
  })) },
11939
- below: allocations.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
11704
+ below: allocations.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
11940
11705
  /* @__PURE__ */ jsx(Text, { children: " " }),
11941
11706
  /* @__PURE__ */ jsxs(Text, {
11942
11707
  color: theme.muted,
@@ -11960,8 +11725,7 @@ function PersonPanel({ id, width, height, go, active, onClose }) {
11960
11725
  });
11961
11726
  }
11962
11727
 
11963
- //#endregion
11964
- //#region src/tui/views/lists.tsx
11728
+ // src/tui/views/lists.tsx
11965
11729
  init_indexes();
11966
11730
  init_load();
11967
11731
  init_raid();
@@ -12005,7 +11769,7 @@ function RowList({ title, right, rows, empty, active, width, height, onOpen, key
12005
11769
  children: [
12006
11770
  on ? "› " : " ",
12007
11771
  " ".repeat(r.depth),
12008
- 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,
12009
11773
  r.title,
12010
11774
  r.detail ? /* @__PURE__ */ jsxs(Text, {
12011
11775
  color: theme.muted,
@@ -12432,8 +12196,7 @@ function PeopleView({ active, width, height, go }) {
12432
12196
  });
12433
12197
  }
12434
12198
 
12435
- //#endregion
12436
- //#region cli/lib/logo.mjs
12199
+ // cli/lib/logo.mjs
12437
12200
  /**
12438
12201
  * Harbor's mark for the terminal: the favicon (public/favicon.svg) as
12439
12202
  * pixels, a teal tile with the white H and three coral boats. Each
@@ -12548,8 +12311,7 @@ function logoRows(pixels = LOGO) {
12548
12311
  return rows;
12549
12312
  }
12550
12313
 
12551
- //#endregion
12552
- //#region src/tui/logo.tsx
12314
+ // src/tui/logo.tsx
12553
12315
  /** Harbor's mark in half blocks (cli/lib/logo.mjs holds the pixels). */
12554
12316
  function Logo({ pixels = LOGO }) {
12555
12317
  return /* @__PURE__ */ jsx(Box, {
@@ -12591,8 +12353,7 @@ function Splash({ opening }) {
12591
12353
  });
12592
12354
  }
12593
12355
 
12594
- //#endregion
12595
- //#region src/tui/views/overlays.tsx
12356
+ // src/tui/views/overlays.tsx
12596
12357
  init_search();
12597
12358
  /** Find a task by key or words; Enter opens it. */
12598
12359
  function SearchBox({ width, onOpen, onClose }) {
@@ -12688,7 +12449,7 @@ function NewTask({ projectId, status, width, onDone, onFull }) {
12688
12449
  const { store } = useDeps();
12689
12450
  const projects = useHarbor((s) => s.projects);
12690
12451
  const me = useHarbor((s) => s.currentUserId);
12691
- const [project, setProject] = useState(projectId);
12452
+ const [project, setProject] = useState(() => projectId ?? soleOpenProject(projects));
12692
12453
  const chosen = projects.find((p) => p.id === project);
12693
12454
  if (!chosen) return /* @__PURE__ */ jsx(Box, {
12694
12455
  width,
@@ -12817,8 +12578,7 @@ function Help({ width, onClose }) {
12817
12578
  });
12818
12579
  }
12819
12580
 
12820
- //#endregion
12821
- //#region src/tui/views/palette.tsx
12581
+ // src/tui/views/palette.tsx
12822
12582
  /**
12823
12583
  * `:` — everything in one list: screens, making things, every project and
12824
12584
  * program by name, other harbors. Type to narrow, Enter to run.
@@ -12924,8 +12684,7 @@ function Palette({ width, base, open, onClose }) {
12924
12684
  });
12925
12685
  }
12926
12686
 
12927
- //#endregion
12928
- //#region src/tui/views/premortem.tsx
12687
+ // src/tui/views/premortem.tsx
12929
12688
  /**
12930
12689
  * A project's pre-mortem in the terminal, as the website's card runs it:
12931
12690
  * start one, answer alone while the clock runs, then turn each answer into
@@ -13023,7 +12782,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13023
12782
  });
13024
12783
  if (pm.phase === "none") {
13025
12784
  const ends = project.endDate ? `after ${shortDay(project.endDate, today())}` : "three months from now";
13026
- return frame(/* @__PURE__ */ jsxs(Fragment, { children: [
12785
+ return frame(/* @__PURE__ */ jsxs(Fragment$1, { children: [
13027
12786
  /* @__PURE__ */ jsxs(Text, {
13028
12787
  wrap: "wrap",
13029
12788
  children: [
@@ -13058,7 +12817,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13058
12817
  viewOnly ? null : "a another answer",
13059
12818
  "Esc close"
13060
12819
  ];
13061
- return frame(/* @__PURE__ */ jsxs(Fragment, { children: [
12820
+ return frame(/* @__PURE__ */ jsxs(Fragment$1, { children: [
13062
12821
  /* @__PURE__ */ jsx(Text, {
13063
12822
  bold: true,
13064
12823
  wrap: "truncate-end",
@@ -13102,7 +12861,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13102
12861
  ]
13103
12862
  }, r.answer.id);
13104
12863
  }),
13105
- 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, {
13106
12865
  height: fullRows,
13107
12866
  overflow: "hidden",
13108
12867
  children: /* @__PURE__ */ jsx(Text, {
@@ -13113,8 +12872,7 @@ function PremortemPanel({ id, width, height, go, active, onClose }) {
13113
12872
  ] }), hints.filter(Boolean).join(" · "));
13114
12873
  }
13115
12874
 
13116
- //#endregion
13117
- //#region src/lib/command-line.ts
12875
+ // src/lib/command-line.ts
13118
12876
  init_date_fns();
13119
12877
  init_format();
13120
12878
  const PAGES = {
@@ -13169,8 +12927,7 @@ function dueFrom(value, now) {
13169
12927
  throw new CommandError(`Can't read the date "${value}". Try today, fri, +3 or 2026-11-02.`);
13170
12928
  }
13171
12929
 
13172
- //#endregion
13173
- //#region src/lib/dry-dock.ts
12930
+ // src/lib/dry-dock.ts
13174
12931
  init_date_fns();
13175
12932
  init_format();
13176
12933
  init_indexes();
@@ -13541,8 +13298,7 @@ function applyDock(actions, projectId, changes) {
13541
13298
  return made;
13542
13299
  }
13543
13300
 
13544
- //#endregion
13545
- //#region node_modules/zod/v4/core/util.js
13301
+ // node_modules/zod/v4/core/util.js
13546
13302
  function getEnumValues(entries) {
13547
13303
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
13548
13304
  return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -13952,6 +13708,7 @@ function hide(inst, key, value) {
13952
13708
  return own(inst, key, value, false);
13953
13709
  }
13954
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__ */
13955
13712
  function derived(computes, table) {
13956
13713
  for (const key in computes) {
13957
13714
  const compute = computes[key];
@@ -14076,8 +13833,7 @@ function constantCatch(value) {
14076
13833
  return fn;
14077
13834
  }
14078
13835
 
14079
- //#endregion
14080
- //#region node_modules/zod/v4/core/core.js
13836
+ // node_modules/zod/v4/core/core.js
14081
13837
  var _a$1;
14082
13838
  const _zodDesc = {
14083
13839
  value: void 0,
@@ -14104,6 +13860,7 @@ function newError(Definition) {
14104
13860
  }
14105
13861
  return new Definition();
14106
13862
  }
13863
+ /* @__NO_SIDE_EFFECTS__ */
14107
13864
  function $constructor(name, initializer, proto, params) {
14108
13865
  const zodProto = {};
14109
13866
  function Internals(def) {
@@ -14183,8 +13940,7 @@ function config(newConfig) {
14183
13940
  return globalConfig;
14184
13941
  }
14185
13942
 
14186
- //#endregion
14187
- //#region node_modules/zod/v4/core/errors.js
13943
+ // node_modules/zod/v4/core/errors.js
14188
13944
  function _getMessage() {
14189
13945
  const internals = this._zod;
14190
13946
  internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
@@ -14235,8 +13991,7 @@ const initializer$1 = (inst, def) => {
14235
13991
  });
14236
13992
  }
14237
13993
  };
14238
- const $ZodError = $constructor("$ZodError", initializer$1);
14239
- const $ZodRealError = $constructor("$ZodError", initializer$1, void 0, { Parent: Error });
13994
+ const $ZodError = /* @__PURE__ */ $constructor("$ZodError", initializer$1);
14240
13995
  /** Get-or-create `obj[key]` as an own data property. A path segment naming an inherited member
14241
13996
  * ("toString", "constructor") would otherwise read through to the prototype, and assigning
14242
13997
  * "__proto__" would hit the setter instead of creating a key. */
@@ -14300,8 +14055,7 @@ function formatError(error, mapper = (issue) => issue.message) {
14300
14055
  return fieldErrors;
14301
14056
  }
14302
14057
 
14303
- //#endregion
14304
- //#region node_modules/zod/v4/core/parse.js
14058
+ // node_modules/zod/v4/core/parse.js
14305
14059
  function finalizeParams(callee, params) {
14306
14060
  return {
14307
14061
  callee: params?.callee ?? callee,
@@ -14504,8 +14258,7 @@ const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
14504
14258
  return _safeParseAsync(_Err)(schema, value, _ctx);
14505
14259
  };
14506
14260
 
14507
- //#endregion
14508
- //#region node_modules/zod/v4/core/regexes.js
14261
+ // node_modules/zod/v4/core/regexes.js
14509
14262
  /**
14510
14263
  * @deprecated CUID v1 is deprecated by its authors due to information leakage
14511
14264
  * (timestamps embedded in the id). Use {@link cuid2} instead.
@@ -14576,8 +14329,7 @@ const boolean$1 = /^(?:true|false)$/i;
14576
14329
  const lowercase = /^[^A-Z]*$/;
14577
14330
  const uppercase = /^[^a-z]*$/;
14578
14331
 
14579
- //#endregion
14580
- //#region node_modules/zod/v4/core/checks.js
14332
+ // node_modules/zod/v4/core/checks.js
14581
14333
  const $ZodCheck = /*@__PURE__*/ $constructor("$ZodCheck", (inst, def) => {
14582
14334
  var _a;
14583
14335
  inst._zod ?? (inst._zod = {});
@@ -14873,8 +14625,7 @@ const $ZodCheckOverwrite = /*@__PURE__*/ $constructor("$ZodCheckOverwrite", (ins
14873
14625
  };
14874
14626
  });
14875
14627
 
14876
- //#endregion
14877
- //#region node_modules/zod/v4/core/doc.js
14628
+ // node_modules/zod/v4/core/doc.js
14878
14629
  var Doc = class {
14879
14630
  constructor(args = [], closed = {}) {
14880
14631
  this.content = [];
@@ -14908,16 +14659,14 @@ var Doc = class {
14908
14659
  }
14909
14660
  };
14910
14661
 
14911
- //#endregion
14912
- //#region node_modules/zod/v4/core/versions.js
14662
+ // node_modules/zod/v4/core/versions.js
14913
14663
  const version = {
14914
14664
  major: 4,
14915
14665
  minor: 6,
14916
14666
  patch: 7
14917
14667
  };
14918
14668
 
14919
- //#endregion
14920
- //#region node_modules/zod/v4/core/schemas.js
14669
+ // node_modules/zod/v4/core/schemas.js
14921
14670
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
14922
14671
  var _a;
14923
14672
  inst ?? (inst = {});
@@ -16161,8 +15910,7 @@ function handleRefineResult(result, payload, input, inst) {
16161
15910
  }
16162
15911
  }
16163
15912
 
16164
- //#endregion
16165
- //#region node_modules/zod/v4/core/memoizer.js
15913
+ // node_modules/zod/v4/core/memoizer.js
16166
15914
  var $ZodCyclicError = class extends Error {
16167
15915
  constructor() {
16168
15916
  super(`Cannot parse a reference cycle that closes through a transform`);
@@ -16415,8 +16163,7 @@ function isBackEdge(ctx, value) {
16415
16163
  return backEdges !== void 0 && isRef(value) && backEdges.has(value);
16416
16164
  }
16417
16165
 
16418
- //#endregion
16419
- //#region node_modules/zod/v4/locales/en.js
16166
+ // node_modules/zod/v4/locales/en.js
16420
16167
  const error = () => {
16421
16168
  const Sizable = {
16422
16169
  string: {
@@ -16524,8 +16271,7 @@ function en_default() {
16524
16271
  return { localeError: error() };
16525
16272
  }
16526
16273
 
16527
- //#endregion
16528
- //#region node_modules/zod/v4/core/registries.js
16274
+ // node_modules/zod/v4/core/registries.js
16529
16275
  var _a;
16530
16276
  var $ZodRegistry = class {
16531
16277
  constructor() {
@@ -16572,8 +16318,7 @@ function registry() {
16572
16318
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
16573
16319
  const globalRegistry = globalThis.__zod_globalRegistry;
16574
16320
 
16575
- //#endregion
16576
- //#region node_modules/zod/v4/core/api.js
16321
+ // node_modules/zod/v4/core/api.js
16577
16322
  function snapshotChecks(def) {
16578
16323
  if (def.checks) def.checks = [...def.checks];
16579
16324
  return def;
@@ -17082,8 +16827,7 @@ function _check(fn, params) {
17082
16827
  return ch;
17083
16828
  }
17084
16829
 
17085
- //#endregion
17086
- //#region node_modules/zod/v4/core/to-json-schema.js
16830
+ // node_modules/zod/v4/core/to-json-schema.js
17087
16831
  function assignProps(target, ...sources) {
17088
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]);
17089
16833
  return target;
@@ -17528,8 +17272,7 @@ const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params)
17528
17272
  return finalize(ctx, schema);
17529
17273
  };
17530
17274
 
17531
- //#endregion
17532
- //#region node_modules/zod/v4/core/json-schema-processors.js
17275
+ // node_modules/zod/v4/core/json-schema-processors.js
17533
17276
  const narrowMin = (agg, key, value) => {
17534
17277
  if (agg[key] === void 0 || value > agg[key]) agg[key] = value;
17535
17278
  };
@@ -17851,8 +17594,7 @@ const optionalProcessor = (schema, ctx, _json, params) => {
17851
17594
  seen.ref = def.innerType;
17852
17595
  };
17853
17596
 
17854
- //#endregion
17855
- //#region node_modules/zod/v4/classic/errors.js
17597
+ // node_modules/zod/v4/classic/errors.js
17856
17598
  const _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
17857
17599
  function _lazyMethod(proto, key, make) {
17858
17600
  Object.defineProperty(proto, key, {
@@ -17902,8 +17644,7 @@ const initializer = (inst, issues) => {
17902
17644
  };
17903
17645
  const ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, void 0, { Parent: Error });
17904
17646
 
17905
- //#endregion
17906
- //#region node_modules/zod/v4/classic/parse.js
17647
+ // node_modules/zod/v4/classic/parse.js
17907
17648
  const parse = /* @__PURE__ */ _parse(ZodRealError);
17908
17649
  const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
17909
17650
  const safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -17917,8 +17658,7 @@ const safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
17917
17658
  const safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
17918
17659
  const safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
17919
17660
 
17920
- //#endregion
17921
- //#region node_modules/zod/v4/classic/schemas.js
17661
+ // node_modules/zod/v4/classic/schemas.js
17922
17662
  function _ensureDefaultLocale() {
17923
17663
  if (!globalConfig.localeError) config(en_default());
17924
17664
  }
@@ -18749,8 +18489,7 @@ function superRefine(fn, params) {
18749
18489
  return _superRefine(fn, params);
18750
18490
  }
18751
18491
 
18752
- //#endregion
18753
- //#region src/lib/long-pole.ts
18492
+ // src/lib/long-pole.ts
18754
18493
  init_date_fns();
18755
18494
  init_blockers();
18756
18495
  init_format();
@@ -18964,8 +18703,7 @@ function undatedText(pole) {
18964
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.`;
18965
18704
  }
18966
18705
 
18967
- //#endregion
18968
- //#region src/lib/csv.ts
18706
+ // src/lib/csv.ts
18969
18707
  /**
18970
18708
  * Text a spreadsheet would run as a formula: a title from an intake form
18971
18709
  * could read =HYPERLINK(…). Exports put an apostrophe in front, which
@@ -18984,8 +18722,7 @@ function toCsv(headers, rows) {
18984
18722
  return [headers, ...rows].map((r) => r.map(cell).join(",")).join("\r\n");
18985
18723
  }
18986
18724
 
18987
- //#endregion
18988
- //#region src/lib/exports.ts
18725
+ // src/lib/exports.ts
18989
18726
  /**
18990
18727
  * The spreadsheets Harbor hands out: a project's tasks, the risk register and
18991
18728
  * the review. The website downloads them, agents and the terminal get the
@@ -19100,8 +18837,7 @@ function reviewCsv(data, programs, now) {
19100
18837
  ]));
19101
18838
  }
19102
18839
 
19103
- //#endregion
19104
- //#region src/lib/crew-clocks.ts
18840
+ // src/lib/crew-clocks.ts
19105
18841
  /** Working hours when only a time zone is set. */
19106
18842
  const DEFAULT_HOURS = {
19107
18843
  start: "09:00",
@@ -19230,8 +18966,7 @@ function todayFor(person, at, fallback) {
19230
18966
  return isZone(person?.timeZone) ? wallIn(person.timeZone, at).date : fallback;
19231
18967
  }
19232
18968
 
19233
- //#endregion
19234
- //#region src/lib/pilot.ts
18969
+ // src/lib/pilot.ts
19235
18970
  init_load();
19236
18971
  init_format();
19237
18972
  init_handover();
@@ -19382,8 +19117,7 @@ function pilotReasons(p, you = false) {
19382
19117
  return out;
19383
19118
  }
19384
19119
 
19385
- //#endregion
19386
- //#region src/lib/seen-mark.ts
19120
+ // src/lib/seen-mark.ts
19387
19121
  /** Days without opening Harbor before the catch-up shows. */
19388
19122
  const UNSEEN_DAYS = 3;
19389
19123
  /** Calendar days from one ISO day (or moment) to another, by their dates alone. */
@@ -19419,8 +19153,7 @@ function welcomeWhen(person, lastSeen, today) {
19419
19153
  } : null;
19420
19154
  }
19421
19155
 
19422
- //#endregion
19423
- //#region src/lib/welcome-back.ts
19156
+ // src/lib/welcome-back.ts
19424
19157
  init_date_text();
19425
19158
  init_indexes();
19426
19159
  init_task_keys();
@@ -19545,33 +19278,7 @@ function movedText(m, healthLabel) {
19545
19278
  return `${m.project.name}: ${bits.join(", ")}`;
19546
19279
  }
19547
19280
 
19548
- //#endregion
19549
- //#region src/lib/agents.ts
19550
- const isAgent = (p) => p?.kind === "agent";
19551
- const RANK = {
19552
- urgent: 0,
19553
- high: 1,
19554
- medium: 2,
19555
- low: 3
19556
- };
19557
- /** What an agent should work on: its open tasks not yet waiting on review, in progress first, then most urgent and soonest. */
19558
- function agentQueue(data, agentId) {
19559
- 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"));
19560
- }
19561
- /** The agent an app means: the one named, else the only one on the crew. */
19562
- function pickAgent(people, key) {
19563
- const agents = people.filter(isAgent);
19564
- if (agents.length === 0) return "There are no agents on this harbor's crew yet. Someone adds one on People with Add an agent.";
19565
- if (!key) {
19566
- if (agents.length === 1) return agents[0];
19567
- return `This harbor has ${agents.length} agents (${agents.map((a) => a.name).join(", ")}). Say which with agent.`;
19568
- }
19569
- const k = key.trim().toLowerCase();
19570
- 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(", ")}.`;
19571
- }
19572
-
19573
- //#endregion
19574
- //#region src/lib/fog.ts
19281
+ // src/lib/fog.ts
19575
19282
  function latestBy(cache, items, key, at) {
19576
19283
  const hit = cache.get(items);
19577
19284
  if (hit && hit.size === items.length) return hit.value;
@@ -19660,8 +19367,7 @@ var init_fog = __esmMin((() => {
19660
19367
  fileCache = /* @__PURE__ */ new WeakMap();
19661
19368
  }));
19662
19369
 
19663
- //#endregion
19664
- //#region src/lib/mcp/tools.ts
19370
+ // src/lib/mcp/tools.ts
19665
19371
  init_thanks();
19666
19372
  init_task_keys();
19667
19373
  init_brief();
@@ -19683,7 +19389,9 @@ init_date_text();
19683
19389
  init_date_fns();
19684
19390
  init_shipping_forecast();
19685
19391
  init_handover();
19392
+ init_agents();
19686
19393
  init_work();
19394
+ init_task_people();
19687
19395
  init_fog();
19688
19396
  init_passage();
19689
19397
  init_board();
@@ -19933,10 +19641,27 @@ function taskLine(t, people, projects, all) {
19933
19641
  priority: t.priority,
19934
19642
  due: dayOf(t.dueDate),
19935
19643
  assignee: nameOf$2(people, t.assigneeId),
19644
+ ...alsoOnOf(t, people),
19936
19645
  project: project?.name ?? null,
19937
19646
  ...waitingOn ? { waitingOn } : {}
19938
19647
  };
19939
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
+ }
19940
19665
  /** One person's week plan as the agent tools give it (get_week, plan_week). */
19941
19666
  /** Most of the tasks not on a day that get_week lists; the count says how many there are. */
19942
19667
  const UNPLANNED_MAX = 200;
@@ -20371,7 +20096,7 @@ const HARBOR_TOOLS = [
20371
20096
  tool({
20372
20097
  name: "get_task",
20373
20098
  title: "Task details",
20374
- 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,
20375
20100
  input: object({
20376
20101
  harbor: harborArg,
20377
20102
  task: string().min(1).max(100).describe("Task id or key (\"RR-42\"), from search_tasks or my_work.")
@@ -20410,6 +20135,7 @@ const HARBOR_TOOLS = [
20410
20135
  priority: t.priority,
20411
20136
  due: dayOf(t.dueDate),
20412
20137
  assignee: nameOf$2(people, t.assigneeId),
20138
+ ...alsoOnOf(t, people),
20413
20139
  project: project?.name ?? null,
20414
20140
  projectId: t.projectId,
20415
20141
  created: dayOf(t.createdAt),
@@ -20428,15 +20154,54 @@ const HARBOR_TOOLS = [
20428
20154
  says: pilotHeadline(pilot, t.dueDate, you),
20429
20155
  why: pilotReasons(pilot, you)
20430
20156
  } } : {},
20157
+ files: (data.attachments ?? []).filter((a) => a.taskId === t.id).map((a) => fileOut(a, people)),
20431
20158
  comments,
20432
20159
  ...webLink(ctx, { task: t.id })
20433
20160
  };
20434
20161
  }
20435
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
+ }),
20436
20201
  tool({
20437
20202
  name: "my_work",
20438
20203
  title: "My work",
20439
- 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,
20440
20205
  input: object({
20441
20206
  harbor: harborArg,
20442
20207
  limit: limitArg(50, 25)
@@ -20475,6 +20240,7 @@ const HARBOR_TOOLS = [
20475
20240
  openTasks: open.length,
20476
20241
  late: open.filter((t) => overdue(t, today)).length,
20477
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)),
20478
20244
  waitingOnYou: waitingOnYou.slice(0, 20),
20479
20245
  raid,
20480
20246
  soundingsToAnswer: soundingsWaitingOn(data, mine.id, ctx.now).map((t) => ({
@@ -21388,8 +21154,7 @@ const LIST_HARBORS = {
21388
21154
  input: object({})
21389
21155
  };
21390
21156
 
21391
- //#endregion
21392
- //#region src/lib/payload.ts
21157
+ // src/lib/payload.ts
21393
21158
  /**
21394
21159
  * The document fields of a store state, by reference, with stable empties for
21395
21160
  * anything missing. Cheap enough to run on every render; feeds `useHarborData`.
@@ -21439,8 +21204,7 @@ var init_payload = __esmMin((() => {
21439
21204
  NO_CONFIGS = {};
21440
21205
  }));
21441
21206
 
21442
- //#endregion
21443
- //#region src/lib/view-only.ts
21207
+ // src/lib/view-only.ts
21444
21208
  function isDocumentKey(key, state) {
21445
21209
  documentKeys ??= new Set(Object.keys(pickData(state)));
21446
21210
  return documentKeys.has(key);
@@ -21479,8 +21243,7 @@ var init_view_only = __esmMin((() => {
21479
21243
  documentKeys = null;
21480
21244
  }));
21481
21245
 
21482
- //#endregion
21483
- //#region cli/lib/errors.mjs
21246
+ // cli/lib/errors.mjs
21484
21247
  var HarborError;
21485
21248
  var init_errors = __esmMin((() => {
21486
21249
  HarborError = class extends Error {
@@ -21488,8 +21251,7 @@ var init_errors = __esmMin((() => {
21488
21251
  };
21489
21252
  }));
21490
21253
 
21491
- //#endregion
21492
- //#region src/lib/empty.ts
21254
+ // src/lib/empty.ts
21493
21255
  function addMonths(iso, months) {
21494
21256
  const [y, m, d] = iso.split("-").map(Number);
21495
21257
  const dt = new Date(y, (m ?? 1) - 1, d ?? 1);
@@ -21572,8 +21334,7 @@ var init_empty = __esmMin((() => {
21572
21334
  STARTER_PROGRAM = "The work";
21573
21335
  }));
21574
21336
 
21575
- //#endregion
21576
- //#region src/lib/deep-equal.ts
21337
+ // src/lib/deep-equal.ts
21577
21338
  /**
21578
21339
  * Structural equality, key-order independent, treating `undefined` and a
21579
21340
  * missing key as the same as `null` (matches how optional fields like
@@ -21597,8 +21358,7 @@ function deepEqual(a, b) {
21597
21358
  }
21598
21359
  var init_deep_equal = __esmMin((() => {}));
21599
21360
 
21600
- //#endregion
21601
- //#region src/lib/row-changes.ts
21361
+ // src/lib/row-changes.ts
21602
21362
  /**
21603
21363
  * The changes that turn `before` into `after`. Rows the store left alone
21604
21364
  * keep their object, so most of the work is an identity check.
@@ -21734,8 +21494,7 @@ var init_row_changes = __esmMin((() => {
21734
21494
  LATEST_WINS = /* @__PURE__ */ new Set(["touchedAt"]);
21735
21495
  }));
21736
21496
 
21737
- //#endregion
21738
- //#region src/lib/undo.ts
21497
+ // src/lib/undo.ts
21739
21498
  function nameOf$1(row) {
21740
21499
  const text = row?.title ?? row?.name;
21741
21500
  return text ? `“${text.length > 40 ? `${text.slice(0, 39)}…` : text}”` : null;
@@ -21849,8 +21608,7 @@ var init_undo = __esmMin((() => {
21849
21608
  ];
21850
21609
  }));
21851
21610
 
21852
- //#endregion
21853
- //#region src/lib/demo-seed.ts
21611
+ // src/lib/demo-seed.ts
21854
21612
  /** Whether createSeedNow can answer without waiting. */
21855
21613
  function seedReady() {
21856
21614
  return create !== null;
@@ -21879,15 +21637,13 @@ var init_demo_seed = __esmMin((() => {
21879
21637
  anchor = null;
21880
21638
  }));
21881
21639
 
21882
- //#endregion
21883
- //#region src/lib/utils.ts
21640
+ // src/lib/utils.ts
21884
21641
  function uid(prefix = "id") {
21885
21642
  return `${prefix}-${Math.random().toString(36).slice(2, 9)}`;
21886
21643
  }
21887
21644
  var init_utils = __esmMin((() => {}));
21888
21645
 
21889
- //#endregion
21890
- //#region src/lib/slices/shared.ts
21646
+ // src/lib/slices/shared.ts
21891
21647
  function stamp() {
21892
21648
  return (/* @__PURE__ */ new Date()).toISOString();
21893
21649
  }
@@ -21907,8 +21663,7 @@ function withStatus(task, status) {
21907
21663
  }
21908
21664
  var init_shared = __esmMin((() => {}));
21909
21665
 
21910
- //#endregion
21911
- //#region src/lib/undo-state.ts
21666
+ // src/lib/undo-state.ts
21912
21667
  function clearUndo() {
21913
21668
  useUndo.setState({
21914
21669
  step: null,
@@ -21924,8 +21679,7 @@ var init_undo_state = __esmMin((() => {
21924
21679
  }));
21925
21680
  }));
21926
21681
 
21927
- //#endregion
21928
- //#region src/lib/slices/session.ts
21682
+ // src/lib/slices/session.ts
21929
21683
  function sessionSlice({ set, get, write }) {
21930
21684
  return {
21931
21685
  setHydrated: (v) => set({ hydrated: v }),
@@ -22076,8 +21830,7 @@ var init_session = __esmMin((() => {
22076
21830
  init_format();
22077
21831
  }));
22078
21832
 
22079
- //#endregion
22080
- //#region src/lib/first-week.ts
21833
+ // src/lib/first-week.ts
22081
21834
  /** The program launch named for you, when nobody has renamed it yet. */
22082
21835
  function starterProgram(data) {
22083
21836
  return data.programs.find((p) => p.name.trim() === "The work") ?? null;
@@ -22086,8 +21839,7 @@ var init_first_week = __esmMin((() => {
22086
21839
  init_empty();
22087
21840
  }));
22088
21841
 
22089
- //#endregion
22090
- //#region src/lib/slices/hierarchy.ts
21842
+ // src/lib/slices/hierarchy.ts
22091
21843
  function hierarchySlice({ get, write }) {
22092
21844
  return {
22093
21845
  addPortfolio: (p) => {
@@ -22524,8 +22276,7 @@ var init_hierarchy = __esmMin((() => {
22524
22276
  init_first_week();
22525
22277
  }));
22526
22278
 
22527
- //#endregion
22528
- //#region src/lib/github-refs.ts
22279
+ // src/lib/github-refs.ts
22529
22280
  /** The task's list with this pull request or commit added, or updated in place, newest first. */
22530
22281
  function withRef(list, ref) {
22531
22282
  const same = (r) => r.kind === ref.kind && r.repo === ref.repo && r.ref === ref.ref;
@@ -22536,8 +22287,7 @@ var init_github_refs = __esmMin((() => {
22536
22287
  REFS_KEPT = 20;
22537
22288
  }));
22538
22289
 
22539
- //#endregion
22540
- //#region src/lib/automations.ts
22290
+ // src/lib/automations.ts
22541
22291
  /**
22542
22292
  * Checked once, against the (before, after) pair of a single user-driven
22543
22293
  * mutation — never re-checked against an automation's own effect. That's the
@@ -22609,8 +22359,7 @@ function applyAutomations(project, prev, next, opts) {
22609
22359
  }
22610
22360
  var init_automations = __esmMin((() => {}));
22611
22361
 
22612
- //#endregion
22613
- //#region src/lib/focus.ts
22362
+ // src/lib/focus.ts
22614
22363
  function focusIdsOf(data, personId, date = todayISO()) {
22615
22364
  return (data.ropes ?? []).find((r) => r.personId === personId && r.date === date)?.taskIds ?? [];
22616
22365
  }
@@ -22633,8 +22382,7 @@ var init_focus = __esmMin((() => {
22633
22382
  CHECK_IN_QUESTION = "On the blocker, or on something else?";
22634
22383
  }));
22635
22384
 
22636
- //#endregion
22637
- //#region src/lib/recurrence.ts
22385
+ // src/lib/recurrence.ts
22638
22386
  /** The due date one interval after `from`. */
22639
22387
  function nextDueDate(from, repeat) {
22640
22388
  const d = /* @__PURE__ */ new Date(`${from}T12:00:00`);
@@ -22679,8 +22427,7 @@ var init_recurrence = __esmMin((() => {
22679
22427
  };
22680
22428
  }));
22681
22429
 
22682
- //#endregion
22683
- //#region src/lib/assignment.ts
22430
+ // src/lib/assignment.ts
22684
22431
  /**
22685
22432
  * Record who set a task's assignee and when. Only a change of assignee
22686
22433
  * stamps; clearing the assignee clears the stamp.
@@ -22700,8 +22447,7 @@ function stampAssignment(before, next, by, at) {
22700
22447
  }
22701
22448
  var init_assignment = __esmMin((() => {}));
22702
22449
 
22703
- //#endregion
22704
- //#region src/lib/bulk.ts
22450
+ // src/lib/bulk.ts
22705
22451
  /** A task's due date moved by `days`, or null when it has none. */
22706
22452
  function shiftedDue(due, days) {
22707
22453
  if (!due) return null;
@@ -22755,8 +22501,7 @@ var init_bulk = __esmMin((() => {
22755
22501
  plural$2 = (n) => `${n} ${n === 1 ? "task" : "tasks"}`;
22756
22502
  }));
22757
22503
 
22758
- //#endregion
22759
- //#region src/lib/slices/tasks.ts
22504
+ // src/lib/slices/tasks.ts
22760
22505
  function tasksSlice({ set, get, write }) {
22761
22506
  return {
22762
22507
  followWork: (personId, taskIds, raidIds = []) => {
@@ -22838,6 +22583,7 @@ function tasksSlice({ set, get, write }) {
22838
22583
  ...patch,
22839
22584
  touchedAt: stamp()
22840
22585
  };
22586
+ if (next.assigneeId && next.followerIds?.includes(next.assigneeId)) next.followerIds = alsoOnIds(next);
22841
22587
  if (patch.status && patch.status !== row.status) {
22842
22588
  if (patch.status === "done" && !patch.completedAt) next.completedAt = stamp();
22843
22589
  else if (row.status === "done" && patch.status !== "done") next.completedAt = null;
@@ -23244,10 +22990,10 @@ var init_tasks = __esmMin((() => {
23244
22990
  init_recurrence();
23245
22991
  init_assignment();
23246
22992
  init_bulk();
22993
+ init_task_people();
23247
22994
  }));
23248
22995
 
23249
- //#endregion
23250
- //#region src/lib/raid-history.ts
22996
+ // src/lib/raid-history.ts
23251
22997
  /**
23252
22998
  * The score history after applying `patch`: a new entry when the rating
23253
22999
  * moved, the same array otherwise. The first change also records where the
@@ -23269,8 +23015,7 @@ function recordScoreChange(item, patch, at) {
23269
23015
  }
23270
23016
  var init_raid_history = __esmMin((() => {}));
23271
23017
 
23272
- //#endregion
23273
- //#region src/lib/slices/milestones-raid.ts
23018
+ // src/lib/slices/milestones-raid.ts
23274
23019
  function milestonesRaidSlice({ set, get, write }) {
23275
23020
  return {
23276
23021
  toggleMilestone: (id) => {
@@ -23653,8 +23398,7 @@ var init_milestones_raid = __esmMin((() => {
23653
23398
  init_shared();
23654
23399
  }));
23655
23400
 
23656
- //#endregion
23657
- //#region src/lib/allocation.ts
23401
+ // src/lib/allocation.ts
23658
23402
  /** Allocations with `programId` set to `percent`; 0 or null removes the line. */
23659
23403
  function withAllocation(allocations, programId, percent) {
23660
23404
  const rest = (allocations ?? []).filter((a) => a.programId !== programId);
@@ -23666,8 +23410,7 @@ function withAllocation(allocations, programId, percent) {
23666
23410
  }
23667
23411
  var init_allocation = __esmMin((() => {}));
23668
23412
 
23669
- //#endregion
23670
- //#region src/lib/slices/people-spend.ts
23413
+ // src/lib/slices/people-spend.ts
23671
23414
  function peopleSpendSlice({ set, get, write }) {
23672
23415
  return {
23673
23416
  setAllocation: (personId, programId, percent) => {
@@ -23951,8 +23694,7 @@ var init_people_spend = __esmMin((() => {
23951
23694
  init_allocation();
23952
23695
  }));
23953
23696
 
23954
- //#endregion
23955
- //#region src/tui/engine/store.ts
23697
+ // src/tui/engine/store.ts
23956
23698
  /** An empty harbor: what the store holds before one loads. */
23957
23699
  function blank() {
23958
23700
  return pickData({ currentUserId: "" });
@@ -24056,8 +23798,7 @@ var init_store = __esmMin((() => {
24056
23798
  PAUSED_NOTICE = "This harbor's free trial has ended, so that wasn't changed. Its owner can subscribe at harborppm.com/keep.";
24057
23799
  }));
24058
23800
 
24059
- //#endregion
24060
- //#region src/lib/changes.ts
23801
+ // src/lib/changes.ts
24061
23802
  /** Keys whose value differs between the last saved document and the current one. */
24062
23803
  function changedCollections(base, current) {
24063
23804
  return COLLECTIONS.filter((key) => !deepEqual(base[key], current[key]));
@@ -24226,8 +23967,7 @@ var init_changes = __esmMin((() => {
24226
23967
  isRowKey = (key) => ROW_COLLECTIONS.includes(key);
24227
23968
  }));
24228
23969
 
24229
- //#endregion
24230
- //#region src/lib/clash-copy.ts
23970
+ // src/lib/clash-copy.ts
24231
23971
  /** A field's value as a person would read it. Long or structured values aren't spelled out. */
24232
23972
  function clashValue(field, value, people, collection = "tasks") {
24233
23973
  if (field === "done") return value ? "done" : "not done";
@@ -24331,8 +24071,7 @@ var init_clash_copy = __esmMin((() => {
24331
24071
  };
24332
24072
  }));
24333
24073
 
24334
- //#endregion
24335
- //#region src/lib/catch-up.ts
24074
+ // src/lib/catch-up.ts
24336
24075
  /**
24337
24076
  * The collections that differ in the server's newer document, or null when
24338
24077
  * none do; `currentUserId` stays this tab's own. An item that didn't change
@@ -24365,8 +24104,7 @@ var init_catch_up = __esmMin((() => {
24365
24104
  hasId = (v) => typeof v === "object" && v !== null && typeof v.id === "string";
24366
24105
  }));
24367
24106
 
24368
- //#endregion
24369
- //#region src/lib/live-changes.ts
24107
+ // src/lib/live-changes.ts
24370
24108
  /** What turned `before` into `after`, for the change log. */
24371
24109
  function changeRecord(before, after) {
24372
24110
  const rows = emptyRows();
@@ -24408,16 +24146,14 @@ var init_live_changes = __esmMin((() => {
24408
24146
  NOT_WHOLE = [...ROW_COLLECTIONS, "currentUserId"];
24409
24147
  }));
24410
24148
 
24411
- //#endregion
24412
- //#region src/lib/roles.ts
24149
+ // src/lib/roles.ts
24413
24150
  /** Anything stored that is not a known role reads as a member, as before roles existed. */
24414
24151
  function normalizeRole(raw) {
24415
24152
  return raw === "owner" || raw === "viewer" ? raw : "member";
24416
24153
  }
24417
24154
  var init_roles = __esmMin((() => {}));
24418
24155
 
24419
- //#endregion
24420
- //#region src/lib/sync-state.ts
24156
+ // src/lib/sync-state.ts
24421
24157
  /** Wait before the nth retry (0-based): 2 s, 4 s, 8 s, 16 s, then every 30 s. */
24422
24158
  function retryDelay(attempt) {
24423
24159
  return Math.min(3e4, 2e3 * 2 ** Math.max(0, attempt));
@@ -24431,8 +24167,7 @@ var init_sync_state = __esmMin((() => {
24431
24167
  }));
24432
24168
  }));
24433
24169
 
24434
- //#endregion
24435
- //#region cli/lib/plain.mjs
24170
+ // cli/lib/plain.mjs
24436
24171
  /** @param {string} text */
24437
24172
  function plain(text) {
24438
24173
  return text.replace(UNSAFE, "");
@@ -24460,8 +24195,7 @@ var init_plain = __esmMin((() => {
24460
24195
  UNSAFE = /[\u0000-\u0008\u000b-\u001f\u007f-\u009f‪-‮⁦-⁩]/g;
24461
24196
  }));
24462
24197
 
24463
- //#endregion
24464
- //#region src/tui/engine/transport.ts
24198
+ // src/tui/engine/transport.ts
24465
24199
  /**
24466
24200
  * The same transport with every answer made plain (cli/lib/plain.mjs):
24467
24201
  * titles, names and notes can come from intake forms, GitHub or anyone in
@@ -24569,8 +24303,7 @@ var init_transport = __esmMin((() => {
24569
24303
  };
24570
24304
  }));
24571
24305
 
24572
- //#endregion
24573
- //#region src/tui/engine/sync.ts
24306
+ // src/tui/engine/sync.ts
24574
24307
  function createSync(opts) {
24575
24308
  const { store, transport } = opts;
24576
24309
  const delay = opts.saveDelayMs ?? 600;
@@ -24789,8 +24522,7 @@ var init_sync = __esmMin((() => {
24789
24522
  init_transport();
24790
24523
  }));
24791
24524
 
24792
- //#endregion
24793
- //#region src/tui/engine/memory-crew.ts
24525
+ // src/tui/engine/memory-crew.ts
24794
24526
  function memoryCrew(account, harbor) {
24795
24527
  let n = 0;
24796
24528
  const token = () => `t${++n}`;
@@ -24967,8 +24699,7 @@ var init_memory_crew = __esmMin((() => {
24967
24699
  ORIGIN = "https://harborppm.com";
24968
24700
  }));
24969
24701
 
24970
- //#endregion
24971
- //#region src/lib/shore.ts
24702
+ // src/lib/shore.ts
24972
24703
  /**
24973
24704
  * Which service an address belongs to, or null when it isn't an incoming
24974
24705
  * webhook Harbor posts to. Only these hosts are allowed, over https, so the
@@ -25027,8 +24758,7 @@ var init_shore = __esmMin((() => {
25027
24758
  ];
25028
24759
  }));
25029
24760
 
25030
- //#endregion
25031
- //#region src/tui/engine/memory.ts
24761
+ // src/tui/engine/memory.ts
25032
24762
  function memoryHarbor(start, opts) {
25033
24763
  const { id, name } = opts.harbor ?? {
25034
24764
  id: "w1",
@@ -25275,8 +25005,7 @@ var init_memory = __esmMin((() => {
25275
25005
  init_transport();
25276
25006
  }));
25277
25007
 
25278
- //#endregion
25279
- //#region src/repo/plan-files.ts
25008
+ // src/repo/plan-files.ts
25280
25009
  /** "RR-42.md" → "RR-42"; a file named anything else is a new task. */
25281
25010
  function keyOfFile(name) {
25282
25011
  return KEY_NAME.exec(name)?.[1] ?? null;
@@ -25558,8 +25287,7 @@ var init_plan_files = __esmMin((() => {
25558
25287
  shown = (v) => Array.isArray(v) ? v.join(", ") || "nothing" : v === null || v === "" ? "nothing" : String(v);
25559
25288
  }));
25560
25289
 
25561
- //#endregion
25562
- //#region src/repo/repo-sync.ts
25290
+ // src/repo/repo-sync.ts
25563
25291
  async function readConfig(folder) {
25564
25292
  const text = await folder.read(CONFIG_FILE);
25565
25293
  if (text === null) return null;
@@ -26077,8 +25805,7 @@ var init_repo_sync = __esmMin((() => {
26077
25805
  };
26078
25806
  }));
26079
25807
 
26080
- //#endregion
26081
- //#region src/tui/try.ts
25808
+ // src/tui/try.ts
26082
25809
  init_format();
26083
25810
  init_task_keys();
26084
25811
  init_tide();
@@ -26272,8 +25999,7 @@ async function saved(sync) {
26272
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.");
26273
26000
  }
26274
26001
 
26275
- //#endregion
26276
- //#region src/tui/views/dock.tsx
26002
+ // src/tui/views/dock.tsx
26277
26003
  /**
26278
26004
  * Dry dock in the full-screen app, as the website's Try a change runs it
26279
26005
  * (src/lib/dry-dock.ts): changes tried on a copy of the project's plan, the
@@ -26554,8 +26280,7 @@ function DockPanel({ id, width, height, go, active, onClose }) {
26554
26280
  });
26555
26281
  }
26556
26282
 
26557
- //#endregion
26558
- //#region src/tui/views/lifeboats.tsx
26283
+ // src/tui/views/lifeboats.tsx
26559
26284
  /**
26560
26285
  * Lifeboats in the full-screen app, as People and the review list them
26561
26286
  * (src/lib/lifeboats.ts): work only one person has touched, each with a
@@ -26719,8 +26444,7 @@ function LifeboatsPanel({ id, width, height, go, active, onClose }) {
26719
26444
  });
26720
26445
  }
26721
26446
 
26722
- //#endregion
26723
- //#region src/tui/views/shore.tsx
26447
+ // src/tui/views/shore.tsx
26724
26448
  /**
26725
26449
  * Ship to shore in the terminal: a program's Slack, Discord or Teams channel
26726
26450
  * and which posts go there, as the website's dialog sets it (shore.ts). The
@@ -26834,7 +26558,7 @@ function ShorePanel({ id, width, height, go, active, onClose }) {
26834
26558
  }) : !hook ? /* @__PURE__ */ jsxs(Text, {
26835
26559
  wrap: "wrap",
26836
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."]
26837
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
26561
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
26838
26562
  /* @__PURE__ */ jsxs(Text, {
26839
26563
  wrap: "truncate-end",
26840
26564
  children: [
@@ -26886,8 +26610,7 @@ function ShorePanel({ id, width, height, go, active, onClose }) {
26886
26610
  });
26887
26611
  }
26888
26612
 
26889
- //#endregion
26890
- //#region src/tui/views/welcome.tsx
26613
+ // src/tui/views/welcome.tsx
26891
26614
  init_swatches();
26892
26615
  const TAG = {
26893
26616
  handed: "Handed to you",
@@ -27009,8 +26732,7 @@ function WelcomeView({ when, active, width, height, go, onDone }) {
27009
26732
  });
27010
26733
  }
27011
26734
 
27012
- //#endregion
27013
- //#region src/tui/views/bands.tsx
26735
+ // src/tui/views/bands.tsx
27014
26736
  /**
27015
26737
  * The website's band layouts in the terminal: a portfolio read program by
27016
26738
  * program, a program read project by project. Each band is a few lines; the
@@ -27290,8 +27012,7 @@ function ProjectBands({ bands, at, active, width, height, w, today }) {
27290
27012
  });
27291
27013
  }
27292
27014
 
27293
- //#endregion
27294
- //#region src/tui/views/program.tsx
27015
+ // src/tui/views/program.tsx
27295
27016
  init_raid();
27296
27017
  init_format();
27297
27018
  init_derived_health();
@@ -27422,7 +27143,7 @@ function ProgramView({ programId, active, width, height, go, onBack }) {
27422
27143
  children: ["Next move: ", program.nextMove || "none written yet (e to write one)"]
27423
27144
  }),
27424
27145
  /* @__PURE__ */ jsx(Text, { children: " " }),
27425
- layout === "bands" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Heading, {
27146
+ layout === "bands" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Heading, {
27426
27147
  right: `${mine.length}${split.done.length > 0 ? ` · ${split.done.length} done ${showDone ? "shown" : "hidden"} (D)` : ""} · v board`,
27427
27148
  children: "By project"
27428
27149
  }), mine.length === 0 ? /* @__PURE__ */ jsx(Text, {
@@ -27749,8 +27470,7 @@ function PortfolioView({ portfolioId, active, width, height, go, onBack }) {
27749
27470
  });
27750
27471
  }
27751
27472
 
27752
- //#endregion
27753
- //#region src/tui/bulk.ts
27473
+ // src/tui/bulk.ts
27754
27474
  init_bulk();
27755
27475
  init_board();
27756
27476
  init_swatches();
@@ -27860,10 +27580,10 @@ function bulkMenu(store, go, ids, today, clear) {
27860
27580
  });
27861
27581
  }
27862
27582
 
27863
- //#endregion
27864
- //#region src/tui/views/project.tsx
27583
+ // src/tui/views/project.tsx
27865
27584
  init_swatches();
27866
27585
  init_format();
27586
+ init_task_people();
27867
27587
  init_hill();
27868
27588
  init_bottle();
27869
27589
  init_clock();
@@ -27908,6 +27628,15 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
27908
27628
  filter
27909
27629
  ]);
27910
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
+ ]);
27911
27640
  const [spendAt, setSpendAt] = useState(0);
27912
27641
  const spendEntries = useHarbor((s) => s.spendEntries) ?? [];
27913
27642
  const [col, setCol] = useState(() => Math.max(0, columns.findIndex((c) => c.tasks.length > 0)));
@@ -27947,9 +27676,16 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
27947
27676
  useInput((input, key) => {
27948
27677
  if (key.escape && picked.length) return setPicked([]);
27949
27678
  if (key.escape || key.backspace) return onBack();
27950
- if (input === " " && selected && mode !== "budget") return setPicked((ids) => ids.includes(selected.id) ? ids.filter((x) => x !== selected.id) : [...ids, selected.id]);
27951
- if (input === "m" && picked.length && mode !== "budget") return bulkMenu(store, go, picked, day, () => setPicked([]));
27952
- 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
+ }
27953
27689
  if (input === "e") return go.openPanel("project", projectId);
27954
27690
  if (input === "b") return go.openPanel("board", projectId);
27955
27691
  if (input === "R") return go.create("raid", { projectId });
@@ -28095,7 +27831,7 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
28095
27831
  lead ? ` · ${lead.name}` : "",
28096
27832
  " · ",
28097
27833
  mode,
28098
- filtered.length && mode !== "budget" ? /* @__PURE__ */ jsxs(Text, {
27834
+ filtered.length && !(mode === "budget" || mode === "files") ? /* @__PURE__ */ jsxs(Text, {
28099
27835
  color: theme.warn,
28100
27836
  children: [
28101
27837
  " · only ",
@@ -28104,7 +27840,7 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
28104
27840
  ]
28105
27841
  }) : null,
28106
27842
  " ",
28107
- picked.length && mode !== "budget" ? /* @__PURE__ */ jsxs(Text, {
27843
+ picked.length && !(mode === "budget" || mode === "files") ? /* @__PURE__ */ jsxs(Text, {
28108
27844
  color: theme.accent,
28109
27845
  children: [
28110
27846
  " ",
@@ -28163,7 +27899,16 @@ function ProjectView({ projectId, active, width, height, go, onBack }) {
28163
27899
  ] })
28164
27900
  ]
28165
27901
  }),
28166
- 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, {
28167
27912
  project,
28168
27913
  spendEntries,
28169
27914
  at: spendAt,
@@ -28417,9 +28162,67 @@ function BudgetPane({ project, spendEntries, at, active, height, today }) {
28417
28162
  ]
28418
28163
  });
28419
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
+ };
28420
28224
 
28421
- //#endregion
28422
- //#region src/tui/views/roadmap.tsx
28225
+ // src/tui/views/roadmap.tsx
28423
28226
  const NAME = 26;
28424
28227
  /**
28425
28228
  * A portfolio's programs and projects across the months, as on the
@@ -28527,8 +28330,7 @@ function RoadmapView({ active, width, height, go }) {
28527
28330
  });
28528
28331
  }
28529
28332
 
28530
- //#endregion
28531
- //#region src/lib/automation-text.ts
28333
+ // src/lib/automation-text.ts
28532
28334
  init_swatches();
28533
28335
  const TRIGGER_LABEL = {
28534
28336
  task_created: "A task is created",
@@ -28580,8 +28382,7 @@ function defaultAction(type) {
28580
28382
  };
28581
28383
  }
28582
28384
 
28583
- //#endregion
28584
- //#region src/lib/custom-field-text.ts
28385
+ // src/lib/custom-field-text.ts
28585
28386
  const FIELD_TYPE_LABEL = {
28586
28387
  text: "Text",
28587
28388
  number: "Number",
@@ -28608,8 +28409,7 @@ function readFieldValue(def, text) {
28608
28409
  return Number.isFinite(n) ? n : void 0;
28609
28410
  }
28610
28411
 
28611
- //#endregion
28612
- //#region src/tui/views/setup.tsx
28412
+ // src/tui/views/setup.tsx
28613
28413
  /**
28614
28414
  * A project's board setup, as the website's board settings have it: where it
28615
28415
  * starts from, each column (name, shown, cap, place), lanes and what cards
@@ -28956,8 +28756,7 @@ function BoardPanel({ id, width, height, go, active, onClose }) {
28956
28756
  });
28957
28757
  }
28958
28758
 
28959
- //#endregion
28960
- //#region src/tui/views/sounding.ts
28759
+ // src/tui/views/sounding.ts
28961
28760
  init_soundings();
28962
28761
  const nameOf = (people, id) => people.find((p) => p.id === id)?.name ?? "someone";
28963
28762
  /** The lines under a task: who's been asked, what's in, and the verdict once shown. */
@@ -29085,13 +28884,13 @@ function days(go, label, initial, then) {
29085
28884
  }, initial == null ? "" : String(initial));
29086
28885
  }
29087
28886
 
29088
- //#endregion
29089
- //#region src/tui/views/task.tsx
28887
+ // src/tui/views/task.tsx
29090
28888
  init_clock();
29091
28889
  init_date_text();
29092
28890
  init_work();
29093
28891
  init_blockers();
29094
28892
  init_recurrence();
28893
+ init_task_people();
29095
28894
  init_search();
29096
28895
  init_swatches();
29097
28896
  const FIELDS = [
@@ -29181,6 +28980,14 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29181
28980
  const item = task.checklist[at - stepsFrom];
29182
28981
  if (item && (input === " " || key.return)) return store.getState().toggleChecklistItem(task.id, item.id);
29183
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
+ }
29184
28991
  if (key.return && FIELDS[at]) return setEditing({
29185
28992
  kind: "field",
29186
28993
  field: FIELDS[at].field
@@ -29215,6 +29022,7 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29215
29022
  title: task.title,
29216
29023
  status: STATUS_LABEL[task.status],
29217
29024
  assignee: owner?.name ?? "Nobody yet",
29025
+ also: alsoOnIds(task).map((id) => people.find((p) => p.id === id)?.name ?? "someone").join(", ") || "Only the owner",
29218
29026
  due: task.dueDate ? `${shortDay(task.dueDate, day)}${isLate(task, day) ? " (late)" : ""}` : "None",
29219
29027
  priority: PRIORITY_LABEL[task.priority],
29220
29028
  project: project ? `${project.name}${project.key ? ` (${project.key})` : ""}` : "",
@@ -29356,6 +29164,25 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29356
29164
  done();
29357
29165
  }
29358
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
+ });
29359
29186
  } else if (f === "repeat") editor = /* @__PURE__ */ jsx(Picker, {
29360
29187
  title: "Repeats (finishing it queues the next one)",
29361
29188
  choices: REPEATS.map((r) => ({
@@ -29419,7 +29246,7 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29419
29246
  ]
29420
29247
  }),
29421
29248
  /* @__PURE__ */ jsx(Text, { children: " " }),
29422
- FIELDS.map((f, i) => /* @__PURE__ */ jsxs(Text, {
29249
+ FIELDS.map((f, i) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Text, {
29423
29250
  wrap: "truncate-end",
29424
29251
  color: at === i ? theme.selected : void 0,
29425
29252
  bold: at === i,
@@ -29431,7 +29258,21 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29431
29258
  }),
29432
29259
  value[f.field]
29433
29260
  ]
29434
- }, 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)),
29435
29276
  own.map((f, n) => {
29436
29277
  const on = at === FIELDS.length + n;
29437
29278
  return /* @__PURE__ */ jsxs(Text, {
@@ -29530,7 +29371,7 @@ function TaskPanel({ taskId, width, height, go, active = true, onClose }) {
29530
29371
  editor ?? /* @__PURE__ */ jsx(Text, {
29531
29372
  color: theme.muted,
29532
29373
  wrap: "truncate-end",
29533
- 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"
29534
29375
  })
29535
29376
  ]
29536
29377
  });
@@ -29666,9 +29507,9 @@ function WaitsEditor({ task, onDone }) {
29666
29507
  });
29667
29508
  }
29668
29509
 
29669
- //#endregion
29670
- //#region src/tui/views/today.tsx
29510
+ // src/tui/views/today.tsx
29671
29511
  init_focus();
29512
+ init_task_people();
29672
29513
  /**
29673
29514
  * What's on you: today's focus and check-in, your open tasks, late first;
29674
29515
  * who waits on you; your risks and issues.
@@ -29700,6 +29541,8 @@ function TodayView({ active, width, height, go }) {
29700
29541
  ]);
29701
29542
  const waits = useMemo(() => waitingOnMe(data, me), [data, me]);
29702
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]);
29703
29546
  const [at, setAt] = useState(0);
29704
29547
  const selected = mine[Math.min(at, mine.length - 1)];
29705
29548
  const late = mine.filter((t) => isLate(t, day)).length;
@@ -29729,7 +29572,7 @@ function TodayView({ active, width, height, go }) {
29729
29572
  });
29730
29573
  }, said?.body);
29731
29574
  }, { isActive: active });
29732
- 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);
29733
29576
  const rows = Math.max(3, height - 2 - extra);
29734
29577
  const view = windowOf(mine, at, rows);
29735
29578
  return /* @__PURE__ */ jsxs(Box, {
@@ -29794,6 +29637,30 @@ function TodayView({ active, width, height, go }) {
29794
29637
  ]
29795
29638
  }, theirs.id + blocker.id))]
29796
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
+ }),
29797
29664
  risks.length > 0 && /* @__PURE__ */ jsxs(Box, {
29798
29665
  flexDirection: "column",
29799
29666
  marginTop: 1,
@@ -29814,8 +29681,7 @@ function TodayView({ active, width, height, go }) {
29814
29681
  });
29815
29682
  }
29816
29683
 
29817
- //#endregion
29818
- //#region src/tui/views/week.tsx
29684
+ // src/tui/views/week.tsx
29819
29685
  init_date_text();
29820
29686
  init_passage();
29821
29687
  const dayName = (date) => format(parseIso(`${date}T12:00:00`), "EEEE");
@@ -29997,8 +29863,7 @@ function WeekView({ active, width, height, go }) {
29997
29863
  });
29998
29864
  }
29999
29865
 
30000
- //#endregion
30001
- //#region src/tui/app.tsx
29866
+ // src/tui/app.tsx
30002
29867
  /**
30003
29868
  * The terminal app's shell: a header (harbor, save state), a sidebar, the
30004
29869
  * screen, and the keys along the bottom. Opening a portfolio, program or
@@ -30680,8 +30545,7 @@ function App({ ui, startIn }) {
30680
30545
  });
30681
30546
  }
30682
30547
 
30683
- //#endregion
30684
- //#region src/tui/theme-detect.ts
30548
+ // src/tui/theme-detect.ts
30685
30549
  const isThemeSetting = (v) => v === "auto" || v === "light" || v === "dark";
30686
30550
  /** COLORFGBG is "fg;bg" (sometimes "fg;x;bg"): background 7 or 15 is a light terminal. */
30687
30551
  function themeFromColorFgBg(value) {
@@ -30727,8 +30591,7 @@ async function pickTheme(setting, env = process.env, ask = () => askBackground(p
30727
30591
  return themeFromColorFgBg(env.COLORFGBG) ?? await ask() ?? "dark";
30728
30592
  }
30729
30593
 
30730
- //#endregion
30731
- //#region src/tui/ui-state.ts
30594
+ // src/tui/ui-state.ts
30732
30595
  init_vanilla();
30733
30596
  function createUiStore() {
30734
30597
  return createStore()(() => ({
@@ -30737,8 +30600,7 @@ function createUiStore() {
30737
30600
  }));
30738
30601
  }
30739
30602
 
30740
- //#endregion
30741
- //#region src/tui/first-run.ts
30603
+ // src/tui/first-run.ts
30742
30604
  init_empty();
30743
30605
  async function firstHarbor(deps) {
30744
30606
  const fallback = suggestedHarborName(deps.account.name, deps.account.email);
@@ -30784,8 +30646,7 @@ async function pickHarbor(deps) {
30784
30646
  }
30785
30647
  }
30786
30648
 
30787
- //#endregion
30788
- //#region src/tui/fog-sweep.ts
30649
+ // src/tui/fog-sweep.ts
30789
30650
  /**
30790
30651
  * `harbor fog --sweep` in a terminal: the tasks nobody has touched for three weeks
30791
30652
  * (lib/fog.ts), one at a time, on the store's own actions. k keeps it
@@ -30874,8 +30735,7 @@ function fogSummary(t) {
30874
30735
  return parts.length ? `${parts.join(", ")}.` : "Nothing changed.";
30875
30736
  }
30876
30737
 
30877
- //#endregion
30878
- //#region src/tui/watch.ts
30738
+ // src/tui/watch.ts
30879
30739
  init_clock();
30880
30740
  init_date_text();
30881
30741
  init_format();
@@ -31052,8 +30912,7 @@ function sinceText(iso, now) {
31052
30912
  return wall.slice(0, 10) === wallClock(now).slice(0, 10) ? time : `${shortDate(wall.slice(0, 10))}, ${time}`;
31053
30913
  }
31054
30914
 
31055
- //#endregion
31056
- //#region src/tui/watch-run.ts
30915
+ // src/tui/watch-run.ts
31057
30916
  init_clock();
31058
30917
  init_plain();
31059
30918
  init_repo_sync();
@@ -31143,8 +31002,7 @@ async function watchOn(opts) {
31143
31002
  }
31144
31003
  }
31145
31004
 
31146
- //#endregion
31147
- //#region src/repo/folder.ts
31005
+ // src/repo/folder.ts
31148
31006
  /**
31149
31007
  * The `.harbor/` folder on disk, and finding it: like git, `harbor sync`
31150
31008
  * works from anywhere inside the repository.
@@ -31212,8 +31070,7 @@ var init_folder = __esmMin((() => {
31212
31070
  PLAN_DIR = ".harbor";
31213
31071
  }));
31214
31072
 
31215
- //#endregion
31216
- //#region src/repo/commands.ts
31073
+ // src/repo/commands.ts
31217
31074
  /**
31218
31075
  * `harbor init` and `harbor sync` as the CLI runs them (cli/lib/cli.mjs,
31219
31076
  * through the bundled app): the folder on disk, the signed-in transport, and
@@ -31365,8 +31222,7 @@ var init_commands = __esmMin((() => {
31365
31222
  HOOK = "harbor sync --quiet || true";
31366
31223
  }));
31367
31224
 
31368
- //#endregion
31369
- //#region src/tui/main.tsx
31225
+ // src/tui/main.tsx
31370
31226
  /**
31371
31227
  * The Harbor terminal app, started by `harbor` with no arguments (cli/).
31372
31228
  * Bundled into cli/dist/app.mjs by cli/build.mjs; Ink and React stay the
@@ -31654,5 +31510,4 @@ function planTransport(source, fetcher) {
31654
31510
  return httpTransport(source, fetcher);
31655
31511
  }
31656
31512
 
31657
- //#endregion
31658
31513
  export { SPLASH_MS, TransportError, firstHarbor, fogHere, harborNamed, httpTransport, initHere, initLocalHere, localPlanAt, planTransport, runApp, runLocalApp, startApp, syncHere, tryHere, watchHere, watchSince };