trainbud 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +675 -0
  3. package/LICENSE +21 -0
  4. package/QUICKSTART.md +182 -0
  5. package/README.md +322 -0
  6. package/dist/appDb.d.ts +83 -0
  7. package/dist/appDb.d.ts.map +1 -0
  8. package/dist/appDb.js +239 -0
  9. package/dist/appDb.js.map +1 -0
  10. package/dist/check.d.ts +12 -0
  11. package/dist/check.d.ts.map +1 -0
  12. package/dist/check.js +230 -0
  13. package/dist/check.js.map +1 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +457 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config.d.ts +61 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +241 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/dashboard.d.ts +8 -0
  23. package/dist/dashboard.d.ts.map +1 -0
  24. package/dist/dashboard.js +1004 -0
  25. package/dist/dashboard.js.map +1 -0
  26. package/dist/dashboardCharts.d.ts +99 -0
  27. package/dist/dashboardCharts.d.ts.map +1 -0
  28. package/dist/dashboardCharts.js +317 -0
  29. package/dist/dashboardCharts.js.map +1 -0
  30. package/dist/dashboardData.d.ts +89 -0
  31. package/dist/dashboardData.d.ts.map +1 -0
  32. package/dist/dashboardData.js +228 -0
  33. package/dist/dashboardData.js.map +1 -0
  34. package/dist/detect/baseline.d.ts +17 -0
  35. package/dist/detect/baseline.d.ts.map +1 -0
  36. package/dist/detect/baseline.js +62 -0
  37. package/dist/detect/baseline.js.map +1 -0
  38. package/dist/detect/countdown.d.ts +30 -0
  39. package/dist/detect/countdown.d.ts.map +1 -0
  40. package/dist/detect/countdown.js +79 -0
  41. package/dist/detect/countdown.js.map +1 -0
  42. package/dist/detect/detectors.d.ts +20 -0
  43. package/dist/detect/detectors.d.ts.map +1 -0
  44. package/dist/detect/detectors.js +291 -0
  45. package/dist/detect/detectors.js.map +1 -0
  46. package/dist/detect/findings.d.ts +29 -0
  47. package/dist/detect/findings.d.ts.map +1 -0
  48. package/dist/detect/findings.js +2 -0
  49. package/dist/detect/findings.js.map +1 -0
  50. package/dist/detect/forecast.d.ts +33 -0
  51. package/dist/detect/forecast.d.ts.map +1 -0
  52. package/dist/detect/forecast.js +122 -0
  53. package/dist/detect/forecast.js.map +1 -0
  54. package/dist/detect/index.d.ts +50 -0
  55. package/dist/detect/index.d.ts.map +1 -0
  56. package/dist/detect/index.js +114 -0
  57. package/dist/detect/index.js.map +1 -0
  58. package/dist/detect/sleepQuality.d.ts +21 -0
  59. package/dist/detect/sleepQuality.d.ts.map +1 -0
  60. package/dist/detect/sleepQuality.js +164 -0
  61. package/dist/detect/sleepQuality.js.map +1 -0
  62. package/dist/detect/trimp.d.ts +22 -0
  63. package/dist/detect/trimp.d.ts.map +1 -0
  64. package/dist/detect/trimp.js +77 -0
  65. package/dist/detect/trimp.js.map +1 -0
  66. package/dist/detect/week.d.ts +31 -0
  67. package/dist/detect/week.d.ts.map +1 -0
  68. package/dist/detect/week.js +184 -0
  69. package/dist/detect/week.js.map +1 -0
  70. package/dist/garmin/auth.d.ts +10 -0
  71. package/dist/garmin/auth.d.ts.map +1 -0
  72. package/dist/garmin/auth.js +81 -0
  73. package/dist/garmin/auth.js.map +1 -0
  74. package/dist/garmin/cache.d.ts +42 -0
  75. package/dist/garmin/cache.d.ts.map +1 -0
  76. package/dist/garmin/cache.js +141 -0
  77. package/dist/garmin/cache.js.map +1 -0
  78. package/dist/garmin/client.d.ts +22 -0
  79. package/dist/garmin/client.d.ts.map +1 -0
  80. package/dist/garmin/client.js +237 -0
  81. package/dist/garmin/client.js.map +1 -0
  82. package/dist/garmin/daily.d.ts +24 -0
  83. package/dist/garmin/daily.d.ts.map +1 -0
  84. package/dist/garmin/daily.js +96 -0
  85. package/dist/garmin/daily.js.map +1 -0
  86. package/dist/garmin/garminApiTypes.d.ts +70 -0
  87. package/dist/garmin/garminApiTypes.d.ts.map +1 -0
  88. package/dist/garmin/garminApiTypes.js +3 -0
  89. package/dist/garmin/garminApiTypes.js.map +1 -0
  90. package/dist/garmin/garminConnect.d.ts +17 -0
  91. package/dist/garmin/garminConnect.d.ts.map +1 -0
  92. package/dist/garmin/garminConnect.js +5 -0
  93. package/dist/garmin/garminConnect.js.map +1 -0
  94. package/dist/garmin/partial.d.ts +32 -0
  95. package/dist/garmin/partial.d.ts.map +1 -0
  96. package/dist/garmin/partial.js +38 -0
  97. package/dist/garmin/partial.js.map +1 -0
  98. package/dist/garmin/rawApi.d.ts +59 -0
  99. package/dist/garmin/rawApi.d.ts.map +1 -0
  100. package/dist/garmin/rawApi.js +113 -0
  101. package/dist/garmin/rawApi.js.map +1 -0
  102. package/dist/garmin/types.d.ts +85 -0
  103. package/dist/garmin/types.d.ts.map +1 -0
  104. package/dist/garmin/types.js +11 -0
  105. package/dist/garmin/types.js.map +1 -0
  106. package/dist/history/capture.d.ts +12 -0
  107. package/dist/history/capture.d.ts.map +1 -0
  108. package/dist/history/capture.js +63 -0
  109. package/dist/history/capture.js.map +1 -0
  110. package/dist/history/context.d.ts +51 -0
  111. package/dist/history/context.d.ts.map +1 -0
  112. package/dist/history/context.js +122 -0
  113. package/dist/history/context.js.map +1 -0
  114. package/dist/history/fallback.d.ts +72 -0
  115. package/dist/history/fallback.d.ts.map +1 -0
  116. package/dist/history/fallback.js +185 -0
  117. package/dist/history/fallback.js.map +1 -0
  118. package/dist/history/ingest.d.ts +44 -0
  119. package/dist/history/ingest.d.ts.map +1 -0
  120. package/dist/history/ingest.js +347 -0
  121. package/dist/history/ingest.js.map +1 -0
  122. package/dist/history/scheduler.d.ts +20 -0
  123. package/dist/history/scheduler.d.ts.map +1 -0
  124. package/dist/history/scheduler.js +54 -0
  125. package/dist/history/scheduler.js.map +1 -0
  126. package/dist/history/schema.d.ts +41 -0
  127. package/dist/history/schema.d.ts.map +1 -0
  128. package/dist/history/schema.js +91 -0
  129. package/dist/history/schema.js.map +1 -0
  130. package/dist/history/store.d.ts +112 -0
  131. package/dist/history/store.d.ts.map +1 -0
  132. package/dist/history/store.js +282 -0
  133. package/dist/history/store.js.map +1 -0
  134. package/dist/httpServer.d.ts +55 -0
  135. package/dist/httpServer.d.ts.map +1 -0
  136. package/dist/httpServer.js +1027 -0
  137. package/dist/httpServer.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +11 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/mcpConfig.d.ts +56 -0
  143. package/dist/mcpConfig.d.ts.map +1 -0
  144. package/dist/mcpConfig.js +106 -0
  145. package/dist/mcpConfig.js.map +1 -0
  146. package/dist/pairApi.d.ts +14 -0
  147. package/dist/pairApi.d.ts.map +1 -0
  148. package/dist/pairApi.js +38 -0
  149. package/dist/pairApi.js.map +1 -0
  150. package/dist/paths.d.ts +45 -0
  151. package/dist/paths.d.ts.map +1 -0
  152. package/dist/paths.js +105 -0
  153. package/dist/paths.js.map +1 -0
  154. package/dist/profile.d.ts +123 -0
  155. package/dist/profile.d.ts.map +1 -0
  156. package/dist/profile.js +327 -0
  157. package/dist/profile.js.map +1 -0
  158. package/dist/promptApi.d.ts +43 -0
  159. package/dist/promptApi.d.ts.map +1 -0
  160. package/dist/promptApi.js +328 -0
  161. package/dist/promptApi.js.map +1 -0
  162. package/dist/promptSuggestions.d.ts +16 -0
  163. package/dist/promptSuggestions.d.ts.map +1 -0
  164. package/dist/promptSuggestions.js +141 -0
  165. package/dist/promptSuggestions.js.map +1 -0
  166. package/dist/selfTest.d.ts +53 -0
  167. package/dist/selfTest.d.ts.map +1 -0
  168. package/dist/selfTest.js +225 -0
  169. package/dist/selfTest.js.map +1 -0
  170. package/dist/server.d.ts +10 -0
  171. package/dist/server.d.ts.map +1 -0
  172. package/dist/server.js +67 -0
  173. package/dist/server.js.map +1 -0
  174. package/dist/setup.d.ts +2 -0
  175. package/dist/setup.d.ts.map +1 -0
  176. package/dist/setup.js +210 -0
  177. package/dist/setup.js.map +1 -0
  178. package/dist/toolErrors.d.ts +2 -0
  179. package/dist/toolErrors.d.ts.map +1 -0
  180. package/dist/toolErrors.js +18 -0
  181. package/dist/toolErrors.js.map +1 -0
  182. package/dist/tools/activities.d.ts +18 -0
  183. package/dist/tools/activities.d.ts.map +1 -0
  184. package/dist/tools/activities.js +182 -0
  185. package/dist/tools/activities.js.map +1 -0
  186. package/dist/tools/bodyComposition.d.ts +10 -0
  187. package/dist/tools/bodyComposition.d.ts.map +1 -0
  188. package/dist/tools/bodyComposition.js +139 -0
  189. package/dist/tools/bodyComposition.js.map +1 -0
  190. package/dist/tools/context.d.ts +8 -0
  191. package/dist/tools/context.d.ts.map +1 -0
  192. package/dist/tools/context.js +148 -0
  193. package/dist/tools/context.js.map +1 -0
  194. package/dist/tools/findings.d.ts +7 -0
  195. package/dist/tools/findings.d.ts.map +1 -0
  196. package/dist/tools/findings.js +51 -0
  197. package/dist/tools/findings.js.map +1 -0
  198. package/dist/tools/heartRate.d.ts +10 -0
  199. package/dist/tools/heartRate.d.ts.map +1 -0
  200. package/dist/tools/heartRate.js +105 -0
  201. package/dist/tools/heartRate.js.map +1 -0
  202. package/dist/tools/index.d.ts +66 -0
  203. package/dist/tools/index.d.ts.map +1 -0
  204. package/dist/tools/index.js +101 -0
  205. package/dist/tools/index.js.map +1 -0
  206. package/dist/tools/payloads.d.ts +148 -0
  207. package/dist/tools/payloads.d.ts.map +1 -0
  208. package/dist/tools/payloads.js +2 -0
  209. package/dist/tools/payloads.js.map +1 -0
  210. package/dist/tools/recovery.d.ts +31 -0
  211. package/dist/tools/recovery.d.ts.map +1 -0
  212. package/dist/tools/recovery.js +350 -0
  213. package/dist/tools/recovery.js.map +1 -0
  214. package/dist/tools/sleep.d.ts +10 -0
  215. package/dist/tools/sleep.d.ts.map +1 -0
  216. package/dist/tools/sleep.js +124 -0
  217. package/dist/tools/sleep.js.map +1 -0
  218. package/dist/tools/stress.d.ts +11 -0
  219. package/dist/tools/stress.d.ts.map +1 -0
  220. package/dist/tools/stress.js +108 -0
  221. package/dist/tools/stress.js.map +1 -0
  222. package/dist/tools/trainingInsights.d.ts +15 -0
  223. package/dist/tools/trainingInsights.d.ts.map +1 -0
  224. package/dist/tools/trainingInsights.js +79 -0
  225. package/dist/tools/trainingInsights.js.map +1 -0
  226. package/dist/tools/types.d.ts +12 -0
  227. package/dist/tools/types.d.ts.map +1 -0
  228. package/dist/tools/types.js +2 -0
  229. package/dist/tools/types.js.map +1 -0
  230. package/dist/tools/vo2Max.d.ts +11 -0
  231. package/dist/tools/vo2Max.d.ts.map +1 -0
  232. package/dist/tools/vo2Max.js +110 -0
  233. package/dist/tools/vo2Max.js.map +1 -0
  234. package/dist/tools/week.d.ts +12 -0
  235. package/dist/tools/week.d.ts.map +1 -0
  236. package/dist/tools/week.js +74 -0
  237. package/dist/tools/week.js.map +1 -0
  238. package/dist/usage.d.ts +104 -0
  239. package/dist/usage.d.ts.map +1 -0
  240. package/dist/usage.js +247 -0
  241. package/dist/usage.js.map +1 -0
  242. package/dist/utils/batch.d.ts +2 -0
  243. package/dist/utils/batch.d.ts.map +1 -0
  244. package/dist/utils/batch.js +18 -0
  245. package/dist/utils/batch.js.map +1 -0
  246. package/dist/utils/helpers.d.ts +32 -0
  247. package/dist/utils/helpers.d.ts.map +1 -0
  248. package/dist/utils/helpers.js +188 -0
  249. package/dist/utils/helpers.js.map +1 -0
  250. package/dist/utils/jsonFile.d.ts +19 -0
  251. package/dist/utils/jsonFile.d.ts.map +1 -0
  252. package/dist/utils/jsonFile.js +24 -0
  253. package/dist/utils/jsonFile.js.map +1 -0
  254. package/dist/utils/logger.d.ts +4 -0
  255. package/dist/utils/logger.d.ts.map +1 -0
  256. package/dist/utils/logger.js +97 -0
  257. package/dist/utils/logger.js.map +1 -0
  258. package/dist/utils/secretFile.d.ts +15 -0
  259. package/dist/utils/secretFile.d.ts.map +1 -0
  260. package/dist/utils/secretFile.js +47 -0
  261. package/dist/utils/secretFile.js.map +1 -0
  262. package/dist/utils/stdio.d.ts +10 -0
  263. package/dist/utils/stdio.d.ts.map +1 -0
  264. package/dist/utils/stdio.js +70 -0
  265. package/dist/utils/stdio.js.map +1 -0
  266. package/dist/version.d.ts +2 -0
  267. package/dist/version.d.ts.map +1 -0
  268. package/dist/version.js +7 -0
  269. package/dist/version.js.map +1 -0
  270. package/dist/watchApi.d.ts +264 -0
  271. package/dist/watchApi.d.ts.map +1 -0
  272. package/dist/watchApi.js +333 -0
  273. package/dist/watchApi.js.map +1 -0
  274. package/package.json +77 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { DateTime } from "luxon";
2
+ /** Chart ink. Mirrors the CSS custom properties; SVG attributes cannot read them. */
3
+ export declare const CHART_COLORS: {
4
+ readonly surface: "#141C2E";
5
+ readonly grid: "#22304A";
6
+ readonly ink: "#E6EDF5";
7
+ readonly muted: "#8FA3BD";
8
+ /** Single-series hue. Blue, the documented sequential default, stepped for a dark surface. */
9
+ readonly series: "#3987E5";
10
+ /**
11
+ * Green is #4CD964, not the mint #3DDC84 it started as, because of a device
12
+ * this file never renders on. The Forerunner 55 has an EIGHT-COLOUR palette
13
+ * and Connect IQ snaps every colour to the nearest entry -- #3DDC84 lands on
14
+ * CYAN, so "good" would reach that wrist as a colour carrying no meaning in
15
+ * this system. One palette across the browser and the watch is worth more
16
+ * than the exact shade, so the shade moved. Contrast on the card surface is
17
+ * 9.2:1 either way.
18
+ */
19
+ readonly good: "#4CD964";
20
+ readonly caution: "#F5A623";
21
+ readonly hard: "#E5484D";
22
+ };
23
+ export interface SeriesPoint {
24
+ date: string;
25
+ value: number | null;
26
+ }
27
+ /**
28
+ * Fill in every day in the range, marking the ones with no measurement null.
29
+ *
30
+ * The store only holds a row for a day that was actually recorded, so an array
31
+ * of points is not a timeline -- it is a list of the days that happened to have
32
+ * data. Plotting it by index puts a three-week gap and a one-day gap the same
33
+ * distance apart.
34
+ */
35
+ export declare function densify(points: SeriesPoint[], days: number, today?: DateTime<true>): SeriesPoint[];
36
+ export interface LineChartOptions {
37
+ /** Names what is plotted; a single series needs no legend box. */
38
+ label: string;
39
+ unit?: string;
40
+ /** A reference line — this person's own median, drawn recessive. */
41
+ baseline?: {
42
+ value: number;
43
+ label: string;
44
+ } | null;
45
+ width?: number;
46
+ height?: number;
47
+ format?: (value: number) => string;
48
+ }
49
+ /**
50
+ * A single series over time, with an optional personal baseline.
51
+ *
52
+ * Line rather than area: the question is "where is this going", and an area
53
+ * fill implies a quantity accumulating under the curve, which a heart rate is
54
+ * not.
55
+ */
56
+ export declare function lineChart(points: SeriesPoint[], options: LineChartOptions): string;
57
+ export interface ColumnPoint {
58
+ label: string;
59
+ value: number;
60
+ }
61
+ export interface ColumnChartOptions {
62
+ label: string;
63
+ width?: number;
64
+ height?: number;
65
+ format?: (value: number) => string;
66
+ }
67
+ /**
68
+ * Magnitude over a short run of periods.
69
+ *
70
+ * Bars are capped at 24px and always leave a 2px gap, so neighbours read apart
71
+ * because of the air between them rather than because of a stroke drawn round
72
+ * each one. Only the largest bar is labelled: a number on every column is
73
+ * noise, and the tooltip and the table carry the rest.
74
+ */
75
+ export declare function columnChart(points: ColumnPoint[], options: ColumnChartOptions): string;
76
+ export interface DumbbellRow {
77
+ label: string;
78
+ unit: string;
79
+ current: number | null;
80
+ previous: number | null;
81
+ }
82
+ /**
83
+ * This week against last week, one row per metric.
84
+ *
85
+ * A dumbbell rather than a paired bar chart, and emphasis rather than two
86
+ * categorical hues, for one reason: THESE METRICS DO NOT SHARE AN AXIS. TRIMP
87
+ * and hours and session counts cannot be measured against one scale, and a
88
+ * single chart with two y-axes is the most reliable way to mislead someone.
89
+ * Each row is scaled to its own two values, which is a small multiple.
90
+ *
91
+ * Colour claims nothing about direction. Training load falling 38% is a lapse
92
+ * in January and the entire point of a taper, and a red bar would call it a
93
+ * failure either way -- so last week is recessive grey, this week is the accent,
94
+ * and the reader takes the direction from which way the dot moved.
95
+ */
96
+ export declare function dumbbellChart(rows: DumbbellRow[], options?: {
97
+ width?: number;
98
+ }): string;
99
+ //# sourceMappingURL=dashboardCharts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardCharts.d.ts","sourceRoot":"","sources":["../src/dashboardCharts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAuBjC,qFAAqF;AACrF,eAAO,MAAM,YAAY;;;;;IAKvB,8FAA8F;;IAE9F;;;;;;;;OAQG;;;;CAIK,CAAC;AAEX,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AA4BD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,iBAAmB,GAAG,WAAW,EAAE,CAepG;AA+BD,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA2ElF;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA6DtF;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAiE3F"}
@@ -0,0 +1,317 @@
1
+ import { DateTime } from "luxon";
2
+ // SECTION: Charts — inline SVG, no library, no CDN
3
+ //
4
+ // Every chart on the dashboard is built here, as a pure function from data to
5
+ // an SVG string. Three reasons it is not a charting library.
6
+ //
7
+ // This server is reached over a public tunnel from a phone. A CDN script tag
8
+ // would tell a third party every time the user opened their own health
9
+ // dashboard, and would leave the page blank on a train. Nothing here loads.
10
+ //
11
+ // A pure function can be tested. Chart bugs are geometry bugs -- a bar taller
12
+ // than its own axis, a line interpolated across a week the watch was not worn
13
+ // -- and geometry is exactly what a unit test is good at. A canvas rendered in
14
+ // a browser is not.
15
+ //
16
+ // And the rule that matters most for this product: A MISSING DAY IS A GAP, NOT
17
+ // A ZERO. An unworn watch is not a resting heart rate of nothing. Every path
18
+ // below breaks at an absence rather than drawing through it, because a line
19
+ // that slides smoothly across four unrecorded days is a measurement the chart
20
+ // invented -- the same mistake, in pixels, that this codebase has now fixed
21
+ // four times in prose.
22
+ /** Chart ink. Mirrors the CSS custom properties; SVG attributes cannot read them. */
23
+ export const CHART_COLORS = {
24
+ surface: "#141C2E",
25
+ grid: "#22304A",
26
+ ink: "#E6EDF5",
27
+ muted: "#8FA3BD",
28
+ /** Single-series hue. Blue, the documented sequential default, stepped for a dark surface. */
29
+ series: "#3987E5",
30
+ /**
31
+ * Green is #4CD964, not the mint #3DDC84 it started as, because of a device
32
+ * this file never renders on. The Forerunner 55 has an EIGHT-COLOUR palette
33
+ * and Connect IQ snaps every colour to the nearest entry -- #3DDC84 lands on
34
+ * CYAN, so "good" would reach that wrist as a colour carrying no meaning in
35
+ * this system. One palette across the browser and the watch is worth more
36
+ * than the exact shade, so the shade moved. Contrast on the card surface is
37
+ * 9.2:1 either way.
38
+ */
39
+ good: "#4CD964",
40
+ caution: "#F5A623",
41
+ hard: "#E5484D",
42
+ };
43
+ function escapeXml(value) {
44
+ return value
45
+ .replace(/&/g, "&amp;")
46
+ .replace(/</g, "&lt;")
47
+ .replace(/>/g, "&gt;")
48
+ .replace(/"/g, "&quot;");
49
+ }
50
+ function round(value, places = 2) {
51
+ const factor = 10 ** places;
52
+ return Math.round(value * factor) / factor;
53
+ }
54
+ /**
55
+ * A chart with nothing to draw says so.
56
+ *
57
+ * Not an empty axis, which reads as "zero everywhere" -- the distinction this
58
+ * whole file exists to preserve.
59
+ */
60
+ function emptyChart(width, height, message) {
61
+ return `<svg class="chart" viewBox="0 0 ${width} ${height}" role="img" aria-label="${escapeXml(message)}" preserveAspectRatio="none">
62
+ <text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle"
63
+ fill="${CHART_COLORS.muted}" font-size="13">${escapeXml(message)}</text>
64
+ </svg>`;
65
+ }
66
+ /**
67
+ * Fill in every day in the range, marking the ones with no measurement null.
68
+ *
69
+ * The store only holds a row for a day that was actually recorded, so an array
70
+ * of points is not a timeline -- it is a list of the days that happened to have
71
+ * data. Plotting it by index puts a three-week gap and a one-day gap the same
72
+ * distance apart.
73
+ */
74
+ export function densify(points, days, today = DateTime.local()) {
75
+ const byDate = new Map();
76
+ for (const point of points) {
77
+ byDate.set(point.date, point.value);
78
+ }
79
+ const out = [];
80
+ const start = today.startOf("day").minus({ days: days - 1 });
81
+ for (let i = 0; i < days; i += 1) {
82
+ const date = start.plus({ days: i }).toISODate();
83
+ if (date) {
84
+ out.push({ date, value: byDate.get(date) ?? null });
85
+ }
86
+ }
87
+ return out;
88
+ }
89
+ /**
90
+ * A y-range with headroom, never a zero-height one.
91
+ *
92
+ * A flat series (every value identical) would otherwise divide by zero and put
93
+ * every point at the same pixel with no axis to read it against.
94
+ */
95
+ function scaleOf(values, includeZero) {
96
+ if (values.length === 0) {
97
+ return { min: 0, max: 1 };
98
+ }
99
+ let min = Math.min(...values);
100
+ let max = Math.max(...values);
101
+ if (includeZero) {
102
+ min = Math.min(0, min);
103
+ max = Math.max(0, max);
104
+ }
105
+ if (min === max) {
106
+ const pad = Math.abs(max) > 0 ? Math.abs(max) * 0.1 : 1;
107
+ return { min: min - pad, max: max + pad };
108
+ }
109
+ const pad = (max - min) * 0.12;
110
+ return { min: min - (includeZero && min === 0 ? 0 : pad), max: max + pad };
111
+ }
112
+ /**
113
+ * A single series over time, with an optional personal baseline.
114
+ *
115
+ * Line rather than area: the question is "where is this going", and an area
116
+ * fill implies a quantity accumulating under the curve, which a heart rate is
117
+ * not.
118
+ */
119
+ export function lineChart(points, options) {
120
+ const width = options.width ?? 320;
121
+ const height = options.height ?? 110;
122
+ const padLeft = 34;
123
+ const padRight = 10;
124
+ const padTop = 10;
125
+ const padBottom = 18;
126
+ const measured = points.filter((p) => p.value !== null);
127
+ if (measured.length === 0) {
128
+ return emptyChart(width, height, "Nothing recorded yet");
129
+ }
130
+ const format = options.format ?? ((value) => String(round(value, 1)));
131
+ const values = measured.map((p) => p.value);
132
+ if (options.baseline) {
133
+ values.push(options.baseline.value);
134
+ }
135
+ const scale = scaleOf(values, false);
136
+ const plotWidth = width - padLeft - padRight;
137
+ const plotHeight = height - padTop - padBottom;
138
+ const x = (index) => padLeft + (points.length <= 1 ? plotWidth / 2 : (index / (points.length - 1)) * plotWidth);
139
+ const y = (value) => padTop + plotHeight - ((value - scale.min) / (scale.max - scale.min)) * plotHeight;
140
+ // Break the path at every absence. `M` starts a new subpath, so an unworn
141
+ // week leaves a hole instead of a straight line pretending to be data.
142
+ const segments = [];
143
+ let open = false;
144
+ points.forEach((point, index) => {
145
+ if (point.value === null) {
146
+ open = false;
147
+ return;
148
+ }
149
+ segments.push(`${open ? "L" : "M"}${round(x(index))} ${round(y(point.value))}`);
150
+ open = true;
151
+ });
152
+ const last = [...points].reverse().find((p) => p.value !== null);
153
+ const lastIndex = last ? points.findIndex((p) => p.date === last.date) : -1;
154
+ const baselineMarkup = options.baseline
155
+ ? `<line x1="${padLeft}" x2="${width - padRight}" y1="${round(y(options.baseline.value))}" y2="${round(y(options.baseline.value))}"
156
+ stroke="${CHART_COLORS.muted}" stroke-width="1" stroke-dasharray="3 3" opacity="0.7"><title>${escapeXml(options.baseline.label)}</title></line>`
157
+ : "";
158
+ const dots = points
159
+ .map((point, index) => point.value === null
160
+ ? ""
161
+ : `<circle cx="${round(x(index))}" cy="${round(y(point.value))}" r="4"
162
+ fill="${CHART_COLORS.series}" stroke="${CHART_COLORS.surface}" stroke-width="2"
163
+ class="dot"><title>${escapeXml(point.date)}: ${escapeXml(format(point.value))}${escapeXml(options.unit ?? "")}</title></circle>`)
164
+ .join("");
165
+ return `<svg class="chart" viewBox="0 0 ${width} ${height}" role="img"
166
+ aria-label="${escapeXml(options.label)}" preserveAspectRatio="none">
167
+ <line x1="${padLeft}" x2="${width - padRight}" y1="${padTop}" y2="${padTop}" stroke="${CHART_COLORS.grid}" stroke-width="1"/>
168
+ <line x1="${padLeft}" x2="${width - padRight}" y1="${padTop + plotHeight}" y2="${padTop + plotHeight}" stroke="${CHART_COLORS.grid}" stroke-width="1"/>
169
+ <text x="4" y="${padTop + 4}" fill="${CHART_COLORS.muted}" font-size="10">${escapeXml(format(scale.max))}</text>
170
+ <text x="4" y="${padTop + plotHeight}" fill="${CHART_COLORS.muted}" font-size="10">${escapeXml(format(scale.min))}</text>
171
+ ${baselineMarkup}
172
+ <path d="${segments.join(" ")}" fill="none" stroke="${CHART_COLORS.series}" stroke-width="2"
173
+ stroke-linejoin="round" stroke-linecap="round"/>
174
+ ${dots}
175
+ ${lastIndex >= 0 && last?.value !== null && last !== undefined
176
+ ? `<text x="${width - padRight}" y="${round(y(last.value)) - 8}" text-anchor="end"
177
+ fill="${CHART_COLORS.ink}" font-size="11">${escapeXml(format(last.value))}${escapeXml(options.unit ?? "")}</text>`
178
+ : ""}
179
+ </svg>`;
180
+ }
181
+ /**
182
+ * Magnitude over a short run of periods.
183
+ *
184
+ * Bars are capped at 24px and always leave a 2px gap, so neighbours read apart
185
+ * because of the air between them rather than because of a stroke drawn round
186
+ * each one. Only the largest bar is labelled: a number on every column is
187
+ * noise, and the tooltip and the table carry the rest.
188
+ */
189
+ export function columnChart(points, options) {
190
+ const width = options.width ?? 320;
191
+ const height = options.height ?? 110;
192
+ const padLeft = 34;
193
+ const padRight = 10;
194
+ const padTop = 14;
195
+ const padBottom = 16;
196
+ if (points.length === 0) {
197
+ return emptyChart(width, height, "Nothing recorded yet");
198
+ }
199
+ const format = options.format ?? ((value) => String(round(value, 2)));
200
+ const maxValue = Math.max(...points.map((p) => p.value));
201
+ // Every column zero is a real and common answer -- a month with no AI calls.
202
+ // It must draw as a flat empty axis, not divide by zero. Drawn short, too:
203
+ // at full height the "nothing" state reserved as much room as a month of
204
+ // data and left a hole in the page.
205
+ if (maxValue <= 0) {
206
+ const flat = 54;
207
+ return `<svg class="chart" viewBox="0 0 ${width} ${flat}" role="img" aria-label="${escapeXml(options.label)}" preserveAspectRatio="none">
208
+ <line x1="${padLeft}" x2="${width - padRight}" y1="${flat - 14}" y2="${flat - 14}" stroke="${CHART_COLORS.grid}" stroke-width="1"/>
209
+ <text x="${width / 2}" y="${flat / 2 - 4}" text-anchor="middle" fill="${CHART_COLORS.muted}" font-size="12">Nothing spent</text>
210
+ </svg>`;
211
+ }
212
+ const plotWidth = width - padLeft - padRight;
213
+ const plotHeight = height - padTop - padBottom;
214
+ const slot = plotWidth / points.length;
215
+ const barWidth = Math.max(1, Math.min(24, slot - 2));
216
+ const radius = Math.min(4, barWidth / 2);
217
+ const bars = points
218
+ .map((point, index) => {
219
+ const barHeight = (point.value / maxValue) * plotHeight;
220
+ const bx = round(padLeft + index * slot + (slot - barWidth) / 2);
221
+ const by = round(padTop + plotHeight - barHeight);
222
+ const title = `${escapeXml(point.label)}: ${escapeXml(format(point.value))}`;
223
+ if (barHeight <= 0) {
224
+ // A recorded zero still gets a hit target, so hovering an empty day
225
+ // says "nothing on this day" rather than nothing at all.
226
+ return `<rect x="${bx}" y="${round(padTop + plotHeight - 1)}" width="${round(barWidth)}" height="1"
227
+ fill="${CHART_COLORS.grid}" class="bar"><title>${title}</title></rect>`;
228
+ }
229
+ return `<rect x="${bx}" y="${by}" width="${round(barWidth)}" height="${round(barHeight)}"
230
+ rx="${round(radius)}" fill="${CHART_COLORS.series}" class="bar"><title>${title}</title></rect>`;
231
+ })
232
+ .join("");
233
+ const peakIndex = points.findIndex((p) => p.value === maxValue);
234
+ const peakX = round(padLeft + peakIndex * slot + slot / 2);
235
+ const peakY = round(padTop + plotHeight - (maxValue / maxValue) * plotHeight) - 4;
236
+ return `<svg class="chart" viewBox="0 0 ${width} ${height}" role="img"
237
+ aria-label="${escapeXml(options.label)}" preserveAspectRatio="none">
238
+ <line x1="${padLeft}" x2="${width - padRight}" y1="${padTop + plotHeight}" y2="${padTop + plotHeight}" stroke="${CHART_COLORS.grid}" stroke-width="1"/>
239
+ <text x="4" y="${padTop + 4}" fill="${CHART_COLORS.muted}" font-size="10">${escapeXml(format(maxValue))}</text>
240
+ ${bars}
241
+ <text x="${peakX}" y="${peakY}" text-anchor="middle" fill="${CHART_COLORS.ink}" font-size="11">${escapeXml(format(maxValue))}</text>
242
+ </svg>`;
243
+ }
244
+ /**
245
+ * This week against last week, one row per metric.
246
+ *
247
+ * A dumbbell rather than a paired bar chart, and emphasis rather than two
248
+ * categorical hues, for one reason: THESE METRICS DO NOT SHARE AN AXIS. TRIMP
249
+ * and hours and session counts cannot be measured against one scale, and a
250
+ * single chart with two y-axes is the most reliable way to mislead someone.
251
+ * Each row is scaled to its own two values, which is a small multiple.
252
+ *
253
+ * Colour claims nothing about direction. Training load falling 38% is a lapse
254
+ * in January and the entire point of a taper, and a red bar would call it a
255
+ * failure either way -- so last week is recessive grey, this week is the accent,
256
+ * and the reader takes the direction from which way the dot moved.
257
+ */
258
+ export function dumbbellChart(rows, options = {}) {
259
+ const usable = rows.filter((row) => row.current !== null && row.previous !== null);
260
+ if (usable.length === 0) {
261
+ return emptyChart(options.width ?? 320, 80, "Not enough history to compare weeks");
262
+ }
263
+ const width = options.width ?? 320;
264
+ const rowHeight = 34;
265
+ // The legend sits above the rows and needs clearance from the first label.
266
+ // At 18px the first row's text ran through the legend swatches.
267
+ const firstRowY = 34;
268
+ const height = usable.length * rowHeight + firstRowY + 6;
269
+ const labelWidth = 96;
270
+ const padRight = 46;
271
+ const trackWidth = width - labelWidth - padRight;
272
+ const body = usable
273
+ .map((row, index) => {
274
+ const current = row.current;
275
+ const previous = row.previous;
276
+ const unchanged = current === previous;
277
+ // Each row is scaled from ZERO to its own larger value, not from its
278
+ // smaller value to its larger one.
279
+ //
280
+ // Scaling min..max was the first attempt and it is worthless: the lower
281
+ // value always lands at one end and the higher at the other, so every row
282
+ // draws the identical length and the bar carries no information at all. A
283
+ // 1.7% move in resting heart rate and a 38% drop in training load came out
284
+ // the same size. Anchored at zero, the length is the relative change --
285
+ // which is the only comparison that means anything across metrics that
286
+ // share no unit.
287
+ const max = Math.max(current, previous, 1);
288
+ const px = labelWidth + (previous / max) * trackWidth;
289
+ const cx = labelWidth + (current / max) * trackWidth;
290
+ const y = firstRowY + index * rowHeight;
291
+ return `
292
+ <text x="0" y="${y + 4}" fill="${CHART_COLORS.muted}" font-size="11">${escapeXml(row.label)}</text>
293
+ <line x1="${round(px)}" x2="${round(cx)}" y1="${y}" y2="${y}" stroke="${CHART_COLORS.grid}" stroke-width="2" stroke-linecap="round"/>
294
+ ${unchanged
295
+ ? // Both weeks land on the same point. Drawn as a grey halo behind the
296
+ // accent dot: with the normal marks, this week's 2px surface ring
297
+ // covers last week's dot completely and "no change" renders as "last
298
+ // week is missing" -- an absence, which is the one thing this codebase
299
+ // must never draw a measurement as.
300
+ `<circle cx="${round(cx)}" cy="${y}" r="8" fill="${CHART_COLORS.muted}" opacity="0.45"><title>No change: ${escapeXml(String(current))}${escapeXml(row.unit)}</title></circle>
301
+ <circle cx="${round(cx)}" cy="${y}" r="4" fill="${CHART_COLORS.series}"><title>This week: ${escapeXml(String(current))}${escapeXml(row.unit)}</title></circle>`
302
+ : `<circle cx="${round(px)}" cy="${y}" r="4" fill="${CHART_COLORS.muted}" stroke="${CHART_COLORS.surface}" stroke-width="2"><title>Last week: ${escapeXml(String(previous))}${escapeXml(row.unit)}</title></circle>
303
+ <circle cx="${round(cx)}" cy="${y}" r="5" fill="${CHART_COLORS.series}" stroke="${CHART_COLORS.surface}" stroke-width="2"><title>This week: ${escapeXml(String(current))}${escapeXml(row.unit)}</title></circle>`}
304
+ <text x="${width}" y="${y + 4}" text-anchor="end" fill="${CHART_COLORS.ink}" font-size="11">${escapeXml(String(current))}${escapeXml(row.unit)}</text>`;
305
+ })
306
+ .join("");
307
+ // Two marks means a legend, always. Identity never rests on colour alone.
308
+ return `<svg class="chart" viewBox="0 0 ${width} ${height}" role="img"
309
+ aria-label="This week against last week" preserveAspectRatio="none">
310
+ <circle cx="4" cy="6" r="4" fill="${CHART_COLORS.muted}"/>
311
+ <text x="13" y="10" fill="${CHART_COLORS.muted}" font-size="10">last week</text>
312
+ <circle cx="76" cy="6" r="5" fill="${CHART_COLORS.series}"/>
313
+ <text x="86" y="10" fill="${CHART_COLORS.muted}" font-size="10">this week</text>
314
+ ${body}
315
+ </svg>`;
316
+ }
317
+ //# sourceMappingURL=dashboardCharts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardCharts.js","sourceRoot":"","sources":["../src/dashboardCharts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import { DateTime } from "luxon";
2
+ import { type MetricState, type TrainBudProfile } from "./profile.js";
3
+ import { type AiSpend, type BudgetState, type DailySpend, type FeatureCount } from "./usage.js";
4
+ import { type DumbbellRow, type SeriesPoint } from "./dashboardCharts.js";
5
+ export interface DashboardContextRow {
6
+ id: number;
7
+ kind: string;
8
+ text: string;
9
+ effective_from: string;
10
+ effective_to: string | null;
11
+ }
12
+ export interface DashboardTile {
13
+ key: string;
14
+ label: string;
15
+ value: string;
16
+ /** The comparison that makes the value mean something, or null. */
17
+ note: string | null;
18
+ state: MetricState;
19
+ }
20
+ export interface DashboardTrend {
21
+ points: SeriesPoint[];
22
+ /** This person's own median over the window, for the reference line. */
23
+ baseline: number | null;
24
+ unit: string;
25
+ }
26
+ export interface DashboardWeek {
27
+ ready: boolean;
28
+ headline: string;
29
+ rows: DumbbellRow[];
30
+ forecastRatio: number | null;
31
+ forecastVerdict: string;
32
+ sleepDebtHours: number | null;
33
+ }
34
+ export interface DashboardFinding {
35
+ severity: string;
36
+ headline: string;
37
+ detail: string;
38
+ }
39
+ export interface DashboardStatus {
40
+ pending: {
41
+ code: string;
42
+ expires_in: number;
43
+ }[];
44
+ ai_configured: boolean;
45
+ insight: string | null;
46
+ public_url: string;
47
+ context: DashboardContextRow[];
48
+ }
49
+ export interface DashboardData extends DashboardStatus {
50
+ profile: TrainBudProfile;
51
+ tiles: DashboardTile[];
52
+ findings: DashboardFinding[];
53
+ /** The one sentence that explains an empty findings list. Null when it is genuinely empty. */
54
+ coverageNote: string | null;
55
+ coverageDays: number;
56
+ coverageThrough: string | null;
57
+ week: DashboardWeek;
58
+ trends: {
59
+ restingHr: DashboardTrend;
60
+ sleep: DashboardTrend;
61
+ stress: DashboardTrend;
62
+ };
63
+ race: {
64
+ text: string;
65
+ daysAway: number;
66
+ phase: string;
67
+ } | null;
68
+ usage: {
69
+ month: AiSpend;
70
+ budget: BudgetState;
71
+ daily: DailySpend[];
72
+ features: FeatureCount[];
73
+ };
74
+ }
75
+ /**
76
+ * What to call the most recent night.
77
+ *
78
+ * "Last night" is a claim about a date, and the store's newest night is only
79
+ * last night if it was recorded. Read at two in the morning the newest row is
80
+ * the night BEFORE last, and the tile said "Last night" over it -- the same
81
+ * fault as the sleep card calling a fortnight-old night "last night", which
82
+ * this project has already fixed once on the watch.
83
+ */
84
+ export declare function nightLabel(date: string | null, today?: DateTime<true>): string;
85
+ export declare function getDashboardStatus(publicUrl?: string): DashboardStatus;
86
+ export declare function getDashboardData(publicUrl?: string): DashboardData;
87
+ /** Tests only. */
88
+ export declare const __nightLabelForTests: typeof nightLabel;
89
+ //# sourceMappingURL=dashboardData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardData.d.ts","sourceRoot":"","sources":["../src/dashboardData.ts"],"names":[],"mappings":"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"}