react-os-shell 4.2.2 → 4.3.1
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/README.md +5 -0
- package/dist/{Browser-TPAIWPZX.js → Browser-674YMWMK.js} +6 -6
- package/dist/{Browser-TPAIWPZX.js.map → Browser-674YMWMK.js.map} +1 -1
- package/dist/{Calculator-RCNLBRHK.js → Calculator-3ULKK5ZA.js} +5 -5
- package/dist/{Calculator-RCNLBRHK.js.map → Calculator-3ULKK5ZA.js.map} +1 -1
- package/dist/ConfirmDialog-XJP67AHR.js +4 -0
- package/dist/{ConfirmDialog-QMBUHDXK.js.map → ConfirmDialog-XJP67AHR.js.map} +1 -1
- package/dist/{CurrencyConverter-CM5OTXWF.js → CurrencyConverter-JC2N7AY3.js} +5 -5
- package/dist/{CurrencyConverter-CM5OTXWF.js.map → CurrencyConverter-JC2N7AY3.js.map} +1 -1
- package/dist/{Documents-3BPIAGQT.js → Documents-MJKEUOOL.js} +6 -6
- package/dist/{Documents-3BPIAGQT.js.map → Documents-MJKEUOOL.js.map} +1 -1
- package/dist/{Files-CR3L5C2L.js → Files-BTZMPTL6.js} +8 -8
- package/dist/{Files-CR3L5C2L.js.map → Files-BTZMPTL6.js.map} +1 -1
- package/dist/{Notepad-C6JHCCF2.js → Notepad-NGLFEJLA.js} +6 -6
- package/dist/{Notepad-C6JHCCF2.js.map → Notepad-NGLFEJLA.js.map} +1 -1
- package/dist/{PomodoroTimer-EZMBYLQX.js → PomodoroTimer-RPCRTUKC.js} +6 -6
- package/dist/{PomodoroTimer-EZMBYLQX.js.map → PomodoroTimer-RPCRTUKC.js.map} +1 -1
- package/dist/{Preview-TFDEMTSH.js → Preview-H4S427VB.js} +6 -6
- package/dist/{Preview-TFDEMTSH.js.map → Preview-H4S427VB.js.map} +1 -1
- package/dist/{Sidebar-VF2IOOFX.js → Sidebar-E553SOXC.js} +4 -4
- package/dist/{Sidebar-VF2IOOFX.js.map → Sidebar-E553SOXC.js.map} +1 -1
- package/dist/{Spreadsheet-FRUPALW4.js → Spreadsheet-2YYUKKSY.js} +6 -6
- package/dist/{Spreadsheet-FRUPALW4.js.map → Spreadsheet-2YYUKKSY.js.map} +1 -1
- package/dist/{Stock-HL42NPTM.js → Stock-YTQ2OYQ7.js} +5 -5
- package/dist/{Stock-HL42NPTM.js.map → Stock-YTQ2OYQ7.js.map} +1 -1
- package/dist/{Weather-N74AKS6V.js → Weather-4I4EFUJO.js} +5 -5
- package/dist/{Weather-N74AKS6V.js.map → Weather-4I4EFUJO.js.map} +1 -1
- package/dist/{WorldClock-A2EDB57H.js → WorldClock-7PZI7VRE.js} +5 -5
- package/dist/{WorldClock-A2EDB57H.js.map → WorldClock-7PZI7VRE.js.map} +1 -1
- package/dist/apps/index.js +18 -18
- package/dist/chunk-3NZSR3ZG.js +20 -0
- package/dist/chunk-3NZSR3ZG.js.map +1 -0
- package/dist/{chunk-RKNJSV2T.js → chunk-ASRXGCSQ.js} +5 -5
- package/dist/{chunk-RKNJSV2T.js.map → chunk-ASRXGCSQ.js.map} +1 -1
- package/dist/{chunk-6Q4KYGMH.js → chunk-DKDD5KXG.js} +14 -3
- package/dist/chunk-DKDD5KXG.js.map +1 -0
- package/dist/chunk-K6MB36UJ.js +7 -0
- package/dist/{chunk-D36OPVAT.js.map → chunk-K6MB36UJ.js.map} +1 -1
- package/dist/{chunk-CWFH34LM.js → chunk-LBY7KH2W.js} +3 -3
- package/dist/{chunk-CWFH34LM.js.map → chunk-LBY7KH2W.js.map} +1 -1
- package/dist/{chunk-QJXXSMPG.js → chunk-PMPJLVZV.js} +3 -3
- package/dist/{chunk-QJXXSMPG.js.map → chunk-PMPJLVZV.js.map} +1 -1
- package/dist/{chunk-52RFL3OQ.js → chunk-QAKURGOG.js} +3 -3
- package/dist/{chunk-52RFL3OQ.js.map → chunk-QAKURGOG.js.map} +1 -1
- package/dist/{chunk-SI4XHEMM.js → chunk-VA6M46NL.js} +242 -13
- package/dist/chunk-VA6M46NL.js.map +1 -0
- package/dist/{chunk-5TU6DT3E.js → chunk-YF2XNVGN.js} +3 -3
- package/dist/{chunk-5TU6DT3E.js.map → chunk-YF2XNVGN.js.map} +1 -1
- package/dist/index.d.ts +222 -1
- package/dist/index.js +53 -16
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/ConfirmDialog-QMBUHDXK.js +0 -4
- package/dist/chunk-6Q4KYGMH.js.map +0 -1
- package/dist/chunk-ADJ3CERD.js +0 -31
- package/dist/chunk-ADJ3CERD.js.map +0 -1
- package/dist/chunk-D36OPVAT.js +0 -7
- package/dist/chunk-SI4XHEMM.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toast_default } from './chunk-VENYVK3L.js';
|
|
2
|
-
import { useShellPrefs } from './chunk-
|
|
2
|
+
import { useShellPrefs } from './chunk-VA6M46NL.js';
|
|
3
3
|
import { useSyncExternalStore, useCallback, useMemo } from 'react';
|
|
4
4
|
|
|
5
5
|
// src/shell/pomodoroStore.ts
|
|
@@ -545,5 +545,5 @@ function migratePomodoroTasksOnce(currentTasks, setAllTasks) {
|
|
|
545
545
|
}
|
|
546
546
|
|
|
547
547
|
export { ALARM_OPTIONS, FOCUS_SOUND_OPTIONS, getPomoSnapshot, migratePomodoroTasksOnce, playAlarm, pomoPause, pomoStart, pomoSwitchMode, previewFocusSound, setPomoAlarm, setPomoAlarmConfig, setPomoBehaviour, setPomoDurations, setPomoFocusSound, setShellTodoProvider, subscribePomo, useTodoTasks };
|
|
548
|
-
//# sourceMappingURL=chunk-
|
|
549
|
-
//# sourceMappingURL=chunk-
|
|
548
|
+
//# sourceMappingURL=chunk-YF2XNVGN.js.map
|
|
549
|
+
//# sourceMappingURL=chunk-YF2XNVGN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shell/pomodoroStore.ts","../src/apps/_todoStore.ts"],"names":[],"mappings":";;;;;AA8DO,IAAM,aAAA,GAA0E;AAAA,EACrF,EAAE,EAAA,EAAI,MAAA,EAAe,KAAA,EAAO,MAAA,EAAiB,aAAa,6BAAA,EAA8B;AAAA,EACxF,EAAE,EAAA,EAAI,OAAA,EAAe,KAAA,EAAO,OAAA,EAAiB,aAAa,0BAAA,EAA2B;AAAA,EACrF,EAAE,EAAA,EAAI,MAAA,EAAe,KAAA,EAAO,cAAA,EAAiB,aAAa,4BAAA,EAA6B;AAAA,EACvF,EAAE,EAAA,EAAI,aAAA,EAAe,KAAA,EAAO,aAAA,EAAiB,aAAa,+BAAA,EAAgC;AAAA,EAC1F,EAAE,EAAA,EAAI,KAAA,EAAe,KAAA,EAAO,cAAA,EAAiB,aAAa,2CAAA;AAC5D;AAEO,IAAM,mBAAA,GAA2D;AAAA,EACtE,EAAE,EAAA,EAAI,MAAA,EAAc,KAAA,EAAO,MAAA,EAAO;AAAA,EAClC,EAAE,EAAA,EAAI,WAAA,EAAc,KAAA,EAAO,cAAA,EAAe;AAAA,EAC1C,EAAE,EAAA,EAAI,WAAA,EAAc,KAAA,EAAO,cAAA,EAAe;AAAA,EAC1C,EAAE,EAAA,EAAI,MAAA,EAAc,KAAA,EAAO,MAAA,EAAO;AAAA,EAClC,EAAE,EAAA,EAAI,WAAA,EAAc,KAAA,EAAO,WAAA,EAAY;AAAA,EACvC,EAAE,EAAA,EAAI,OAAA,EAAc,KAAA,EAAO,aAAA,EAAc;AAAA,EACzC,EAAE,EAAA,EAAI,MAAA,EAAc,KAAA,EAAO,YAAA,EAAa;AAAA,EACxC,EAAE,EAAA,EAAI,OAAA,EAAc,KAAA,EAAO,aAAA;AAC7B;AAEA,IAAM,QAAA,GAAW,MAAM,CAAA,SAAA,EAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AACxE,IAAM,YAAY,MAAM;AACtB,EAAA,IAAI;AAAE,IAAA,OAAO,QAAA,CAAS,aAAa,OAAA,CAAQ,QAAA,EAAU,CAAA,IAAK,GAAA,EAAK,EAAE,CAAA,IAAK,CAAA;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,CAAA;AAAA,EAAG;AAC/F,CAAA;AACA,IAAM,SAAA,GAAY,CAAC,CAAA,KAAc;AAC/B,EAAA,IAAI;AAAE,IAAA,YAAA,CAAa,OAAA,CAAQ,QAAA,EAAS,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAA,EAAC;AAC9D,CAAA;AAEA,IAAI,UAAA,GAA4B,EAAE,KAAA,EAAO,EAAA,GAAK,EAAA,EAAI,OAAO,CAAA,GAAI,EAAA,EAAI,IAAA,EAAM,EAAA,GAAK,EAAA,EAAG;AAC/E,IAAI,MAAA,GAAqB,MAAA;AACzB,IAAI,YAAA,GAAe,GAAA;AACnB,IAAI,YAAA,GAAe,CAAA;AACnB,IAAI,eAAA,GAA8B,MAAA;AAClC,IAAI,YAAA,GAAe,EAAA;AACnB,IAAI,aAA4B,EAAE,eAAA,EAAiB,OAAO,kBAAA,EAAoB,KAAA,EAAO,mBAAmB,CAAA,EAAE;AAE1G,IAAI,MAAA,GAAuB;AAAA,EACzB,OAAA,EAAS,KAAA;AAAA,EACT,WAAW,UAAA,CAAW,KAAA;AAAA,EACtB,IAAA,EAAM,OAAA;AAAA,EACN,OAAO,UAAA,CAAW,KAAA;AAAA,EAClB,MAAA,EAAQ,CAAA;AAAA,EACR,KAAA,EAAO,OAAO,YAAA,KAAiB,WAAA,GAAc,WAAU,GAAI;AAC7D,CAAA;AAEA,IAAI,WAAA,GAAqD,IAAA;AACzD,IAAM,UAAA,uBAAiB,GAAA,EAAgB;AAEvC,IAAM,UAAU,MAAM,UAAA,CAAW,OAAA,CAAQ,CAAA,CAAA,KAAK,GAAG,CAAA;AACjD,IAAM,IAAA,GAAO,CAAC,CAAA,KAA6B;AAAE,EAAA,MAAA,GAAS,EAAE,GAAG,MAAA,EAAQ,GAAG,CAAA,EAAE;AAAG,EAAA,OAAA,EAAQ;AAAG,CAAA;AAE/E,SAAS,eAAA,GAAgC;AAAE,EAAA,OAAO,MAAA;AAAQ;AAC1D,SAAS,cAAc,CAAA,EAAe;AAAE,EAAA,UAAA,CAAW,IAAI,CAAC,CAAA;AAAG,EAAA,OAAO,MAAM;AAAE,IAAA,UAAA,CAAW,OAAO,CAAC,CAAA;AAAA,EAAG,CAAA;AAAG;AAEnG,SAAS,iBAAiB,CAAA,EAAkB;AACjD,EAAA,UAAA,GAAa,CAAA;AAGb,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,SAAA,KAAc,OAAO,KAAA,EAAO;AACxD,IAAA,IAAA,CAAK,EAAE,SAAA,EAAW,CAAA,CAAE,MAAA,CAAO,IAAI,CAAA,EAAG,KAAA,EAAO,CAAA,CAAE,MAAA,CAAO,IAAI,CAAA,EAAG,CAAA;AAAA,EAC3D;AACF;AAGO,SAAS,aAAa,CAAA,EAAe;AAAE,EAAA,MAAA,GAAS,CAAA;AAAG;AAMnD,SAAS,kBAAA,CAAmB,QAAgB,MAAA,EAAgB;AACjE,EAAA,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,KAAK,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAC,CAAA;AAC5D,EAAA,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAC,CAAA;AAC5D;AAGO,SAAS,iBAAiB,CAAA,EAAkB;AACjD,EAAA,UAAA,GAAa;AAAA,IACX,eAAA,EAAiB,CAAC,CAAC,CAAA,CAAE,eAAA;AAAA,IACrB,kBAAA,EAAoB,CAAC,CAAC,CAAA,CAAE,kBAAA;AAAA,IACxB,iBAAA,EAAmB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,iBAAA,IAAqB,CAAC,CAAC,CAAC;AAAA,GACnF;AACF;AAKO,SAAS,iBAAA,CAAkB,MAAkB,MAAA,EAAgB;AAClE,EAAA,eAAA,GAAkB,IAAA;AAClB,EAAA,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,KAAK,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAC,CAAA;AAE5D,EAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,IAAA,KAAS,OAAA,EAAS;AAC7C,IAAA,cAAA,EAAe;AACf,IAAA,eAAA,EAAgB;AAAA,EAClB,CAAA,MAAA,IAAW,IAAA,KAAS,MAAA,IAAU,YAAA,KAAiB,CAAA,EAAG;AAChD,IAAA,cAAA,EAAe;AAAA,EACjB;AACF;AAGO,SAAS,SAAA,GAAY;AAC1B,EAAA,IAAI,OAAO,OAAA,EAAS;AACpB,EAAA,IAAA,CAAK,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA;AACtB,EAAA,WAAA,GAAc,WAAA,CAAY,OAAO,GAAI,CAAA;AACrC,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,OAAA,EAAS,eAAA,EAAgB;AAC/C;AACO,SAAS,SAAA,GAAY;AAC1B,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,WAAA,KAAgB,IAAA,EAAM;AAC7C,EAAA,IAAI,gBAAgB,IAAA,EAAM;AAAE,IAAA,aAAA,CAAc,WAAW,CAAA;AAAG,IAAA,WAAA,GAAc,IAAA;AAAA,EAAM;AAC5E,EAAA,IAAA,CAAK,EAAE,OAAA,EAAS,KAAA,EAAO,CAAA;AACvB,EAAA,cAAA,EAAe;AACjB;AAKO,SAAS,eAAe,CAAA,EAAS;AACtC,EAAA,SAAA,EAAU;AACV,EAAA,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,SAAA,EAAW,UAAA,CAAW,CAAC,CAAA,EAAG,KAAA,EAAO,UAAA,CAAW,CAAC,CAAA,EAAG,CAAA;AAClE;AAEA,SAAS,KAAA,GAAQ;AACf,EAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,IAAA,aAAA,EAAc;AACd,IAAA;AAAA,EACF;AACA,EAAA,IAAA,CAAK,EAAE,SAAA,EAAW,MAAA,CAAO,SAAA,GAAY,GAAG,CAAA;AAC1C;AAEA,SAAS,aAAA,GAAgB;AACvB,EAAA,IAAI,gBAAgB,IAAA,EAAM;AAAE,IAAA,aAAA,CAAc,WAAW,CAAA;AAAG,IAAA,WAAA,GAAc,IAAA;AAAA,EAAM;AAC5E,EAAA,cAAA,EAAe;AACf,EAAA,SAAA,CAAU,QAAQ,EAAE,MAAA,EAAQ,YAAA,EAAc,MAAA,EAAQ,cAAc,CAAA;AAQhE,EAAA,MAAM,iBAAA,GAAoB,OAAO,IAAA,KAAS,OAAA;AAC1C,EAAA,MAAM,QAAA,GAAW,oBAAoB,sDAAA,GAA6C,mCAAA;AAClF,EAAA,IAAI,OAAO,YAAA,KAAiB,WAAA,IAAe,YAAA,CAAa,eAAe,SAAA,EAAW;AAChF,IAAA,IAAI;AAAE,MAAA,IAAI,aAAa,QAAQ,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAC;AAAA,EAC7C;AACA,EAAA,IAAI;AAAE,IAAA,aAAA,CAAM,KAAK,QAAQ,CAAA;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAA,EAAC;AAErC,EAAA,IAAI,MAAA,CAAO,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,UAAA,GAAa,OAAO,MAAA,GAAS,CAAA;AACnC,IAAA,MAAM,QAAA,GAAW,OAAO,KAAA,GAAQ,CAAA;AAChC,IAAA,SAAA,CAAU,QAAQ,CAAA;AAClB,IAAA,MAAM,QAAA,GAAiB,UAAA,GAAa,UAAA,CAAW,iBAAA,KAAsB,IAAI,MAAA,GAAS,OAAA;AAClF,IAAA,IAAA,CAAK;AAAA,MACH,OAAA,EAAS,KAAA;AAAA,MACT,MAAA,EAAQ,UAAA;AAAA,MACR,KAAA,EAAO,QAAA;AAAA,MACP,IAAA,EAAM,QAAA;AAAA,MACN,SAAA,EAAW,WAAW,QAAQ,CAAA;AAAA,MAC9B,KAAA,EAAO,WAAW,QAAQ;AAAA,KAC3B,CAAA;AACD,IAAA,IAAI,WAAW,eAAA,EAAiB,UAAA,CAAW,MAAM,SAAA,IAAa,EAAE,CAAA;AAAA,EAClE,CAAA,MAAO;AACL,IAAA,IAAA,CAAK;AAAA,MACH,OAAA,EAAS,KAAA;AAAA,MACT,IAAA,EAAM,OAAA;AAAA,MACN,WAAW,UAAA,CAAW,KAAA;AAAA,MACtB,OAAO,UAAA,CAAW;AAAA,KACnB,CAAA;AACD,IAAA,IAAI,WAAW,kBAAA,EAAoB,UAAA,CAAW,MAAM,SAAA,IAAa,EAAE,CAAA;AAAA,EACrE;AACF;AAMO,SAAS,SAAA,CAAU,IAAA,GAAmB,MAAA,EAAQ,IAAA,GAA6C,EAAC,EAAG;AACpG,EAAA,IAAI,SAAS,KAAA,EAAO;AACpB,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,MAAA,IAAU,GAAG,CAAC,CAAA,GAAI,GAAA;AAClE,EAAA,IAAI,aAAa,CAAA,EAAG;AACpB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,MAAA,IAAU,CAAC,CAAC,CAAA;AACxD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,UAAA,CAAW,MAAM,cAAA,CAAe,IAAA,EAAM,QAAQ,CAAA,EAAG,IAAI,IAAI,CAAA;AAAA,EAC3D;AACF;AAEA,SAAS,cAAA,CAAe,MAAkB,QAAA,EAAkB;AAC1D,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAA6B,MAAA,CAAe,YAAA,IAAiB,MAAA,CAAe,kBAAA;AAClF,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,GAAA,GAAM,IAAI,IAAA,EAAK;AACrB,IAAA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAc,KAAA,EAAe,UAAkB,GAAA,GAAM,IAAA,EAAM,OAAuB,MAAA,KAAW;AAC7G,MAAA,MAAM,GAAA,GAAM,IAAI,gBAAA,EAAiB;AACjC,MAAA,MAAM,IAAA,GAAO,IAAI,UAAA,EAAW;AAC5B,MAAA,GAAA,CAAI,QAAQ,IAAI,CAAA;AAAG,MAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,WAAW,CAAA;AAC/C,MAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,MAAA,GAAA,CAAI,UAAU,KAAA,GAAQ,IAAA;AACtB,MAAA,MAAM,EAAA,GAAK,IAAI,WAAA,GAAc,KAAA;AAC7B,MAAA,IAAA,CAAK,IAAA,CAAK,cAAA,CAAe,CAAA,EAAG,EAAE,CAAA;AAC9B,MAAA,IAAA,CAAK,IAAA,CAAK,uBAAA,CAAwB,GAAA,GAAM,QAAA,EAAU,KAAK,IAAI,CAAA;AAC3D,MAAA,IAAA,CAAK,IAAA,CAAK,4BAAA,CAA6B,IAAA,EAAQ,EAAA,GAAK,QAAQ,CAAA;AAC5D,MAAA,GAAA,CAAI,MAAM,EAAE,CAAA;AACZ,MAAA,GAAA,CAAI,IAAA,CAAK,KAAK,QAAQ,CAAA;AAAA,IACxB,CAAA;AACA,IAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,QAAA,CAAS,GAAA,EAAK,GAAG,GAAG,CAAA;AACpB,MAAA,QAAA,CAAS,IAAA,EAAM,CAAA,EAAG,GAAA,EAAK,GAAI,CAAA;AAC3B,MAAA,aAAA,GAAgB,CAAA;AAAA,IAClB,CAAA,MAAA,IAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,QAAA,CAAS,MAAA,EAAQ,GAAG,GAAG,CAAA;AACvB,MAAA,QAAA,CAAS,GAAA,EAAK,KAAM,GAAG,CAAA;AACvB,MAAA,aAAA,GAAgB,CAAA;AAAA,IAClB,CAAA,MAAA,IAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,QAAA,CAAS,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,IAAI,CAAA;AAC1B,MAAA,QAAA,CAAS,GAAA,EAAK,CAAA,EAAG,CAAA,EAAK,IAAI,CAAA;AAC1B,MAAA,QAAA,CAAS,GAAA,EAAK,IAAA,EAAM,GAAA,EAAK,IAAI,CAAA;AAC7B,MAAA,aAAA,GAAgB,CAAA;AAAA,IAClB,CAAA,MAAA,IAAW,SAAS,aAAA,EAAe;AACjC,MAAA,QAAA,CAAS,IAAA,EAAM,CAAA,EAAM,GAAA,EAAK,IAAI,CAAA;AAC9B,MAAA,QAAA,CAAS,GAAA,EAAM,IAAA,EAAM,GAAA,EAAK,IAAI,CAAA;AAC9B,MAAA,QAAA,CAAS,IAAA,EAAM,GAAA,EAAM,GAAA,EAAK,IAAI,CAAA;AAC9B,MAAA,QAAA,CAAS,IAAA,EAAM,GAAA,EAAM,GAAA,EAAK,IAAI,CAAA;AAC9B,MAAA,aAAA,GAAgB,CAAA;AAAA,IAClB;AACA,IAAA,UAAA,CAAW,MAAM;AAAE,MAAA,IAAI;AAAE,QAAA,GAAA,CAAI,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAA,IAAE,CAAA,EAAG,aAAA,GAAgB,GAAA,GAAO,GAAG,CAAA;AAAA,EAChF,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AAGA,IAAI,WAAA,GAAwF,IAAA;AAM5F,IAAM,aAAA,GAA4C;AAAA,EAChD,IAAA,EAAa,CAAA;AAAA,EACb,KAAA,EAAa,GAAA;AAAA,EACb,IAAA,EAAa,GAAA;AAAA,EACb,KAAA,EAAa,GAAA;AAAA,EACb,WAAA,EAAa,GAAA;AAAA,EACb,WAAA,EAAa,GAAA;AAAA,EACb,IAAA,EAAa,GAAA;AAAA,EACb,SAAA,EAAa;AACf,CAAA;AAEA,SAAS,gBAAA,CAAiB,KAAmB,IAAA,EAAsC;AACjF,EAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,IAAA;AAC5B,EAAA,MAAM,KAAK,GAAA,CAAI,UAAA;AAIf,EAAA,MAAM,MAAO,IAAA,KAAS,OAAA,IAAW,SAAS,MAAA,IAAU,IAAA,KAAS,UAAW,CAAA,GAAI,CAAA;AAC5E,EAAA,MAAM,MAAM,EAAA,GAAK,GAAA;AACjB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,YAAA,CAAa,CAAA,EAAG,KAAK,EAAE,CAAA;AAC1C,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,cAAA,CAAe,CAAC,CAAA;AAEpC,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK,IAAA,CAAK,CAAC,CAAA,GAAA,CAAK,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA,GAAI,CAAA,IAAK,GAAA;AAAA,EAEpE,CAAA,MAAA,IAAW,SAAS,MAAA,EAAQ;AAE1B,IAAA,IAAI,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,CAAA;AACzD,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA,GAAI,CAAA;AAC9B,MAAA,EAAA,GAAK,OAAA,GAAU,KAAK,CAAA,GAAI,SAAA;AACxB,MAAA,EAAA,GAAK,OAAA,GAAU,KAAK,CAAA,GAAI,SAAA;AACxB,MAAA,EAAA,GAAK,KAAA,GAAU,KAAK,CAAA,GAAI,QAAA;AACxB,MAAA,EAAA,GAAK,MAAA,GAAU,KAAK,CAAA,GAAI,SAAA;AACxB,MAAA,EAAA,GAAK,IAAA,GAAU,KAAK,CAAA,GAAI,SAAA;AACxB,MAAA,EAAA,GAAK,OAAA,GAAU,KAAK,CAAA,GAAI,QAAA;AACxB,MAAA,IAAA,CAAK,CAAC,CAAA,GAAA,CAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,CAAA,GAAI,MAAA,IAAU,IAAA,GAAO,IAAA;AACnE,MAAA,EAAA,GAAK,CAAA,GAAI,QAAA;AAAA,IACX;AAAA,EAEF,CAAA,MAAA,IAAW,SAAS,OAAA,EAAS;AAE3B,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA,GAAI,CAAA;AAC9B,MAAA,IAAA,GAAA,CAAQ,IAAA,GAAO,OAAO,CAAA,IAAK,IAAA;AAC3B,MAAA,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,GAAO,GAAA,GAAM,GAAA;AAAA,IACzB;AAAA,EAEF,CAAA,MAAA,IAAW,IAAA,KAAS,WAAA,IAAe,IAAA,KAAS,WAAA,EAAa;AAIvD,IAAA,MAAM,WAAA,GAAc,IAAA,KAAS,WAAA,GAAc,GAAA,GAAM,CAAA;AACjD,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,KAAK,CAAA;AACzC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,KAAK,WAAA,EAAa;AACzC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAE,CAAA;AAC/B,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,eAAe,KAAA,GAAQ,CAAA,GAAI,KAAK,CAAA,EAAA,EAAK;AACvD,QAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,KAAK,GAAG,CAAA;AAClC,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA,GAAI,CAAA;AAElC,QAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,GAAI,KAAK,EAAA,GAAK,IAAA,IAAQ,IAAI,EAAA,CAAG,CAAA;AACnD,QAAA,IAAA,CAAK,QAAQ,CAAC,CAAA,IAAA,CAAM,QAAQ,GAAA,GAAM,IAAA,GAAO,QAAQ,GAAA,GAAM,IAAA;AAAA,MACzD;AAAA,IACF;AAAA,EAEF,CAAA,MAAA,IAAW,SAAS,MAAA,EAAQ;AAG1B,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA,GAAI,CAAA;AAC9B,MAAA,MAAM,QAAA,GAAW,IAAI,IAAA,GAAO,IAAA;AAC5B,MAAA,IAAA,GAAO,CAAA;AACP,MAAA,MAAM,IAAA,GAAO,GAAA,GAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAK,IAAI,EAAA,GAAM,CAAA,GAAI,IAAA,CAAK,EAAA,GAAK,IAAI,CAAA;AAC/D,MAAA,IAAA,CAAK,CAAC,CAAA,GAAI,QAAA,GAAW,IAAA,GAAO,GAAA;AAAA,IAC9B;AAAA,EAEF,CAAA,MAAA,IAAW,SAAS,WAAA,EAAa;AAG/B,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,CAAA,EAAA,EAAK;AAC5B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA,GAAI,CAAA;AAC9B,MAAA,IAAA,GAAA,CAAQ,IAAA,GAAO,OAAO,CAAA,IAAK,IAAA;AAC3B,MAAA,IAAA,CAAK,CAAC,IAAI,IAAA,GAAO,GAAA;AAAA,IACnB;AACA,IAAA,IAAI,IAAA,GAAO,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,GAAM,EAAA;AACjC,IAAA,OAAO,OAAO,GAAA,EAAK;AACjB,MAAA,MAAM,MAAA,GAAS,KAAK,KAAA,CAAA,CAAO,KAAA,GAAQ,KAAK,MAAA,EAAO,GAAI,QAAQ,EAAE,CAAA;AAC7D,MAAA,MAAM,MAAA,GAAS,IAAA,GAAO,IAAA,CAAK,MAAA,EAAO,GAAI,IAAA;AACtC,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC9B,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,UAAU,MAAA,GAAS,CAAA,GAAI,KAAK,CAAA,EAAA,EAAK;AACnD,QAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,KAAK,EAAE,CAAA;AACjC,QAAA,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,IAAA,CAAM,IAAA,CAAK,QAAO,GAAI,CAAA,GAAI,KAAK,GAAA,GAAM,MAAA;AAAA,MACtD;AAEA,MAAA,IAAA,IAAA,CAAS,IAAA,GAAO,IAAA,CAAK,MAAA,EAAO,GAAI,IAAA,IAAQ,EAAA;AAAA,IAC1C;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,eAAA,GAAkB;AACzB,EAAA,IAAI,WAAA,EAAa;AACjB,EAAA,IAAI,eAAA,KAAoB,MAAA,IAAU,YAAA,KAAiB,CAAA,EAAG;AACtD,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAA6B,MAAA,CAAe,YAAA,IAAiB,MAAA,CAAe,kBAAA;AAClF,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,GAAA,GAAM,IAAI,IAAA,EAAK;AACrB,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,EAAK,eAAe,CAAA;AACpD,IAAA,IAAI,CAAC,MAAA,EAAQ;AAAE,MAAA,IAAI;AAAE,QAAA,GAAA,CAAI,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAE,MAAA;AAAA,IAAQ;AACrD,IAAA,MAAM,GAAA,GAAM,IAAI,kBAAA,EAAmB;AACnC,IAAA,GAAA,CAAI,MAAA,GAAS,MAAA;AACb,IAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,IAAA,MAAM,IAAA,GAAO,IAAI,UAAA,EAAW;AAC5B,IAAA,IAAA,CAAK,IAAA,CAAK,KAAA,GAAS,YAAA,GAAe,GAAA,GAAO,cAAc,eAAe,CAAA;AACtE,IAAA,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAE,OAAA,CAAQ,IAAI,WAAW,CAAA;AACzC,IAAA,GAAA,CAAI,KAAA,EAAM;AACV,IAAA,WAAA,GAAc,EAAE,GAAA,EAAK,GAAA,EAAK,IAAA,EAAK;AAAA,EACjC,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AAEA,SAAS,cAAA,GAAiB;AACxB,EAAA,IAAI,CAAC,WAAA,EAAa;AAClB,EAAA,IAAI;AAAE,IAAA,WAAA,CAAY,IAAI,IAAA,EAAK;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAA,EAAC;AACvC,EAAA,IAAI;AAAE,IAAA,WAAA,CAAY,IAAI,KAAA,EAAM;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAA,EAAC;AACxC,EAAA,WAAA,GAAc,IAAA;AAChB;AAIO,SAAS,iBAAA,CAAkB,MAAkB,MAAA,EAAgB;AAClE,EAAA,IAAI,IAAA,KAAS,MAAA,IAAU,MAAA,KAAW,CAAA,EAAG;AACrC,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAA6B,MAAA,CAAe,YAAA,IAAiB,MAAA,CAAe,kBAAA;AAClF,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,GAAA,GAAM,IAAI,IAAA,EAAK;AACrB,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,EAAK,IAAI,CAAA;AACzC,IAAA,IAAI,CAAC,MAAA,EAAQ;AAAE,MAAA,IAAI;AAAE,QAAA,GAAA,CAAI,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAE,MAAA;AAAA,IAAQ;AACrD,IAAA,MAAM,GAAA,GAAM,IAAI,kBAAA,EAAmB;AACnC,IAAA,GAAA,CAAI,MAAA,GAAS,MAAA;AACb,IAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,IAAA,MAAM,IAAA,GAAO,IAAI,UAAA,EAAW;AAC5B,IAAA,IAAA,CAAK,IAAA,CAAK,KAAA,GAAS,MAAA,GAAS,GAAA,GAAO,cAAc,IAAI,CAAA;AACrD,IAAA,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAE,OAAA,CAAQ,IAAI,WAAW,CAAA;AACzC,IAAA,GAAA,CAAI,KAAA,EAAM;AACV,IAAA,UAAA,CAAW,MAAM;AACf,MAAA,IAAI;AAAE,QAAA,GAAA,CAAI,IAAA,EAAK;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAC3B,MAAA,IAAI;AAAE,QAAA,GAAA,CAAI,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAA,IAC9B,GAAG,GAAI,CAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AC/aA,IAAM,mBAAA,GAAsB,gBAAA;AAC5B,IAAM,6BAAA,GAAgC,yBAAA;AAEtC,SAAS,GAAA,GAAc;AACrB,EAAA,OAAO,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AAC/C;AAEA,SAAS,MAAA,GAAiB;AACxB,EAAA,OAAA,iBAAO,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAChC;AA6BA,IAAI,QAAA,GAAgC,IAAA;AACpC,IAAI,QAAoB,EAAC;AACzB,IAAI,MAAA,GAAS,KAAA;AACb,IAAI,QAAA,GAAiC,IAAA;AACrC,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,SAAS,IAAA,GAAa;AACpB,EAAA,KAAA,MAAW,CAAA,IAAK,WAAW,CAAA,EAAE;AAC/B;AAEA,SAAS,SAAS,IAAA,EAAwB;AACxC,EAAA,KAAA,GAAQ,IAAA;AACR,EAAA,IAAA,EAAK;AACP;AAEA,SAAS,OAAA,GAAyB;AAChC,EAAA,MAAM,CAAA,GAAI,QAAA;AACV,EAAA,IAAI,CAAC,CAAA,EAAG;AACN,IAAA,KAAA,GAAQ,EAAC;AACT,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,IAAA,EAAK;AACL,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AACA,EAAA,QAAA,GAAW,CAAA,CACR,IAAA,EAAK,CACL,IAAA,CAAK,CAAA,IAAA,KAAQ;AACZ,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,KAAA,GAAQ,IAAA;AACR,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,IAAA,EAAK;AAAA,IACP;AAAA,EACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,IAAA,EAAK;AAAA,IACP;AAAA,EACF,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,IAAA,QAAA,GAAW,IAAA;AAAA,EACb,CAAC,CAAA;AACH,EAAA,OAAO,QAAA;AACT;AAGO,SAAS,qBAAqB,IAAA,EAAiC;AACpE,EAAA,QAAA,GAAW,IAAA;AACX,EAAA,KAAA,GAAQ,EAAC;AACT,EAAA,MAAA,GAAS,KAAA;AACT,EAAA,IAAI,MAAM,OAAA,EAAQ;AAAA,OACb,IAAA,EAAK;AACZ;AAEO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,QAAA,KAAa,IAAA;AACtB;AAEA,SAAS,UAAU,EAAA,EAA4B;AAC7C,EAAA,SAAA,CAAU,IAAI,EAAE,CAAA;AAChB,EAAA,IAAI,QAAA,IAAY,CAAC,MAAA,IAAU,CAAC,UAAU,OAAA,EAAQ;AAC9C,EAAA,OAAO,MAAM;AACX,IAAA,SAAA,CAAU,OAAO,EAAE,CAAA;AAAA,EACrB,CAAA;AACF;AAEA,SAAS,WAAA,GAA0B;AACjC,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,iBAAA,GAAkC;AACzC,EAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,aAAA,EAAc;AACtC,EAAA,MAAM,KAAA,GAAoB,QAAQ,MAAM;AACtC,IAAA,MAAM,MAAM,KAAA,CAAM,UAAA;AAClB,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAK,MAAqB,EAAC;AAAA,EACrD,CAAA,EAAG,CAAC,KAAA,CAAM,UAAU,CAAC,CAAA;AAErB,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,IAAA,KAAqB;AACnD,IAAA,IAAA,CAAK,EAAE,UAAA,EAAY,IAAA,EAAM,CAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,OAAA,GAAU,WAAA,CAAqC,CAAC,KAAA,KAAU;AAC9D,IAAA,MAAM,KAAK,GAAA,EAAI;AACf,IAAA,MAAM,KAAK,MAAA,EAAO;AAClB,IAAA,MAAM,IAAA,GAAiB,EAAE,IAAA,EAAM,KAAA,EAAO,GAAG,KAAA,EAAO,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,MAAK,EAAG,EAAA,EAAI,SAAA,EAAW,EAAA,EAAI,WAAW,EAAA,EAAG;AAC1G,IAAA,UAAA,CAAW,CAAC,GAAG,KAAA,EAAO,IAAI,CAAC,CAAA;AAC3B,IAAA,OAAO,EAAA;AAAA,EACT,CAAA,EAAG,CAAC,KAAA,EAAO,UAAU,CAAC,CAAA;AAEtB,EAAA,MAAM,UAAA,GAAa,WAAA,CAAwC,CAAC,EAAA,EAAI,KAAA,KAAU;AACxE,IAAA,UAAA,CAAW,MAAM,GAAA,CAAI,CAAA,CAAA,KAAM,EAAE,EAAA,KAAO,EAAA,GAAK,EAAE,GAAG,CAAA,EAAG,GAAG,KAAA,EAAO,EAAA,EAAI,EAAE,EAAA,EAAI,SAAA,EAAW,QAAO,EAAE,GAAI,CAAE,CAAC,CAAA;AAAA,EAClG,CAAA,EAAG,CAAC,KAAA,EAAO,UAAU,CAAC,CAAA;AAEtB,EAAA,MAAM,UAAA,GAAa,WAAA,CAAwC,CAAC,EAAA,KAAO;AACjE,IAAA,UAAA,CAAW,MAAM,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,KAAA,EAAO,UAAU,CAAC,CAAA;AAEtB,EAAA,MAAM,UAAA,GAAa,WAAA,CAAwC,CAAC,EAAA,KAAO;AACjE,IAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,EAAE,CAAA;AAC1C,IAAA,IAAI,MAAA,aAAmB,EAAA,EAAI,EAAE,MAAM,CAAC,MAAA,CAAO,MAAM,CAAA;AAAA,EACnD,CAAA,EAAG,CAAC,KAAA,EAAO,UAAU,CAAC,CAAA;AAEtB,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,YAAY,UAAA,EAAY,UAAA,EAAY,aAAa,UAAA,EAAW;AACvF;AAGO,SAAS,YAAA,GAA6B;AAE3C,EAAA,MAAM,YAAY,iBAAA,EAAkB;AACpC,EAAA,MAAM,aAAA,GAAgB,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,WAAW,CAAA;AAE9E,EAAA,MAAM,OAAA,GAAU,WAAA,CAAqC,CAAC,KAAA,KAAU;AAC9D,IAAA,MAAM,CAAA,GAAI,QAAA;AACV,IAAA,IAAI,CAAC,CAAA,EAAG,OAAO,SAAA,CAAU,QAAQ,KAAK,CAAA;AACtC,IAAA,MAAM,MAAA,GAAS,SAAS,GAAA,EAAI;AAC5B,IAAA,MAAM,KAAK,MAAA,EAAO;AAClB,IAAA,MAAM,aAAuB,EAAE,IAAA,EAAM,KAAA,EAAO,GAAG,OAAO,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAA,IAAQ,EAAA,EAAI,MAAA,EAAQ,SAAA,EAAW,EAAA,EAAI,WAAW,EAAA,EAAG;AACxH,IAAA,QAAA,CAAS,CAAC,GAAG,KAAA,EAAO,UAAU,CAAC,CAAA;AAC/B,IAAA,CAAA,CAAE,OAAO,EAAE,GAAG,OAAO,IAAA,EAAM,KAAA,CAAM,KAAK,IAAA,EAAK,EAAG,CAAA,CAG3C,KAAK,CAAA,KAAA,KAAS,QAAA,CAAS,MAAM,GAAA,CAAI,CAAA,CAAA,KAAM,EAAE,EAAA,KAAO,MAAA,GAAS,EAAE,GAAG,YAAY,GAAG,KAAA,KAAU,CAAE,CAAC,CAAC,CAAA,CAC3F,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,EAAA,KAAO,MAAM,CAAC,CAAC,CAAA;AAC3D,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,UAAA,GAAa,WAAA,CAAwC,CAAC,EAAA,EAAI,KAAA,KAAU;AACxE,IAAA,MAAM,CAAA,GAAI,QAAA;AACV,IAAA,IAAI,CAAC,CAAA,EAAG,OAAO,SAAA,CAAU,UAAA,CAAW,IAAI,KAAK,CAAA;AAC7C,IAAA,QAAA,CAAS,MAAM,GAAA,CAAI,CAAA,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,KAAK,EAAE,GAAG,CAAA,EAAG,GAAG,OAAO,EAAA,EAAI,SAAA,EAAW,QAAO,EAAE,GAAI,CAAE,CAAC,CAAA;AACxF,IAAA,CAAA,CAAE,MAAA,CAAO,EAAA,EAAI,KAAK,CAAA,CAAE,MAAM,MAAM;AAAE,MAAA,OAAA,EAAQ;AAAA,IAAG,CAAC,CAAA;AAAA,EAChD,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,UAAA,GAAa,WAAA,CAAwC,CAAC,EAAA,KAAO;AACjE,IAAA,MAAM,CAAA,GAAI,QAAA;AACV,IAAA,IAAI,CAAC,CAAA,EAAG,OAAO,SAAA,CAAU,WAAW,EAAE,CAAA;AACtC,IAAA,MAAM,IAAA,GAAO,KAAA;AACb,IAAA,QAAA,CAAS,MAAM,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AACvC,IAAA,CAAA,CAAE,OAAO,EAAE,CAAA,CAAE,MAAM,MAAM,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,EACzC,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,UAAA,GAAa,WAAA,CAAwC,CAAC,EAAA,KAAO;AACjE,IAAA,IAAI,CAAC,QAAA,EAAU,OAAO,SAAA,CAAU,WAAW,EAAE,CAAA;AAC7C,IAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,EAAE,CAAA;AAC1C,IAAA,IAAI,MAAA,aAAmB,EAAA,EAAI,EAAE,MAAM,CAAC,MAAA,CAAO,MAAM,CAAA;AAAA,EACnD,CAAA,EAAG,CAAC,SAAA,EAAW,UAAU,CAAC,CAAA;AAE1B,EAAA,MAAM,WAAA,GAAc,WAAA,CAAyC,CAAC,IAAA,KAAS;AAErE,IAAA,IAAI,CAAC,QAAA,EAAU,SAAA,CAAU,WAAA,CAAY,IAAI,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,IAAI,CAAC,oBAAA,EAAqB,EAAG,OAAO,SAAA;AACpC,EAAA,OAAO,EAAE,KAAA,EAAO,aAAA,EAAe,SAAS,UAAA,EAAY,UAAA,EAAY,YAAY,WAAA,EAAY;AAC1F;AAOO,SAAS,wBAAA,CACd,cACA,WAAA,EACM;AACN,EAAA,IAAI;AACF,IAAA,IAAI,YAAA,CAAa,OAAA,CAAQ,6BAA6B,CAAA,EAAG;AACzD,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,mBAAmB,CAAA;AACpD,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,YAAA,CAAa,OAAA,CAAQ,+BAA+B,GAAG,CAAA;AACvD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GACF,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAClB,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,IAAK,MAAA,CAAO,WAAW,CAAA,EAAG;AACjD,MAAA,YAAA,CAAa,WAAW,mBAAmB,CAAA;AAC3C,MAAA,YAAA,CAAa,OAAA,CAAQ,+BAA+B,GAAG,CAAA;AACvD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAK,MAAA,EAAO;AAClB,IAAA,MAAM,QAAA,GAAuB,MAAA,CAC1B,MAAA,CAAO,CAAA,CAAA,KAAK,OAAO,GAAG,IAAA,KAAS,QAAQ,CAAA,CACvC,GAAA,CAAI,CAAA,CAAA,MAAM;AAAA,MACT,EAAA,EAAI,CAAA,CAAE,EAAA,IAAM,GAAA,EAAI;AAAA,MAChB,IAAA,EAAM,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA;AAAA,MACnB,IAAA,EAAM,CAAC,CAAC,CAAA,CAAE,IAAA;AAAA,MACV,WAAW,OAAO,CAAA,CAAE,SAAA,KAAc,QAAA,GAAW,EAAE,SAAA,GAAY,KAAA,CAAA;AAAA,MAC3D,WAAW,OAAO,CAAA,CAAE,SAAA,KAAc,QAAA,GAAW,EAAE,SAAA,GAAY,KAAA,CAAA;AAAA,MAC3D,SAAA,EAAW,EAAA;AAAA,MACX,SAAA,EAAW;AAAA,KACb,CAAE,CAAA;AACJ,IAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,YAAA,CAAa,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AACvD,IAAA,MAAM,SAAA,GAAY,SAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AAC7D,IAAA,WAAA,CAAY,CAAC,GAAG,SAAA,EAAW,GAAG,YAAY,CAAC,CAAA;AAC3C,IAAA,YAAA,CAAa,WAAW,mBAAmB,CAAA;AAC3C,IAAA,YAAA,CAAa,OAAA,CAAQ,+BAA+B,GAAG,CAAA;AAAA,EACzD,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AAAE,MAAA,YAAA,CAAa,OAAA,CAAQ,+BAA+B,GAAG,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAC;AAAA,EAC3E;AACF","file":"chunk-5TU6DT3E.js","sourcesContent":["/**\n * Pomodoro store — module-level singleton that owns the timer state and\n * tick loop. Lifting the state above the widget means:\n *\n * 1. The taskbar indicator (`TaskbarPomodoro`) can subscribe even when\n * the widget itself is closed.\n * 2. The timer keeps running if the user closes / reopens the widget;\n * no progress is lost mid-session.\n *\n * The widget acts as a pure controller: it reads the snapshot via\n * `useSyncExternalStore` and calls the action functions below to drive\n * state transitions.\n *\n * The alarm sound on session-end is synthesised through the WebAudio API\n * (no audio file assets to bundle / license). All the presets are tuned\n * to be soft — gentle decay, low peak gain — so they don't startle. The\n * focus-time ambient sound (white / pink / brown noise) is synthesised\n * the same way and looped through an AudioBufferSourceNode.\n */\n\nimport toast from './toast';\n\nexport type Mode = 'focus' | 'short' | 'long';\nexport type AlarmSound = 'bell' | 'chime' | 'bowl' | 'wind-chimes' | 'off';\nexport type FocusSound =\n | 'none'\n | 'white' | 'pink' | 'brown'\n | 'tick-fast' | 'tick-slow'\n | 'rain' | 'fireplace';\n\nexport interface PomoDurations {\n /** Focus block, in seconds. */\n focus: number;\n /** Short break, in seconds. */\n short: number;\n /** Long break, in seconds. Triggered every Nth focus where N is\n * `longBreakInterval` from `setPomoBehaviour`. */\n long: number;\n}\n\nexport interface PomoBehaviour {\n /** When a focus block ends, automatically start the break. */\n autoStartBreaks: boolean;\n /** When a break ends, automatically start the next focus block. */\n autoStartPomodoros: boolean;\n /** Long break is taken after every Nth focus block. Default 4. */\n longBreakInterval: number;\n}\n\nexport interface PomoSnapshot {\n running: boolean;\n /** Seconds remaining in the current block. */\n remaining: number;\n mode: Mode;\n /** Seconds in the full current block — used for progress %. */\n total: number;\n /** Pomodoros completed since the page loaded. */\n streak: number;\n /** Today's lifetime count (persisted to localStorage). */\n count: number;\n}\n\nexport const ALARM_OPTIONS: { id: AlarmSound; label: string; description: string }[] = [\n { id: 'bell', label: 'Bell', description: 'Soft bell with one harmonic' },\n { id: 'chime', label: 'Chime', description: 'Two-note ascending chime' },\n { id: 'bowl', label: 'Singing Bowl', description: 'Long-decay meditation tone' },\n { id: 'wind-chimes', label: 'Wind Chimes', description: 'Four soft tones in succession' },\n { id: 'off', label: 'Off (silent)', description: 'No sound — only desktop notification' },\n];\n\nexport const FOCUS_SOUND_OPTIONS: { id: FocusSound; label: string }[] = [\n { id: 'none', label: 'None' },\n { id: 'tick-fast', label: 'Ticking Fast' },\n { id: 'tick-slow', label: 'Ticking Slow' },\n { id: 'rain', label: 'Rain' },\n { id: 'fireplace', label: 'Fireplace' },\n { id: 'white', label: 'White Noise' },\n { id: 'pink', label: 'Pink Noise' },\n { id: 'brown', label: 'Brown Noise' },\n];\n\nconst todayKey = () => `pomodoro-${new Date().toISOString().slice(0, 10)}`;\nconst loadCount = () => {\n try { return parseInt(localStorage.getItem(todayKey()) || '0', 10) || 0; } catch { return 0; }\n};\nconst saveCount = (n: number) => {\n try { localStorage.setItem(todayKey(), String(n)); } catch {}\n};\n\nlet _durations: PomoDurations = { focus: 25 * 60, short: 5 * 60, long: 15 * 60 };\nlet _alarm: AlarmSound = 'bell';\nlet _alarmVolume = 100; // 0–100\nlet _alarmRepeat = 1; // 1–5\nlet _focusSoundType: FocusSound = 'none';\nlet _focusVolume = 50; // 0–100\nlet _behaviour: PomoBehaviour = { autoStartBreaks: false, autoStartPomodoros: false, longBreakInterval: 4 };\n\nlet _state: PomoSnapshot = {\n running: false,\n remaining: _durations.focus,\n mode: 'focus',\n total: _durations.focus,\n streak: 0,\n count: typeof localStorage !== 'undefined' ? loadCount() : 0,\n};\n\nlet _intervalId: ReturnType<typeof setInterval> | null = null;\nconst _listeners = new Set<() => void>();\n\nconst _notify = () => _listeners.forEach(l => l());\nconst _set = (s: Partial<PomoSnapshot>) => { _state = { ..._state, ...s }; _notify(); };\n\nexport function getPomoSnapshot(): PomoSnapshot { return _state; }\nexport function subscribePomo(l: () => void) { _listeners.add(l); return () => { _listeners.delete(l); }; }\n\nexport function setPomoDurations(d: PomoDurations) {\n _durations = d;\n // If the user changed durations while not running and at the start of the\n // block, sync the visible time to the new value.\n if (!_state.running && _state.remaining === _state.total) {\n _set({ remaining: d[_state.mode], total: d[_state.mode] });\n }\n}\nexport function getPomoDurations(): PomoDurations { return _durations; }\n\nexport function setPomoAlarm(a: AlarmSound) { _alarm = a; }\nexport function getPomoAlarm(): AlarmSound { return _alarm; }\n\n/** Configure the alarm playback volume (0–100) and repeat count (1–5).\n * Used at session-end. The standalone `playAlarm()` preview button can\n * still pass overrides. */\nexport function setPomoAlarmConfig(volume: number, repeat: number) {\n _alarmVolume = Math.max(0, Math.min(100, Math.round(volume)));\n _alarmRepeat = Math.max(1, Math.min(5, Math.round(repeat)));\n}\nexport function getPomoAlarmConfig() { return { volume: _alarmVolume, repeat: _alarmRepeat }; }\n\nexport function setPomoBehaviour(b: PomoBehaviour) {\n _behaviour = {\n autoStartBreaks: !!b.autoStartBreaks,\n autoStartPomodoros: !!b.autoStartPomodoros,\n longBreakInterval: Math.max(1, Math.min(20, Math.round(b.longBreakInterval || 4))),\n };\n}\nexport function getPomoBehaviour(): PomoBehaviour { return _behaviour; }\n\n/** Configure the ambient focus-time sound. If a focus block is currently\n * running the audio is hot-swapped to the new settings. */\nexport function setPomoFocusSound(type: FocusSound, volume: number) {\n _focusSoundType = type;\n _focusVolume = Math.max(0, Math.min(100, Math.round(volume)));\n // Hot-swap if focus mode is currently running.\n if (_state.running && _state.mode === 'focus') {\n stopFocusAudio();\n startFocusAudio();\n } else if (type === 'none' || _focusVolume === 0) {\n stopFocusAudio();\n }\n}\nexport function getPomoFocusSound() { return { type: _focusSoundType, volume: _focusVolume }; }\n\nexport function pomoStart() {\n if (_state.running) return;\n _set({ running: true });\n _intervalId = setInterval(_tick, 1000);\n if (_state.mode === 'focus') startFocusAudio();\n}\nexport function pomoPause() {\n if (!_state.running && _intervalId === null) return;\n if (_intervalId !== null) { clearInterval(_intervalId); _intervalId = null; }\n _set({ running: false });\n stopFocusAudio();\n}\nexport function pomoReset() {\n pomoPause();\n _set({ remaining: _durations[_state.mode], total: _durations[_state.mode] });\n}\nexport function pomoSwitchMode(m: Mode) {\n pomoPause();\n _set({ mode: m, remaining: _durations[m], total: _durations[m] });\n}\n\nfunction _tick() {\n if (_state.remaining <= 1) {\n _onSessionEnd();\n return;\n }\n _set({ remaining: _state.remaining - 1 });\n}\n\nfunction _onSessionEnd() {\n if (_intervalId !== null) { clearInterval(_intervalId); _intervalId = null; }\n stopFocusAudio();\n playAlarm(_alarm, { volume: _alarmVolume, repeat: _alarmRepeat });\n\n // Notify the user three ways so they don't miss it:\n // 1. The alarm sound (already fired above).\n // 2. A native OS notification — fires even when the tab is in the\n // background, but only if the user granted permission.\n // 3. The in-app toast — guaranteed to render whenever the page is\n // open, regardless of OS permission state.\n const justFinishedFocus = _state.mode === 'focus';\n const headline = justFinishedFocus ? 'Pomodoro complete — time for a break! 🍅' : 'Break\\'s over — back to work!';\n if (typeof Notification !== 'undefined' && Notification.permission === 'granted') {\n try { new Notification(headline); } catch {}\n }\n try { toast.info(headline); } catch {}\n\n if (_state.mode === 'focus') {\n const nextStreak = _state.streak + 1;\n const newCount = _state.count + 1;\n saveCount(newCount);\n const nextMode: Mode = nextStreak % _behaviour.longBreakInterval === 0 ? 'long' : 'short';\n _set({\n running: false,\n streak: nextStreak,\n count: newCount,\n mode: nextMode,\n remaining: _durations[nextMode],\n total: _durations[nextMode],\n });\n if (_behaviour.autoStartBreaks) setTimeout(() => pomoStart(), 50);\n } else {\n _set({\n running: false,\n mode: 'focus',\n remaining: _durations.focus,\n total: _durations.focus,\n });\n if (_behaviour.autoStartPomodoros) setTimeout(() => pomoStart(), 50);\n }\n}\n\n/** Synthesise the chosen alarm via WebAudio. All presets are tuned soft —\n * exponential decay to near-silence, peak gain ≤ 0.22. The `volume`\n * option scales the peak (0-100). The `repeat` option plays the cue\n * several times with a 2.5 s gap between starts. */\nexport function playAlarm(kind: AlarmSound = _alarm, opts: { volume?: number; repeat?: number } = {}) {\n if (kind === 'off') return;\n const volScale = Math.max(0, Math.min(100, opts.volume ?? 100)) / 100;\n if (volScale === 0) return;\n const repeat = Math.max(1, Math.min(5, opts.repeat ?? 1));\n for (let i = 0; i < repeat; i++) {\n setTimeout(() => _playAlarmOnce(kind, volScale), i * 2500);\n }\n}\n\nfunction _playAlarmOnce(kind: AlarmSound, volScale: number) {\n try {\n const Ctor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!Ctor) return;\n const ctx = new Ctor();\n const playNote = (freq: number, start: number, duration: number, vol = 0.22, type: OscillatorType = 'sine') => {\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.connect(gain); gain.connect(ctx.destination);\n osc.type = type;\n osc.frequency.value = freq;\n const t0 = ctx.currentTime + start;\n gain.gain.setValueAtTime(0, t0);\n gain.gain.linearRampToValueAtTime(vol * volScale, t0 + 0.03);\n gain.gain.exponentialRampToValueAtTime(0.0001, t0 + duration);\n osc.start(t0);\n osc.stop(t0 + duration);\n };\n let totalDuration = 2;\n if (kind === 'bell') {\n playNote(880, 0, 1.8);\n playNote(1320, 0, 1.4, 0.10);\n totalDuration = 2;\n } else if (kind === 'chime') {\n playNote(659.25, 0, 0.7); // E5\n playNote(880, 0.20, 1.3); // A5\n totalDuration = 2;\n } else if (kind === 'bowl') {\n playNote(440, 0, 3.4, 0.22);\n playNote(660, 0, 3.0, 0.08);\n playNote(880, 0.05, 2.8, 0.05);\n totalDuration = 4;\n } else if (kind === 'wind-chimes') {\n playNote(1175, 0, 1.1, 0.16); // D6\n playNote(880, 0.15, 1.3, 0.16); // A5\n playNote(1318, 0.30, 1.5, 0.16); // E6\n playNote(1047, 0.50, 1.7, 0.13); // C6\n totalDuration = 3;\n }\n setTimeout(() => { try { ctx.close(); } catch {} }, totalDuration * 1000 + 500);\n } catch {}\n}\n\n// ── Ambient focus-time sound ──\nlet _focusAudio: { ctx: AudioContext; src: AudioBufferSourceNode; gain: GainNode } | null = null;\n\n/** Per-type volume cap. Sparse signals (ticking, fireplace pops) need a\n * higher gain to perceive at the same loudness as a continuous noise\n * texture. The user-facing slider always shows 0–100; this multiplier\n * is the headroom mapping. */\nconst FOCUS_VOL_CAP: Record<FocusSound, number> = {\n none: 0,\n white: 0.30,\n pink: 0.30,\n brown: 0.30,\n 'tick-fast': 0.60,\n 'tick-slow': 0.60,\n rain: 0.40,\n fireplace: 0.50,\n};\n\nfunction _makeNoiseBuffer(ctx: AudioContext, type: FocusSound): AudioBuffer | null {\n if (type === 'none') return null;\n const sr = ctx.sampleRate;\n // Noise textures use a 2 s loop. Ticking, rain, and fireplace use 4 s\n // so multiple ticks / pops fit in one cycle and the loop seam is masked\n // by the texture itself.\n const dur = (type === 'white' || type === 'pink' || type === 'brown') ? 2 : 4;\n const len = sr * dur;\n const buffer = ctx.createBuffer(1, len, sr);\n const data = buffer.getChannelData(0);\n\n if (type === 'white') {\n for (let i = 0; i < len; i++) data[i] = (Math.random() * 2 - 1) * 0.5;\n\n } else if (type === 'pink') {\n // Paul Kellet's filter — cheap pink-noise approximation.\n let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + w * 0.0555179;\n b1 = 0.99332 * b1 + w * 0.0750759;\n b2 = 0.96900 * b2 + w * 0.1538520;\n b3 = 0.86650 * b3 + w * 0.3104856;\n b4 = 0.55000 * b4 + w * 0.5329522;\n b5 = -0.7616 * b5 - w * 0.0168980;\n data[i] = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362) * 0.11 * 0.55;\n b6 = w * 0.115926;\n }\n\n } else if (type === 'brown') {\n // 1/f² — leaky integrator on white noise.\n let last = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n last = (last + 0.02 * w) / 1.02;\n data[i] = last * 3.5 * 0.5;\n }\n\n } else if (type === 'tick-fast' || type === 'tick-slow') {\n // Wall-clock tick: brief noise burst with a sharp exponential decay.\n // Two intervals are even divisors of the 4 s buffer, so the loop is\n // perfectly seamless.\n const intervalSec = type === 'tick-fast' ? 0.5 : 1.0;\n const tickSamples = Math.floor(sr * 0.045);\n for (let t = 0; t < dur; t += intervalSec) {\n const start = Math.floor(t * sr);\n for (let i = 0; i < tickSamples && start + i < len; i++) {\n const env = Math.exp(-i / sr * 180); // ~5 ms attack, ~25 ms decay tail\n const noise = Math.random() * 2 - 1;\n // Mix sharp click (filtered noise) with a faint sine to add body.\n const tone = Math.sin(2 * Math.PI * 1100 * (i / sr));\n data[start + i] += (noise * 0.7 + tone * 0.25) * env * 0.55;\n }\n }\n\n } else if (type === 'rain') {\n // High-pass filtered white noise (the \"patter\") plus a slow tremolo\n // for occasional gusts.\n let prev = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n const filtered = w - prev * 0.93; // high-pass\n prev = w;\n const gust = 0.7 + 0.3 * Math.sin((i / sr) * 2 * Math.PI * 0.25);\n data[i] = filtered * gust * 0.4;\n }\n\n } else if (type === 'fireplace') {\n // Brown-noise rumble underneath, plus randomly-spaced \"pops\" (short\n // noise transients with sharp decay) for the crackle.\n let last = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n last = (last + 0.02 * w) / 1.02;\n data[i] = last * 1.6;\n }\n let next = Math.random() * 0.4 * sr;\n while (next < len) {\n const popLen = Math.floor((0.012 + Math.random() * 0.05) * sr);\n const popVol = 0.35 + Math.random() * 0.45;\n const popPos = Math.floor(next);\n for (let i = 0; i < popLen && popPos + i < len; i++) {\n const env = Math.exp(-i / sr * 90);\n data[popPos + i] += (Math.random() * 2 - 1) * env * popVol;\n }\n // Next pop somewhere between 80 ms and 700 ms later.\n next += (0.08 + Math.random() * 0.62) * sr;\n }\n }\n\n return buffer;\n}\n\nfunction startFocusAudio() {\n if (_focusAudio) return;\n if (_focusSoundType === 'none' || _focusVolume === 0) return;\n try {\n const Ctor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!Ctor) return;\n const ctx = new Ctor();\n const buffer = _makeNoiseBuffer(ctx, _focusSoundType);\n if (!buffer) { try { ctx.close(); } catch {} return; }\n const src = ctx.createBufferSource();\n src.buffer = buffer;\n src.loop = true;\n const gain = ctx.createGain();\n gain.gain.value = (_focusVolume / 100) * FOCUS_VOL_CAP[_focusSoundType];\n src.connect(gain).connect(ctx.destination);\n src.start();\n _focusAudio = { ctx, src, gain };\n } catch {}\n}\n\nfunction stopFocusAudio() {\n if (!_focusAudio) return;\n try { _focusAudio.src.stop(); } catch {}\n try { _focusAudio.ctx.close(); } catch {}\n _focusAudio = null;\n}\n\n/** Play the configured ambient focus sound for ~3 s as a preview. Used by\n * the Settings UI when the user adjusts the dropdown / volume slider. */\nexport function previewFocusSound(type: FocusSound, volume: number) {\n if (type === 'none' || volume === 0) return;\n try {\n const Ctor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!Ctor) return;\n const ctx = new Ctor();\n const buffer = _makeNoiseBuffer(ctx, type);\n if (!buffer) { try { ctx.close(); } catch {} return; }\n const src = ctx.createBufferSource();\n src.buffer = buffer;\n src.loop = true;\n const gain = ctx.createGain();\n gain.gain.value = (volume / 100) * FOCUS_VOL_CAP[type];\n src.connect(gain).connect(ctx.destination);\n src.start();\n setTimeout(() => {\n try { src.stop(); } catch {}\n try { ctx.close(); } catch {}\n }, 3000);\n } catch {}\n}\n","/**\n * Shared task store for the Todo List app and the Pomodoro widget — both\n * read/write the same list via `useTodoTasks()`.\n *\n * Two backends:\n * • Default: `useShellPrefs()` → `prefs.todo_tasks` (per-user prefs blob).\n * • Opt-in: a consumer-supplied `TodoProvider` registered with\n * `setShellTodoProvider(...)`. When set, the three apps read/write through\n * it instead — letting an ERP make the shell's tasks the SAME records as\n * its own task table, and tag each with a `contextLabel` badge (e.g.\n * \"Deal: Acme\"). Mirrors `setShellApiClient`.\n *\n * `migratePomodoroTasksOnce()` folds legacy `localStorage.pomodoro_tasks`\n * into the prefs store on first Pomodoro mount (no-op in provider mode).\n */\nimport { useCallback, useMemo, useSyncExternalStore } from 'react';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport type { TodoTask } from './_todoTypes';\n\nconst POMODORO_LEGACY_KEY = 'pomodoro_tasks';\nconst POMODORO_LEGACY_MIGRATED_FLAG = 'pomodoro_tasks_migrated';\n\nfunction uid(): string {\n return Math.random().toString(36).slice(2, 11);\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport interface UseTodoTasks {\n tasks: TodoTask[];\n /** Add a new task. Returns the id of the freshly-added task. */\n addTask: (input: Partial<Omit<TodoTask, 'id' | 'createdAt' | 'updatedAt'>> & { name: string }) => string;\n /** Patch any subset of fields on a task by id. `updatedAt` is auto-bumped. */\n updateTask: (id: string, patch: Partial<TodoTask>) => void;\n /** Remove a task by id. Used by both Pomodoro's kebab menu and TodoList's delete action. */\n removeTask: (id: string) => void;\n /** Flip `done`. Same as `updateTask(id, { done: !done })` but faster to type at call sites. */\n toggleDone: (id: string) => void;\n /** Replace the entire list. Used by Google Tasks sync after a pull. */\n setAllTasks: (tasks: TodoTask[]) => void;\n}\n\n/**\n * A consumer-supplied task backend. Registering one (opt-in) routes every\n * shell task surface through it instead of the prefs blob. Methods map to/from\n * the shell's `TodoTask` shape, including the optional `source`/`contextLabel`.\n */\nexport interface TodoProvider {\n list(): Promise<TodoTask[]>;\n create(input: Partial<Omit<TodoTask, 'id' | 'createdAt' | 'updatedAt'>> & { name: string }): Promise<TodoTask>;\n update(id: string, patch: Partial<TodoTask>): Promise<TodoTask>;\n remove(id: string): Promise<void>;\n}\n\n// ── Module-level provider store (shared across all consumers) ──\nlet provider: TodoProvider | null = null;\nlet cache: TodoTask[] = [];\nlet loaded = false;\nlet inflight: Promise<void> | null = null;\nconst listeners = new Set<() => void>();\n\nfunction emit(): void {\n for (const l of listeners) l();\n}\n\nfunction setCache(next: TodoTask[]): void {\n cache = next;\n emit();\n}\n\nfunction refresh(): Promise<void> {\n const p = provider;\n if (!p) {\n cache = [];\n loaded = true;\n emit();\n return Promise.resolve();\n }\n inflight = p\n .list()\n .then(rows => {\n if (provider === p) {\n cache = rows;\n loaded = true;\n emit();\n }\n })\n .catch(() => {\n if (provider === p) {\n loaded = true;\n emit();\n }\n })\n .finally(() => {\n inflight = null;\n });\n return inflight;\n}\n\n/** Register (or clear with `null`) the backend task provider. Opt-in. */\nexport function setShellTodoProvider(next: TodoProvider | null): void {\n provider = next;\n cache = [];\n loaded = false;\n if (next) refresh();\n else emit();\n}\n\nexport function hasShellTodoProvider(): boolean {\n return provider !== null;\n}\n\nfunction subscribe(cb: () => void): () => void {\n listeners.add(cb);\n if (provider && !loaded && !inflight) refresh();\n return () => {\n listeners.delete(cb);\n };\n}\n\nfunction getSnapshot(): TodoTask[] {\n return cache;\n}\n\n// ── Prefs-backed implementation (default / fallback) ──\nfunction usePrefsTodoTasks(): UseTodoTasks {\n const { prefs, save } = useShellPrefs();\n const tasks: TodoTask[] = useMemo(() => {\n const raw = prefs.todo_tasks;\n return Array.isArray(raw) ? (raw as TodoTask[]) : [];\n }, [prefs.todo_tasks]);\n\n const writeTasks = useCallback((next: TodoTask[]) => {\n save({ todo_tasks: next });\n }, [save]);\n\n const addTask = useCallback<UseTodoTasks['addTask']>((input) => {\n const id = uid();\n const ts = nowIso();\n const task: TodoTask = { done: false, ...input, name: input.name.trim(), id, createdAt: ts, updatedAt: ts };\n writeTasks([...tasks, task]);\n return id;\n }, [tasks, writeTasks]);\n\n const updateTask = useCallback<UseTodoTasks['updateTask']>((id, patch) => {\n writeTasks(tasks.map(t => (t.id === id ? { ...t, ...patch, id: t.id, updatedAt: nowIso() } : t)));\n }, [tasks, writeTasks]);\n\n const removeTask = useCallback<UseTodoTasks['removeTask']>((id) => {\n writeTasks(tasks.filter(t => t.id !== id));\n }, [tasks, writeTasks]);\n\n const toggleDone = useCallback<UseTodoTasks['toggleDone']>((id) => {\n const target = tasks.find(t => t.id === id);\n if (target) updateTask(id, { done: !target.done });\n }, [tasks, updateTask]);\n\n return { tasks, addTask, updateTask, removeTask, toggleDone, setAllTasks: writeTasks };\n}\n\n// ── Public hook (provider-aware) ──\nexport function useTodoTasks(): UseTodoTasks {\n // Both hooks always run (rules of hooks); the active impl is chosen below.\n const prefsImpl = usePrefsTodoTasks();\n const providerTasks = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n const addTask = useCallback<UseTodoTasks['addTask']>((input) => {\n const p = provider;\n if (!p) return prefsImpl.addTask(input);\n const tempId = 'tmp-' + uid();\n const ts = nowIso();\n const optimistic: TodoTask = { done: false, ...input, name: input.name.trim(), id: tempId, createdAt: ts, updatedAt: ts };\n setCache([...cache, optimistic]);\n p.create({ ...input, name: input.name.trim() })\n // Merge so server-owned fields win but client-only fields (estimated/\n // completed/notes the backend may not persist) survive the round-trip.\n .then(saved => setCache(cache.map(t => (t.id === tempId ? { ...optimistic, ...saved } : t))))\n .catch(() => setCache(cache.filter(t => t.id !== tempId)));\n return tempId;\n }, [prefsImpl]);\n\n const updateTask = useCallback<UseTodoTasks['updateTask']>((id, patch) => {\n const p = provider;\n if (!p) return prefsImpl.updateTask(id, patch);\n setCache(cache.map(t => (t.id === id ? { ...t, ...patch, id, updatedAt: nowIso() } : t)));\n p.update(id, patch).catch(() => { refresh(); });\n }, [prefsImpl]);\n\n const removeTask = useCallback<UseTodoTasks['removeTask']>((id) => {\n const p = provider;\n if (!p) return prefsImpl.removeTask(id);\n const prev = cache;\n setCache(cache.filter(t => t.id !== id));\n p.remove(id).catch(() => setCache(prev));\n }, [prefsImpl]);\n\n const toggleDone = useCallback<UseTodoTasks['toggleDone']>((id) => {\n if (!provider) return prefsImpl.toggleDone(id);\n const target = cache.find(t => t.id === id);\n if (target) updateTask(id, { done: !target.done });\n }, [prefsImpl, updateTask]);\n\n const setAllTasks = useCallback<UseTodoTasks['setAllTasks']>((next) => {\n // Provider owns persistence — bulk replace (Google Tasks sync) is a no-op there.\n if (!provider) prefsImpl.setAllTasks(next);\n }, [prefsImpl]);\n\n if (!hasShellTodoProvider()) return prefsImpl;\n return { tasks: providerTasks, addTask, updateTask, removeTask, toggleDone, setAllTasks };\n}\n\n/**\n * One-time migration: pull any tasks the Pomodoro widget previously\n * persisted to `localStorage.pomodoro_tasks` into the shared store.\n * No-op when a provider is registered (the provider owns persistence).\n */\nexport function migratePomodoroTasksOnce(\n currentTasks: TodoTask[],\n setAllTasks: (next: TodoTask[]) => void,\n): void {\n try {\n if (localStorage.getItem(POMODORO_LEGACY_MIGRATED_FLAG)) return;\n const raw = localStorage.getItem(POMODORO_LEGACY_KEY);\n if (!raw) {\n localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1');\n return;\n }\n const legacy: Array<{ id?: string; name?: string; estimated?: number; completed?: number; done?: boolean }>\n = JSON.parse(raw);\n if (!Array.isArray(legacy) || legacy.length === 0) {\n localStorage.removeItem(POMODORO_LEGACY_KEY);\n localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1');\n return;\n }\n const ts = nowIso();\n const migrated: TodoTask[] = legacy\n .filter(t => typeof t?.name === 'string')\n .map(t => ({\n id: t.id || uid(),\n name: String(t.name),\n done: !!t.done,\n estimated: typeof t.estimated === 'number' ? t.estimated : undefined,\n completed: typeof t.completed === 'number' ? t.completed : undefined,\n createdAt: ts,\n updatedAt: ts,\n }));\n const existingIds = new Set(currentTasks.map(t => t.id));\n const additions = migrated.filter(t => !existingIds.has(t.id));\n setAllTasks([...additions, ...currentTasks]);\n localStorage.removeItem(POMODORO_LEGACY_KEY);\n localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1');\n } catch {\n try { localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1'); } catch {}\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/shell/pomodoroStore.ts","../src/apps/_todoStore.ts"],"names":[],"mappings":"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","file":"chunk-YF2XNVGN.js","sourcesContent":["/**\n * Pomodoro store — module-level singleton that owns the timer state and\n * tick loop. Lifting the state above the widget means:\n *\n * 1. The taskbar indicator (`TaskbarPomodoro`) can subscribe even when\n * the widget itself is closed.\n * 2. The timer keeps running if the user closes / reopens the widget;\n * no progress is lost mid-session.\n *\n * The widget acts as a pure controller: it reads the snapshot via\n * `useSyncExternalStore` and calls the action functions below to drive\n * state transitions.\n *\n * The alarm sound on session-end is synthesised through the WebAudio API\n * (no audio file assets to bundle / license). All the presets are tuned\n * to be soft — gentle decay, low peak gain — so they don't startle. The\n * focus-time ambient sound (white / pink / brown noise) is synthesised\n * the same way and looped through an AudioBufferSourceNode.\n */\n\nimport toast from './toast';\n\nexport type Mode = 'focus' | 'short' | 'long';\nexport type AlarmSound = 'bell' | 'chime' | 'bowl' | 'wind-chimes' | 'off';\nexport type FocusSound =\n | 'none'\n | 'white' | 'pink' | 'brown'\n | 'tick-fast' | 'tick-slow'\n | 'rain' | 'fireplace';\n\nexport interface PomoDurations {\n /** Focus block, in seconds. */\n focus: number;\n /** Short break, in seconds. */\n short: number;\n /** Long break, in seconds. Triggered every Nth focus where N is\n * `longBreakInterval` from `setPomoBehaviour`. */\n long: number;\n}\n\nexport interface PomoBehaviour {\n /** When a focus block ends, automatically start the break. */\n autoStartBreaks: boolean;\n /** When a break ends, automatically start the next focus block. */\n autoStartPomodoros: boolean;\n /** Long break is taken after every Nth focus block. Default 4. */\n longBreakInterval: number;\n}\n\nexport interface PomoSnapshot {\n running: boolean;\n /** Seconds remaining in the current block. */\n remaining: number;\n mode: Mode;\n /** Seconds in the full current block — used for progress %. */\n total: number;\n /** Pomodoros completed since the page loaded. */\n streak: number;\n /** Today's lifetime count (persisted to localStorage). */\n count: number;\n}\n\nexport const ALARM_OPTIONS: { id: AlarmSound; label: string; description: string }[] = [\n { id: 'bell', label: 'Bell', description: 'Soft bell with one harmonic' },\n { id: 'chime', label: 'Chime', description: 'Two-note ascending chime' },\n { id: 'bowl', label: 'Singing Bowl', description: 'Long-decay meditation tone' },\n { id: 'wind-chimes', label: 'Wind Chimes', description: 'Four soft tones in succession' },\n { id: 'off', label: 'Off (silent)', description: 'No sound — only desktop notification' },\n];\n\nexport const FOCUS_SOUND_OPTIONS: { id: FocusSound; label: string }[] = [\n { id: 'none', label: 'None' },\n { id: 'tick-fast', label: 'Ticking Fast' },\n { id: 'tick-slow', label: 'Ticking Slow' },\n { id: 'rain', label: 'Rain' },\n { id: 'fireplace', label: 'Fireplace' },\n { id: 'white', label: 'White Noise' },\n { id: 'pink', label: 'Pink Noise' },\n { id: 'brown', label: 'Brown Noise' },\n];\n\nconst todayKey = () => `pomodoro-${new Date().toISOString().slice(0, 10)}`;\nconst loadCount = () => {\n try { return parseInt(localStorage.getItem(todayKey()) || '0', 10) || 0; } catch { return 0; }\n};\nconst saveCount = (n: number) => {\n try { localStorage.setItem(todayKey(), String(n)); } catch {}\n};\n\nlet _durations: PomoDurations = { focus: 25 * 60, short: 5 * 60, long: 15 * 60 };\nlet _alarm: AlarmSound = 'bell';\nlet _alarmVolume = 100; // 0–100\nlet _alarmRepeat = 1; // 1–5\nlet _focusSoundType: FocusSound = 'none';\nlet _focusVolume = 50; // 0–100\nlet _behaviour: PomoBehaviour = { autoStartBreaks: false, autoStartPomodoros: false, longBreakInterval: 4 };\n\nlet _state: PomoSnapshot = {\n running: false,\n remaining: _durations.focus,\n mode: 'focus',\n total: _durations.focus,\n streak: 0,\n count: typeof localStorage !== 'undefined' ? loadCount() : 0,\n};\n\nlet _intervalId: ReturnType<typeof setInterval> | null = null;\nconst _listeners = new Set<() => void>();\n\nconst _notify = () => _listeners.forEach(l => l());\nconst _set = (s: Partial<PomoSnapshot>) => { _state = { ..._state, ...s }; _notify(); };\n\nexport function getPomoSnapshot(): PomoSnapshot { return _state; }\nexport function subscribePomo(l: () => void) { _listeners.add(l); return () => { _listeners.delete(l); }; }\n\nexport function setPomoDurations(d: PomoDurations) {\n _durations = d;\n // If the user changed durations while not running and at the start of the\n // block, sync the visible time to the new value.\n if (!_state.running && _state.remaining === _state.total) {\n _set({ remaining: d[_state.mode], total: d[_state.mode] });\n }\n}\nexport function getPomoDurations(): PomoDurations { return _durations; }\n\nexport function setPomoAlarm(a: AlarmSound) { _alarm = a; }\nexport function getPomoAlarm(): AlarmSound { return _alarm; }\n\n/** Configure the alarm playback volume (0–100) and repeat count (1–5).\n * Used at session-end. The standalone `playAlarm()` preview button can\n * still pass overrides. */\nexport function setPomoAlarmConfig(volume: number, repeat: number) {\n _alarmVolume = Math.max(0, Math.min(100, Math.round(volume)));\n _alarmRepeat = Math.max(1, Math.min(5, Math.round(repeat)));\n}\nexport function getPomoAlarmConfig() { return { volume: _alarmVolume, repeat: _alarmRepeat }; }\n\nexport function setPomoBehaviour(b: PomoBehaviour) {\n _behaviour = {\n autoStartBreaks: !!b.autoStartBreaks,\n autoStartPomodoros: !!b.autoStartPomodoros,\n longBreakInterval: Math.max(1, Math.min(20, Math.round(b.longBreakInterval || 4))),\n };\n}\nexport function getPomoBehaviour(): PomoBehaviour { return _behaviour; }\n\n/** Configure the ambient focus-time sound. If a focus block is currently\n * running the audio is hot-swapped to the new settings. */\nexport function setPomoFocusSound(type: FocusSound, volume: number) {\n _focusSoundType = type;\n _focusVolume = Math.max(0, Math.min(100, Math.round(volume)));\n // Hot-swap if focus mode is currently running.\n if (_state.running && _state.mode === 'focus') {\n stopFocusAudio();\n startFocusAudio();\n } else if (type === 'none' || _focusVolume === 0) {\n stopFocusAudio();\n }\n}\nexport function getPomoFocusSound() { return { type: _focusSoundType, volume: _focusVolume }; }\n\nexport function pomoStart() {\n if (_state.running) return;\n _set({ running: true });\n _intervalId = setInterval(_tick, 1000);\n if (_state.mode === 'focus') startFocusAudio();\n}\nexport function pomoPause() {\n if (!_state.running && _intervalId === null) return;\n if (_intervalId !== null) { clearInterval(_intervalId); _intervalId = null; }\n _set({ running: false });\n stopFocusAudio();\n}\nexport function pomoReset() {\n pomoPause();\n _set({ remaining: _durations[_state.mode], total: _durations[_state.mode] });\n}\nexport function pomoSwitchMode(m: Mode) {\n pomoPause();\n _set({ mode: m, remaining: _durations[m], total: _durations[m] });\n}\n\nfunction _tick() {\n if (_state.remaining <= 1) {\n _onSessionEnd();\n return;\n }\n _set({ remaining: _state.remaining - 1 });\n}\n\nfunction _onSessionEnd() {\n if (_intervalId !== null) { clearInterval(_intervalId); _intervalId = null; }\n stopFocusAudio();\n playAlarm(_alarm, { volume: _alarmVolume, repeat: _alarmRepeat });\n\n // Notify the user three ways so they don't miss it:\n // 1. The alarm sound (already fired above).\n // 2. A native OS notification — fires even when the tab is in the\n // background, but only if the user granted permission.\n // 3. The in-app toast — guaranteed to render whenever the page is\n // open, regardless of OS permission state.\n const justFinishedFocus = _state.mode === 'focus';\n const headline = justFinishedFocus ? 'Pomodoro complete — time for a break! 🍅' : 'Break\\'s over — back to work!';\n if (typeof Notification !== 'undefined' && Notification.permission === 'granted') {\n try { new Notification(headline); } catch {}\n }\n try { toast.info(headline); } catch {}\n\n if (_state.mode === 'focus') {\n const nextStreak = _state.streak + 1;\n const newCount = _state.count + 1;\n saveCount(newCount);\n const nextMode: Mode = nextStreak % _behaviour.longBreakInterval === 0 ? 'long' : 'short';\n _set({\n running: false,\n streak: nextStreak,\n count: newCount,\n mode: nextMode,\n remaining: _durations[nextMode],\n total: _durations[nextMode],\n });\n if (_behaviour.autoStartBreaks) setTimeout(() => pomoStart(), 50);\n } else {\n _set({\n running: false,\n mode: 'focus',\n remaining: _durations.focus,\n total: _durations.focus,\n });\n if (_behaviour.autoStartPomodoros) setTimeout(() => pomoStart(), 50);\n }\n}\n\n/** Synthesise the chosen alarm via WebAudio. All presets are tuned soft —\n * exponential decay to near-silence, peak gain ≤ 0.22. The `volume`\n * option scales the peak (0-100). The `repeat` option plays the cue\n * several times with a 2.5 s gap between starts. */\nexport function playAlarm(kind: AlarmSound = _alarm, opts: { volume?: number; repeat?: number } = {}) {\n if (kind === 'off') return;\n const volScale = Math.max(0, Math.min(100, opts.volume ?? 100)) / 100;\n if (volScale === 0) return;\n const repeat = Math.max(1, Math.min(5, opts.repeat ?? 1));\n for (let i = 0; i < repeat; i++) {\n setTimeout(() => _playAlarmOnce(kind, volScale), i * 2500);\n }\n}\n\nfunction _playAlarmOnce(kind: AlarmSound, volScale: number) {\n try {\n const Ctor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!Ctor) return;\n const ctx = new Ctor();\n const playNote = (freq: number, start: number, duration: number, vol = 0.22, type: OscillatorType = 'sine') => {\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.connect(gain); gain.connect(ctx.destination);\n osc.type = type;\n osc.frequency.value = freq;\n const t0 = ctx.currentTime + start;\n gain.gain.setValueAtTime(0, t0);\n gain.gain.linearRampToValueAtTime(vol * volScale, t0 + 0.03);\n gain.gain.exponentialRampToValueAtTime(0.0001, t0 + duration);\n osc.start(t0);\n osc.stop(t0 + duration);\n };\n let totalDuration = 2;\n if (kind === 'bell') {\n playNote(880, 0, 1.8);\n playNote(1320, 0, 1.4, 0.10);\n totalDuration = 2;\n } else if (kind === 'chime') {\n playNote(659.25, 0, 0.7); // E5\n playNote(880, 0.20, 1.3); // A5\n totalDuration = 2;\n } else if (kind === 'bowl') {\n playNote(440, 0, 3.4, 0.22);\n playNote(660, 0, 3.0, 0.08);\n playNote(880, 0.05, 2.8, 0.05);\n totalDuration = 4;\n } else if (kind === 'wind-chimes') {\n playNote(1175, 0, 1.1, 0.16); // D6\n playNote(880, 0.15, 1.3, 0.16); // A5\n playNote(1318, 0.30, 1.5, 0.16); // E6\n playNote(1047, 0.50, 1.7, 0.13); // C6\n totalDuration = 3;\n }\n setTimeout(() => { try { ctx.close(); } catch {} }, totalDuration * 1000 + 500);\n } catch {}\n}\n\n// ── Ambient focus-time sound ──\nlet _focusAudio: { ctx: AudioContext; src: AudioBufferSourceNode; gain: GainNode } | null = null;\n\n/** Per-type volume cap. Sparse signals (ticking, fireplace pops) need a\n * higher gain to perceive at the same loudness as a continuous noise\n * texture. The user-facing slider always shows 0–100; this multiplier\n * is the headroom mapping. */\nconst FOCUS_VOL_CAP: Record<FocusSound, number> = {\n none: 0,\n white: 0.30,\n pink: 0.30,\n brown: 0.30,\n 'tick-fast': 0.60,\n 'tick-slow': 0.60,\n rain: 0.40,\n fireplace: 0.50,\n};\n\nfunction _makeNoiseBuffer(ctx: AudioContext, type: FocusSound): AudioBuffer | null {\n if (type === 'none') return null;\n const sr = ctx.sampleRate;\n // Noise textures use a 2 s loop. Ticking, rain, and fireplace use 4 s\n // so multiple ticks / pops fit in one cycle and the loop seam is masked\n // by the texture itself.\n const dur = (type === 'white' || type === 'pink' || type === 'brown') ? 2 : 4;\n const len = sr * dur;\n const buffer = ctx.createBuffer(1, len, sr);\n const data = buffer.getChannelData(0);\n\n if (type === 'white') {\n for (let i = 0; i < len; i++) data[i] = (Math.random() * 2 - 1) * 0.5;\n\n } else if (type === 'pink') {\n // Paul Kellet's filter — cheap pink-noise approximation.\n let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + w * 0.0555179;\n b1 = 0.99332 * b1 + w * 0.0750759;\n b2 = 0.96900 * b2 + w * 0.1538520;\n b3 = 0.86650 * b3 + w * 0.3104856;\n b4 = 0.55000 * b4 + w * 0.5329522;\n b5 = -0.7616 * b5 - w * 0.0168980;\n data[i] = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362) * 0.11 * 0.55;\n b6 = w * 0.115926;\n }\n\n } else if (type === 'brown') {\n // 1/f² — leaky integrator on white noise.\n let last = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n last = (last + 0.02 * w) / 1.02;\n data[i] = last * 3.5 * 0.5;\n }\n\n } else if (type === 'tick-fast' || type === 'tick-slow') {\n // Wall-clock tick: brief noise burst with a sharp exponential decay.\n // Two intervals are even divisors of the 4 s buffer, so the loop is\n // perfectly seamless.\n const intervalSec = type === 'tick-fast' ? 0.5 : 1.0;\n const tickSamples = Math.floor(sr * 0.045);\n for (let t = 0; t < dur; t += intervalSec) {\n const start = Math.floor(t * sr);\n for (let i = 0; i < tickSamples && start + i < len; i++) {\n const env = Math.exp(-i / sr * 180); // ~5 ms attack, ~25 ms decay tail\n const noise = Math.random() * 2 - 1;\n // Mix sharp click (filtered noise) with a faint sine to add body.\n const tone = Math.sin(2 * Math.PI * 1100 * (i / sr));\n data[start + i] += (noise * 0.7 + tone * 0.25) * env * 0.55;\n }\n }\n\n } else if (type === 'rain') {\n // High-pass filtered white noise (the \"patter\") plus a slow tremolo\n // for occasional gusts.\n let prev = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n const filtered = w - prev * 0.93; // high-pass\n prev = w;\n const gust = 0.7 + 0.3 * Math.sin((i / sr) * 2 * Math.PI * 0.25);\n data[i] = filtered * gust * 0.4;\n }\n\n } else if (type === 'fireplace') {\n // Brown-noise rumble underneath, plus randomly-spaced \"pops\" (short\n // noise transients with sharp decay) for the crackle.\n let last = 0;\n for (let i = 0; i < len; i++) {\n const w = Math.random() * 2 - 1;\n last = (last + 0.02 * w) / 1.02;\n data[i] = last * 1.6;\n }\n let next = Math.random() * 0.4 * sr;\n while (next < len) {\n const popLen = Math.floor((0.012 + Math.random() * 0.05) * sr);\n const popVol = 0.35 + Math.random() * 0.45;\n const popPos = Math.floor(next);\n for (let i = 0; i < popLen && popPos + i < len; i++) {\n const env = Math.exp(-i / sr * 90);\n data[popPos + i] += (Math.random() * 2 - 1) * env * popVol;\n }\n // Next pop somewhere between 80 ms and 700 ms later.\n next += (0.08 + Math.random() * 0.62) * sr;\n }\n }\n\n return buffer;\n}\n\nfunction startFocusAudio() {\n if (_focusAudio) return;\n if (_focusSoundType === 'none' || _focusVolume === 0) return;\n try {\n const Ctor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!Ctor) return;\n const ctx = new Ctor();\n const buffer = _makeNoiseBuffer(ctx, _focusSoundType);\n if (!buffer) { try { ctx.close(); } catch {} return; }\n const src = ctx.createBufferSource();\n src.buffer = buffer;\n src.loop = true;\n const gain = ctx.createGain();\n gain.gain.value = (_focusVolume / 100) * FOCUS_VOL_CAP[_focusSoundType];\n src.connect(gain).connect(ctx.destination);\n src.start();\n _focusAudio = { ctx, src, gain };\n } catch {}\n}\n\nfunction stopFocusAudio() {\n if (!_focusAudio) return;\n try { _focusAudio.src.stop(); } catch {}\n try { _focusAudio.ctx.close(); } catch {}\n _focusAudio = null;\n}\n\n/** Play the configured ambient focus sound for ~3 s as a preview. Used by\n * the Settings UI when the user adjusts the dropdown / volume slider. */\nexport function previewFocusSound(type: FocusSound, volume: number) {\n if (type === 'none' || volume === 0) return;\n try {\n const Ctor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;\n if (!Ctor) return;\n const ctx = new Ctor();\n const buffer = _makeNoiseBuffer(ctx, type);\n if (!buffer) { try { ctx.close(); } catch {} return; }\n const src = ctx.createBufferSource();\n src.buffer = buffer;\n src.loop = true;\n const gain = ctx.createGain();\n gain.gain.value = (volume / 100) * FOCUS_VOL_CAP[type];\n src.connect(gain).connect(ctx.destination);\n src.start();\n setTimeout(() => {\n try { src.stop(); } catch {}\n try { ctx.close(); } catch {}\n }, 3000);\n } catch {}\n}\n","/**\n * Shared task store for the Todo List app and the Pomodoro widget — both\n * read/write the same list via `useTodoTasks()`.\n *\n * Two backends:\n * • Default: `useShellPrefs()` → `prefs.todo_tasks` (per-user prefs blob).\n * • Opt-in: a consumer-supplied `TodoProvider` registered with\n * `setShellTodoProvider(...)`. When set, the three apps read/write through\n * it instead — letting an ERP make the shell's tasks the SAME records as\n * its own task table, and tag each with a `contextLabel` badge (e.g.\n * \"Deal: Acme\"). Mirrors `setShellApiClient`.\n *\n * `migratePomodoroTasksOnce()` folds legacy `localStorage.pomodoro_tasks`\n * into the prefs store on first Pomodoro mount (no-op in provider mode).\n */\nimport { useCallback, useMemo, useSyncExternalStore } from 'react';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport type { TodoTask } from './_todoTypes';\n\nconst POMODORO_LEGACY_KEY = 'pomodoro_tasks';\nconst POMODORO_LEGACY_MIGRATED_FLAG = 'pomodoro_tasks_migrated';\n\nfunction uid(): string {\n return Math.random().toString(36).slice(2, 11);\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nexport interface UseTodoTasks {\n tasks: TodoTask[];\n /** Add a new task. Returns the id of the freshly-added task. */\n addTask: (input: Partial<Omit<TodoTask, 'id' | 'createdAt' | 'updatedAt'>> & { name: string }) => string;\n /** Patch any subset of fields on a task by id. `updatedAt` is auto-bumped. */\n updateTask: (id: string, patch: Partial<TodoTask>) => void;\n /** Remove a task by id. Used by both Pomodoro's kebab menu and TodoList's delete action. */\n removeTask: (id: string) => void;\n /** Flip `done`. Same as `updateTask(id, { done: !done })` but faster to type at call sites. */\n toggleDone: (id: string) => void;\n /** Replace the entire list. Used by Google Tasks sync after a pull. */\n setAllTasks: (tasks: TodoTask[]) => void;\n}\n\n/**\n * A consumer-supplied task backend. Registering one (opt-in) routes every\n * shell task surface through it instead of the prefs blob. Methods map to/from\n * the shell's `TodoTask` shape, including the optional `source`/`contextLabel`.\n */\nexport interface TodoProvider {\n list(): Promise<TodoTask[]>;\n create(input: Partial<Omit<TodoTask, 'id' | 'createdAt' | 'updatedAt'>> & { name: string }): Promise<TodoTask>;\n update(id: string, patch: Partial<TodoTask>): Promise<TodoTask>;\n remove(id: string): Promise<void>;\n}\n\n// ── Module-level provider store (shared across all consumers) ──\nlet provider: TodoProvider | null = null;\nlet cache: TodoTask[] = [];\nlet loaded = false;\nlet inflight: Promise<void> | null = null;\nconst listeners = new Set<() => void>();\n\nfunction emit(): void {\n for (const l of listeners) l();\n}\n\nfunction setCache(next: TodoTask[]): void {\n cache = next;\n emit();\n}\n\nfunction refresh(): Promise<void> {\n const p = provider;\n if (!p) {\n cache = [];\n loaded = true;\n emit();\n return Promise.resolve();\n }\n inflight = p\n .list()\n .then(rows => {\n if (provider === p) {\n cache = rows;\n loaded = true;\n emit();\n }\n })\n .catch(() => {\n if (provider === p) {\n loaded = true;\n emit();\n }\n })\n .finally(() => {\n inflight = null;\n });\n return inflight;\n}\n\n/** Register (or clear with `null`) the backend task provider. Opt-in. */\nexport function setShellTodoProvider(next: TodoProvider | null): void {\n provider = next;\n cache = [];\n loaded = false;\n if (next) refresh();\n else emit();\n}\n\nexport function hasShellTodoProvider(): boolean {\n return provider !== null;\n}\n\nfunction subscribe(cb: () => void): () => void {\n listeners.add(cb);\n if (provider && !loaded && !inflight) refresh();\n return () => {\n listeners.delete(cb);\n };\n}\n\nfunction getSnapshot(): TodoTask[] {\n return cache;\n}\n\n// ── Prefs-backed implementation (default / fallback) ──\nfunction usePrefsTodoTasks(): UseTodoTasks {\n const { prefs, save } = useShellPrefs();\n const tasks: TodoTask[] = useMemo(() => {\n const raw = prefs.todo_tasks;\n return Array.isArray(raw) ? (raw as TodoTask[]) : [];\n }, [prefs.todo_tasks]);\n\n const writeTasks = useCallback((next: TodoTask[]) => {\n save({ todo_tasks: next });\n }, [save]);\n\n const addTask = useCallback<UseTodoTasks['addTask']>((input) => {\n const id = uid();\n const ts = nowIso();\n const task: TodoTask = { done: false, ...input, name: input.name.trim(), id, createdAt: ts, updatedAt: ts };\n writeTasks([...tasks, task]);\n return id;\n }, [tasks, writeTasks]);\n\n const updateTask = useCallback<UseTodoTasks['updateTask']>((id, patch) => {\n writeTasks(tasks.map(t => (t.id === id ? { ...t, ...patch, id: t.id, updatedAt: nowIso() } : t)));\n }, [tasks, writeTasks]);\n\n const removeTask = useCallback<UseTodoTasks['removeTask']>((id) => {\n writeTasks(tasks.filter(t => t.id !== id));\n }, [tasks, writeTasks]);\n\n const toggleDone = useCallback<UseTodoTasks['toggleDone']>((id) => {\n const target = tasks.find(t => t.id === id);\n if (target) updateTask(id, { done: !target.done });\n }, [tasks, updateTask]);\n\n return { tasks, addTask, updateTask, removeTask, toggleDone, setAllTasks: writeTasks };\n}\n\n// ── Public hook (provider-aware) ──\nexport function useTodoTasks(): UseTodoTasks {\n // Both hooks always run (rules of hooks); the active impl is chosen below.\n const prefsImpl = usePrefsTodoTasks();\n const providerTasks = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n const addTask = useCallback<UseTodoTasks['addTask']>((input) => {\n const p = provider;\n if (!p) return prefsImpl.addTask(input);\n const tempId = 'tmp-' + uid();\n const ts = nowIso();\n const optimistic: TodoTask = { done: false, ...input, name: input.name.trim(), id: tempId, createdAt: ts, updatedAt: ts };\n setCache([...cache, optimistic]);\n p.create({ ...input, name: input.name.trim() })\n // Merge so server-owned fields win but client-only fields (estimated/\n // completed/notes the backend may not persist) survive the round-trip.\n .then(saved => setCache(cache.map(t => (t.id === tempId ? { ...optimistic, ...saved } : t))))\n .catch(() => setCache(cache.filter(t => t.id !== tempId)));\n return tempId;\n }, [prefsImpl]);\n\n const updateTask = useCallback<UseTodoTasks['updateTask']>((id, patch) => {\n const p = provider;\n if (!p) return prefsImpl.updateTask(id, patch);\n setCache(cache.map(t => (t.id === id ? { ...t, ...patch, id, updatedAt: nowIso() } : t)));\n p.update(id, patch).catch(() => { refresh(); });\n }, [prefsImpl]);\n\n const removeTask = useCallback<UseTodoTasks['removeTask']>((id) => {\n const p = provider;\n if (!p) return prefsImpl.removeTask(id);\n const prev = cache;\n setCache(cache.filter(t => t.id !== id));\n p.remove(id).catch(() => setCache(prev));\n }, [prefsImpl]);\n\n const toggleDone = useCallback<UseTodoTasks['toggleDone']>((id) => {\n if (!provider) return prefsImpl.toggleDone(id);\n const target = cache.find(t => t.id === id);\n if (target) updateTask(id, { done: !target.done });\n }, [prefsImpl, updateTask]);\n\n const setAllTasks = useCallback<UseTodoTasks['setAllTasks']>((next) => {\n // Provider owns persistence — bulk replace (Google Tasks sync) is a no-op there.\n if (!provider) prefsImpl.setAllTasks(next);\n }, [prefsImpl]);\n\n if (!hasShellTodoProvider()) return prefsImpl;\n return { tasks: providerTasks, addTask, updateTask, removeTask, toggleDone, setAllTasks };\n}\n\n/**\n * One-time migration: pull any tasks the Pomodoro widget previously\n * persisted to `localStorage.pomodoro_tasks` into the shared store.\n * No-op when a provider is registered (the provider owns persistence).\n */\nexport function migratePomodoroTasksOnce(\n currentTasks: TodoTask[],\n setAllTasks: (next: TodoTask[]) => void,\n): void {\n try {\n if (localStorage.getItem(POMODORO_LEGACY_MIGRATED_FLAG)) return;\n const raw = localStorage.getItem(POMODORO_LEGACY_KEY);\n if (!raw) {\n localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1');\n return;\n }\n const legacy: Array<{ id?: string; name?: string; estimated?: number; completed?: number; done?: boolean }>\n = JSON.parse(raw);\n if (!Array.isArray(legacy) || legacy.length === 0) {\n localStorage.removeItem(POMODORO_LEGACY_KEY);\n localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1');\n return;\n }\n const ts = nowIso();\n const migrated: TodoTask[] = legacy\n .filter(t => typeof t?.name === 'string')\n .map(t => ({\n id: t.id || uid(),\n name: String(t.name),\n done: !!t.done,\n estimated: typeof t.estimated === 'number' ? t.estimated : undefined,\n completed: typeof t.completed === 'number' ? t.completed : undefined,\n createdAt: ts,\n updatedAt: ts,\n }));\n const existingIds = new Set(currentTasks.map(t => t.id));\n const additions = migrated.filter(t => !existingIds.has(t.id));\n setAllTasks([...additions, ...currentTasks]);\n localStorage.removeItem(POMODORO_LEGACY_KEY);\n localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1');\n } catch {\n try { localStorage.setItem(POMODORO_LEGACY_MIGRATED_FLAG, '1'); } catch {}\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -235,6 +235,30 @@ interface ModalProps {
|
|
|
235
235
|
}
|
|
236
236
|
/** Register an Escape interceptor; returns an unregister function. */
|
|
237
237
|
declare function registerModalEscapeInterceptor(fn: (e: KeyboardEvent) => boolean): () => void;
|
|
238
|
+
/**
|
|
239
|
+
* Is the window identified by `windowKey` the frontmost one?
|
|
240
|
+
*
|
|
241
|
+
* For anything that binds a global shortcut from *outside* the `<Modal>` it
|
|
242
|
+
* belongs to — `UndoProvider` is mounted a level above `PageWindow`, so it has
|
|
243
|
+
* no `ModalActionsContext` to read and cannot use {@link useModalActive}, whose
|
|
244
|
+
* fallback path is made of module globals and therefore answers identically for
|
|
245
|
+
* every caller. That fallback is fine for "is any window active"; it is useless
|
|
246
|
+
* for "is *mine* active", and a per-window listener that asks the wrong
|
|
247
|
+
* question fires in every window at once.
|
|
248
|
+
*
|
|
249
|
+
* `windowKey` is the stable key a window passes to `<Modal windowKey=...>` —
|
|
250
|
+
* `WindowManager`'s `item.id` — not the private per-mount `modalId` that
|
|
251
|
+
* `activationOrder` actually holds. The two are mapped by `mountModal`, and
|
|
252
|
+
* resolving through that map is the whole point: `useIsActiveModal(item.id)`
|
|
253
|
+
* would compare a window key against a `modal-xxxxxx` id and be false for every
|
|
254
|
+
* window rather than true for every window.
|
|
255
|
+
*
|
|
256
|
+
* Omit `windowKey` — or pass one no mounted modal has claimed, which is the
|
|
257
|
+
* case for a `rendersOwnModal` window whose inner `<Modal>` sets no
|
|
258
|
+
* `windowKey` — and this degrades to {@link useModalActive}: the enclosing
|
|
259
|
+
* `<ModalActions>` context if there is one, the global test if there is not.
|
|
260
|
+
*/
|
|
261
|
+
declare function useIsActiveWindow(windowKey?: string | null): boolean;
|
|
238
262
|
declare function toggleExposeMode(): void;
|
|
239
263
|
declare function exitExposeMode(): void;
|
|
240
264
|
declare function subscribeExposeHighlight(fn: () => void): () => boolean;
|
|
@@ -2428,6 +2452,23 @@ interface MergeBulkOptions<T extends BaseItem> {
|
|
|
2428
2452
|
}
|
|
2429
2453
|
declare function mergeBulkItems<T extends BaseItem>(options: MergeBulkOptions<T>): MergeBulkResult<T>;
|
|
2430
2454
|
|
|
2455
|
+
interface UndoControlsProps {
|
|
2456
|
+
/** Extra classes for the wrapping row. */
|
|
2457
|
+
className?: string;
|
|
2458
|
+
}
|
|
2459
|
+
/**
|
|
2460
|
+
* Undo/Redo for the enclosing form, reading the stack from {@link UndoProvider}.
|
|
2461
|
+
*
|
|
2462
|
+
* Put it wherever the form's actions live — a window header, a section header,
|
|
2463
|
+
* beside the save button. The keys work without it; this is for discoverability
|
|
2464
|
+
* and for the mouse. Both buttons stay rendered and go disabled, so the row
|
|
2465
|
+
* does not reflow the moment there is something to undo.
|
|
2466
|
+
*
|
|
2467
|
+
* Renders nothing for a user who may not edit the record — dead buttons on a
|
|
2468
|
+
* read-only form read as something broken rather than something withheld.
|
|
2469
|
+
*/
|
|
2470
|
+
declare function UndoControls({ className }: UndoControlsProps): react_jsx_runtime.JSX.Element | null;
|
|
2471
|
+
|
|
2431
2472
|
/** Default item shape — overridable via the accessor props for any other shape. */
|
|
2432
2473
|
interface ContainerFillItem {
|
|
2433
2474
|
quantity?: number | null;
|
|
@@ -2895,4 +2936,184 @@ declare function useNewHotkey(callback: () => void): void;
|
|
|
2895
2936
|
*/
|
|
2896
2937
|
declare function useEditHotkey(callback: (() => void) | null): void;
|
|
2897
2938
|
|
|
2898
|
-
|
|
2939
|
+
interface UndoProviderProps {
|
|
2940
|
+
children: React.ReactNode;
|
|
2941
|
+
/**
|
|
2942
|
+
* Whether this user may edit the record. Undo is offered to everyone who
|
|
2943
|
+
* can — it is not gated on role or seniority — and withheld from a reader
|
|
2944
|
+
* only because they have nothing to take back. Defaults to true.
|
|
2945
|
+
*/
|
|
2946
|
+
canEdit?: boolean;
|
|
2947
|
+
/**
|
|
2948
|
+
* Permission codes that count as "may edit", checked through
|
|
2949
|
+
* `ShellAuthProvider`. Combined with `canEdit`, so a form that already knows
|
|
2950
|
+
* it is read-only stays read-only whatever the codes say. Omit to rely on
|
|
2951
|
+
* `canEdit` alone.
|
|
2952
|
+
*/
|
|
2953
|
+
perms?: string[];
|
|
2954
|
+
/**
|
|
2955
|
+
* The window this stack belongs to — the same stable key its `<Modal>` gets
|
|
2956
|
+
* as `windowKey`, which for a `WindowManager` window is `item.id`.
|
|
2957
|
+
*
|
|
2958
|
+
* This is what keeps ⌘Z inside the window the user is looking at. The
|
|
2959
|
+
* provider binds its hotkey on `window`, so every open window's provider sees
|
|
2960
|
+
* every keypress; the id is how one of them recognises the press as its own.
|
|
2961
|
+
* Without it there is no per-window identity to test and the best available
|
|
2962
|
+
* answer is "is any window active", which is true in all of them at once.
|
|
2963
|
+
*
|
|
2964
|
+
* Omit it for a provider nested inside a `<Modal>` — there the enclosing
|
|
2965
|
+
* modal's own context answers the question — or where there are no windows
|
|
2966
|
+
* at all.
|
|
2967
|
+
*/
|
|
2968
|
+
windowId?: string;
|
|
2969
|
+
}
|
|
2970
|
+
/**
|
|
2971
|
+
* Undo/redo for everything in one open form.
|
|
2972
|
+
*
|
|
2973
|
+
* Wrap a form window in it, register each piece of its state with
|
|
2974
|
+
* {@link useUndoable}, and the whole form shares one stack: a field edit, a
|
|
2975
|
+
* line added, a bulk import are all steps in the same history, undone newest
|
|
2976
|
+
* first. Two open windows have two independent stacks, and passing
|
|
2977
|
+
* {@link UndoProviderProps.windowId} is what keeps them independent in
|
|
2978
|
+
* practice — see that prop.
|
|
2979
|
+
*
|
|
2980
|
+
* History is the unsaved edit only. It lives with the mounted provider and
|
|
2981
|
+
* dies with it. Both ends of the edit are the caller's to mark: `baseline()`
|
|
2982
|
+
* once the record has arrived, so the load is the starting point rather than
|
|
2983
|
+
* the first thing ⌘Z takes back, and `clear()` at a save, past which "earlier"
|
|
2984
|
+
* is on the server and not something a form can reach.
|
|
2985
|
+
*
|
|
2986
|
+
* Anyone who may edit the record gets it — it is not a privileged feature, and
|
|
2987
|
+
* the user most helped by an undo is the one least sure of what they just did.
|
|
2988
|
+
* A reader is the only one it is withheld from, and only because there is
|
|
2989
|
+
* nothing for them to take back. Note that `canEdit` is the caller's claim, and
|
|
2990
|
+
* the shell-level provider `WindowManager` mounts around every window has no
|
|
2991
|
+
* way to make it: it knows nothing about the record inside. That one defaults
|
|
2992
|
+
* to enabled, and a read-only form states the fact by nesting its own
|
|
2993
|
+
* `<UndoProvider canEdit={false}>`, which shadows it.
|
|
2994
|
+
*/
|
|
2995
|
+
declare function UndoProvider({ children, canEdit, perms, windowId }: UndoProviderProps): react_jsx_runtime.JSX.Element;
|
|
2996
|
+
interface UndoControlsApi {
|
|
2997
|
+
undo: () => void;
|
|
2998
|
+
redo: () => void;
|
|
2999
|
+
canUndo: boolean;
|
|
3000
|
+
canRedo: boolean;
|
|
3001
|
+
/** What Undo/Redo would act on, for a button title. Null when unavailable. */
|
|
3002
|
+
undoLabel: string | null;
|
|
3003
|
+
redoLabel: string | null;
|
|
3004
|
+
/** End the history — call after a successful save. */
|
|
3005
|
+
clear: () => void;
|
|
3006
|
+
/**
|
|
3007
|
+
* Make the form as it stands the starting point, discarding the history.
|
|
3008
|
+
*
|
|
3009
|
+
* Call it once the record has arrived from the server. State filled from a
|
|
3010
|
+
* fetch is a change like any other as far as the slices are concerned, so
|
|
3011
|
+
* without this the load itself is the oldest step and the user's first ⌘Z
|
|
3012
|
+
* empties the form they were just given:
|
|
3013
|
+
*
|
|
3014
|
+
* const { data } = useQuery(...);
|
|
3015
|
+
* const { baseline } = useUndo();
|
|
3016
|
+
* useEffect(() => { if (data) baseline(); }, [data, baseline]);
|
|
3017
|
+
*
|
|
3018
|
+
* Worth calling on every arrival, not just the first: a window kept open
|
|
3019
|
+
* across a refetch, or one whose entity changes underneath it, wants the
|
|
3020
|
+
* same treatment, and the call is idempotent for a form nobody has touched.
|
|
3021
|
+
*/
|
|
3022
|
+
baseline: () => void;
|
|
3023
|
+
/** False when the user may not edit this record, so custom UI can hide
|
|
3024
|
+
* itself the way `UndoControls` does. */
|
|
3025
|
+
enabled: boolean;
|
|
3026
|
+
}
|
|
3027
|
+
/**
|
|
3028
|
+
* The enclosing form's undo stack, for custom UI or to `clear()` on save.
|
|
3029
|
+
* Everything is inert outside an {@link UndoProvider}.
|
|
3030
|
+
*/
|
|
3031
|
+
declare function useUndo(): UndoControlsApi;
|
|
3032
|
+
interface UndoableOptions {
|
|
3033
|
+
/** Names the step in a button title: `"qty"`, `"line items"`. */
|
|
3034
|
+
label: string;
|
|
3035
|
+
/**
|
|
3036
|
+
* Consecutive changes sharing a key fold into one step — pass the field name
|
|
3037
|
+
* so a run of typing is one Undo rather than one per keystroke. Omit for a
|
|
3038
|
+
* change that is already whole, like a bulk import or a deleted row.
|
|
3039
|
+
*/
|
|
3040
|
+
coalesceKey?: string | null;
|
|
3041
|
+
}
|
|
3042
|
+
/**
|
|
3043
|
+
* Put one piece of the form's state under the window's undo stack.
|
|
3044
|
+
*
|
|
3045
|
+
* `value` is watched; when it changes, the form as it stood beforehand becomes
|
|
3046
|
+
* a step. `apply` puts a value back — the same setter the form already uses.
|
|
3047
|
+
*
|
|
3048
|
+
* const [items, setItems] = useState<Line[]>([]);
|
|
3049
|
+
* useUndoable(items, setItems, { label: 'line items' });
|
|
3050
|
+
*
|
|
3051
|
+
* Registering more than one slice is the point: a step snapshots all of them
|
|
3052
|
+
* together, so undoing restores a coherent form rather than one slice out of
|
|
3053
|
+
* step with the rest.
|
|
3054
|
+
*
|
|
3055
|
+
* `value` must be the state itself, not something derived from it on the way
|
|
3056
|
+
* in. A change is detected by identity, so `useUndoable(rows.filter(r => r.on),
|
|
3057
|
+
* ...)` hands over a new array on every render and reads as a change every
|
|
3058
|
+
* time — and since recording a step re-renders the provider, that closes a
|
|
3059
|
+
* loop at render speed. The provider trips a runaway guard and says so rather
|
|
3060
|
+
* than letting the tab hang, but the fix is at the call site: register the
|
|
3061
|
+
* state, and derive from it afterwards.
|
|
3062
|
+
*/
|
|
3063
|
+
declare function useUndoable<T>(value: T, apply: (next: T) => void, opts: UndoableOptions): void;
|
|
3064
|
+
/**
|
|
3065
|
+
* `useState`, with the value in the window's undo stack.
|
|
3066
|
+
*
|
|
3067
|
+
* Written to be a rename rather than an extra line, because the forms this is
|
|
3068
|
+
* for hold their state in dozens of separate `useState` calls — one of them has
|
|
3069
|
+
* forty-three. Adopting a form is then a per-line edit:
|
|
3070
|
+
*
|
|
3071
|
+
* const [supplier, setSupplier] = useState('');
|
|
3072
|
+
* const [supplier, setSupplier] = useUndoableState('', { label: 'supplier' });
|
|
3073
|
+
*
|
|
3074
|
+
* Which also makes the choice legible: state left as plain `useState` is state
|
|
3075
|
+
* deliberately kept out of the history. Keep it that way for anything that is
|
|
3076
|
+
* not the user's input — a search box, fetched data, validation output, an
|
|
3077
|
+
* initialisation guard. Undoing those puts stale results back on screen, and a
|
|
3078
|
+
* reverted guard can re-fire the effect it exists to suppress.
|
|
3079
|
+
*
|
|
3080
|
+
* Pass `coalesceKey` for anything typed into, so a run of keystrokes is one
|
|
3081
|
+
* Undo; the field's own name is the obvious key.
|
|
3082
|
+
*/
|
|
3083
|
+
declare function useUndoableState<T>(initial: T | (() => T), opts: UndoableOptions): [T, React.Dispatch<React.SetStateAction<T>>];
|
|
3084
|
+
|
|
3085
|
+
/**
|
|
3086
|
+
* Undo/redo for one open form — the pure half.
|
|
3087
|
+
*
|
|
3088
|
+
* A form window owns a single stack covering everything in it: its fields, its
|
|
3089
|
+
* line-items table, a bulk import. One ⌘Z steps back the last thing the user
|
|
3090
|
+
* did, whatever part of the form it happened in.
|
|
3091
|
+
*
|
|
3092
|
+
* The stack holds snapshots, not diffs. A step stores the value of every
|
|
3093
|
+
* registered slice **as it was before the change**, so undoing restores the
|
|
3094
|
+
* whole form to a coherent moment rather than replaying one slice out of step
|
|
3095
|
+
* with the others. Forms are small — a few dozen fields and some line items —
|
|
3096
|
+
* so whole-form snapshots stay cheap and the logic stays honest.
|
|
3097
|
+
*
|
|
3098
|
+
* Scope is the unsaved edit. History lives with the open window and dies with
|
|
3099
|
+
* it; nothing here reverses a saved record.
|
|
3100
|
+
*/
|
|
3101
|
+
/** Registered slice id → that slice's value at the time of the snapshot. */
|
|
3102
|
+
type UndoSnapshot = Record<string, unknown>;
|
|
3103
|
+
interface UndoStep {
|
|
3104
|
+
/** The form as it stood before this change. Undo restores exactly this. */
|
|
3105
|
+
values: UndoSnapshot;
|
|
3106
|
+
/** What the step was, for a button title: `"qty"`, `"import of 5 lines"`. */
|
|
3107
|
+
label: string;
|
|
3108
|
+
/**
|
|
3109
|
+
* Consecutive changes sharing a non-null key fold into one step — typing in
|
|
3110
|
+
* a field is one Undo, not one per keystroke. Null never folds.
|
|
3111
|
+
*/
|
|
3112
|
+
coalesceKey: string | null;
|
|
3113
|
+
}
|
|
3114
|
+
interface UndoState {
|
|
3115
|
+
past: UndoStep[];
|
|
3116
|
+
future: UndoStep[];
|
|
3117
|
+
}
|
|
3118
|
+
|
|
3119
|
+
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, type AccordionItem, type AccordionProps, AuthScreen, type AuthScreenProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarSize, type AvatarStatus, BLOCKED_PCT_CPU, Banner, type BannerProps, type BannerTone, BarChart, type BarChartProps, BehaviorPanel, type BottleneckKind, type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps, type BulkColumn, type BulkColumnKind, BulkImportGrid, type BulkImportGridProps, type BulkRow, Button, type ButtonProps, type ButtonSize, type ButtonVariant, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, Card, type CardProps, type CellStyle, ChangePasswordForm, type ChangePasswordFormProps, type ChangelogEntry, ChatTemplate, Checkbox, type CheckboxProps, CheckoutTemplate, type ClockCalendarConfig, ColoredBadge, type ColoredBadgeProps, type ColumnDef, ConfirmProvider, ContainerFillChart, type ContainerFillChartProps, type ContainerFillItem, CopyButton, Customization, type CustomizationOmitSection, type CustomizationProps, type CustomizationSection, DEV_BANNER_TEXT, DashboardTemplate, DataTablePage, DateRangePicker, type DateRangePickerProps, Desktop, type DesktopContextMenuItem, type DesktopHostConfig, DesktopHostProvider, DevIndicator, DocFavStar, DonutChart, type DonutChartProps, type DonutSegment, type DuplicateGroup, ENTER, EditableGrid, type EditableGridProps, EmailTemplate, EmptyState, type EmptyStateProps, type EntityFetcher, EntityList, type EntityListColumn, type EntityListContextAction, type EntityListProps, ErrorPage, type ErrorPageProps, FilterBar, type FilterOption, FormField, type FormFieldProps, FormLayoutPage, type FpsGroup, GLASS_DIVIDER, GLASS_INPUT_BG, GalleryTemplate, GlobalSearch, type GridColumn, type HealthCheckResult, HelpCenter, type HelpCenterDoc, type HelpCenterProps, INPUT_BASE, ImageAnnotator, type ImageAnnotatorHandle, type ImageAnnotatorProps, Input, type InputProps, Kanban, type KanbanColumn, type KanbanProps, LOG_CAP, Label, type LabelProps, Layout, type LayoutProps, ListFooter, ListLoadError, type ListLoadErrorProps, LoadingSpinner, type LoadingSpinnerProps, type LogSummary, MIN_GROUP_SAMPLES, MOD, Markdown, type MarkdownProps, MediaUploadField, type MediaUploadFieldProps, MediaUploadGrid, type MediaUploadGridItem, type MediaUploadGridProps, type MergeBulkOptions, type MergeBulkResult, MetricBar, type MetricBarProps, type Milestone, type MilestoneKind, MilestoneTimeline, type MilestoneTimelineProps, type MobileAppConfig, Modal, ModalActions, NativeSelect, NotificationBell, type NotificationsConfig, PageHeader, type PageHeaderProps, type PaginatedResponse, Pagination, type PaginationProps, PdfActionButton, type PdfActionButtonProps, type PerfLogRecord, type PerfReading, PerfStats, type PerfStatsProps, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, Radio, type RadioProps, ResizableTable, SHIFT, SMOOTH_FPS, type SearchConfig, type SearchProvider, type SearchResult, type SearchableOption, SearchableSelect, type SearchableSelectProps, Select, type SelectOption, type SelectProps, type SemanticGroup, ServerStatusIndicator, type ServerStatusIndicatorProps, type ServerStatusUser, type SeverityTone, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, SidebarActionButton, type SidebarActionButtonProps, SidebarGroupLabel, SidebarLayout, type SidebarLayoutProps, SidebarNavItem, type SortState, SoundsPanel, Sparkline, type SparklineProps, StartMenu, StatCard, type StatCardProps, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, SystemPreferences, type SystemPreferencesProps, type SystemPreferencesSection, type TabItem, Tabs, type TabsProps, Textarea, type TextareaProps, type TodoProvider, type TodoTask, Tooltip, type TooltipProps, TopNav, type TopNavItem, type TopNavProps, UndoControls, type UndoControlsApi, type UndoControlsProps, UndoProvider, type UndoProviderProps, type UndoSnapshot, type UndoState, type UndoStep, type UndoableOptions, VERSION, type Verdict, WidgetManager, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowRegistry, WindowTitle, appendRecord as appendPerfRecord, applyDevTitle, classify as classifyPerf, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, findDuplicateKeys, formatDate, getActiveWindowRoute, getExposeHighlight, getWindowPosition, glassStyle, inputClasses, isDevEnv, isInteracting, isMac, isSeverityTone, mediaFileName, mergeBulkItems, toCsv as perfLogToCsv, prompt, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellNavIcons, setShellTodoProvider, setWindowDefaultPosition, setWindowPosition, severityOf, subscribeExposeHighlight, summariseFrames, summariseLog as summarisePerfLog, toISODate, toast, toggleExposeMode, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useFilters, useInfiniteScroll, useIsActiveWindow, useLocalStoragePrefs, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useSort, useTableNav, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
|