things-api 0.9.0 → 0.11.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 (261) hide show
  1. package/README.md +57 -12
  2. package/dist/audit/log.js +56 -2
  3. package/dist/audit/log.js.map +1 -1
  4. package/dist/audit/schema.d.ts +26 -8
  5. package/dist/audit/schema.js +42 -1
  6. package/dist/audit/schema.js.map +1 -1
  7. package/dist/cli/clock.d.ts +8 -0
  8. package/dist/cli/clock.js +24 -0
  9. package/dist/cli/clock.js.map +1 -0
  10. package/dist/cli/commands/area.d.ts +26 -3
  11. package/dist/cli/commands/area.js +129 -75
  12. package/dist/cli/commands/area.js.map +1 -1
  13. package/dist/cli/commands/doctor.d.ts +1 -1
  14. package/dist/cli/commands/doctor.js +44 -5
  15. package/dist/cli/commands/doctor.js.map +1 -1
  16. package/dist/cli/commands/install-skill.d.ts +45 -0
  17. package/dist/cli/commands/install-skill.js +207 -0
  18. package/dist/cli/commands/install-skill.js.map +1 -0
  19. package/dist/cli/commands/mcp.js +23 -4
  20. package/dist/cli/commands/mcp.js.map +1 -1
  21. package/dist/cli/commands/project.d.ts +18 -1
  22. package/dist/cli/commands/project.js +74 -35
  23. package/dist/cli/commands/project.js.map +1 -1
  24. package/dist/cli/commands/reads.d.ts +15 -2
  25. package/dist/cli/commands/reads.js +459 -165
  26. package/dist/cli/commands/reads.js.map +1 -1
  27. package/dist/cli/commands/repeat-flags.d.ts +20 -0
  28. package/dist/cli/commands/repeat-flags.js +76 -0
  29. package/dist/cli/commands/repeat-flags.js.map +1 -0
  30. package/dist/cli/commands/setup.js +8 -4
  31. package/dist/cli/commands/setup.js.map +1 -1
  32. package/dist/cli/commands/show.js +53 -30
  33. package/dist/cli/commands/show.js.map +1 -1
  34. package/dist/cli/commands/todo.d.ts +1 -1
  35. package/dist/cli/commands/todo.js +20 -13
  36. package/dist/cli/commands/todo.js.map +1 -1
  37. package/dist/cli/commands/writes.js +388 -161
  38. package/dist/cli/commands/writes.js.map +1 -1
  39. package/dist/cli/did-you-mean.d.ts +1 -1
  40. package/dist/cli/excess-args.d.ts +15 -0
  41. package/dist/cli/excess-args.js +51 -0
  42. package/dist/cli/excess-args.js.map +1 -0
  43. package/dist/cli/glyphs.d.ts +55 -2
  44. package/dist/cli/glyphs.js +114 -21
  45. package/dist/cli/glyphs.js.map +1 -1
  46. package/dist/cli/help.d.ts +54 -0
  47. package/dist/cli/help.js +405 -0
  48. package/dist/cli/help.js.map +1 -0
  49. package/dist/cli/main.js +64 -26
  50. package/dist/cli/main.js.map +1 -1
  51. package/dist/cli/move-hint.d.ts +45 -0
  52. package/dist/cli/move-hint.js +196 -0
  53. package/dist/cli/move-hint.js.map +1 -0
  54. package/dist/cli/period.d.ts +9 -8
  55. package/dist/cli/period.js +56 -30
  56. package/dist/cli/period.js.map +1 -1
  57. package/dist/cli/read-driver.d.ts +26 -19
  58. package/dist/cli/read-driver.js +77 -33
  59. package/dist/cli/read-driver.js.map +1 -1
  60. package/dist/cli/render.d.ts +92 -28
  61. package/dist/cli/render.js +333 -103
  62. package/dist/cli/render.js.map +1 -1
  63. package/dist/cli/resolve-invocation.d.ts +42 -4
  64. package/dist/cli/resolve-invocation.js +97 -14
  65. package/dist/cli/resolve-invocation.js.map +1 -1
  66. package/dist/cli/skill-check.d.ts +21 -0
  67. package/dist/cli/skill-check.js +82 -0
  68. package/dist/cli/skill-check.js.map +1 -0
  69. package/dist/cli/skill.d.ts +62 -0
  70. package/dist/cli/skill.js +142 -0
  71. package/dist/cli/skill.js.map +1 -0
  72. package/dist/cli/tag-filters.d.ts +63 -0
  73. package/dist/cli/tag-filters.js +59 -0
  74. package/dist/cli/tag-filters.js.map +1 -0
  75. package/dist/cli/verb-hint.d.ts +25 -0
  76. package/dist/cli/verb-hint.js +163 -0
  77. package/dist/cli/verb-hint.js.map +1 -0
  78. package/dist/cli/version.d.ts +4 -0
  79. package/dist/cli/version.js +18 -0
  80. package/dist/cli/version.js.map +1 -0
  81. package/dist/cli/width.d.ts +135 -0
  82. package/dist/cli/width.js +313 -0
  83. package/dist/cli/width.js.map +1 -0
  84. package/dist/client.d.ts +160 -24
  85. package/dist/client.js +132 -19
  86. package/dist/client.js.map +1 -1
  87. package/dist/config.d.ts +11 -0
  88. package/dist/config.js +3 -0
  89. package/dist/config.js.map +1 -1
  90. package/dist/contracts.d.ts +97 -17
  91. package/dist/contracts.js +44 -1
  92. package/dist/contracts.js.map +1 -1
  93. package/dist/db/fingerprint.d.ts +12 -0
  94. package/dist/db/fingerprint.js +15 -1
  95. package/dist/db/fingerprint.js.map +1 -1
  96. package/dist/db/locate.js +1 -1
  97. package/dist/db/locate.js.map +1 -1
  98. package/dist/diagnose.d.ts +63 -0
  99. package/dist/diagnose.js +38 -1
  100. package/dist/diagnose.js.map +1 -1
  101. package/dist/index.d.ts +36 -5
  102. package/dist/index.js +38 -2
  103. package/dist/index.js.map +1 -1
  104. package/dist/mcp/server.d.ts +9 -1
  105. package/dist/mcp/server.js +1038 -436
  106. package/dist/mcp/server.js.map +1 -1
  107. package/dist/model/clock.d.ts +61 -0
  108. package/dist/model/clock.js +71 -0
  109. package/dist/model/clock.js.map +1 -0
  110. package/dist/model/dates.d.ts +26 -3
  111. package/dist/model/dates.js +84 -3
  112. package/dist/model/dates.js.map +1 -1
  113. package/dist/model/entities.d.ts +48 -10
  114. package/dist/model/entities.js.map +1 -1
  115. package/dist/model/mappers.d.ts +9 -2
  116. package/dist/model/mappers.js +32 -9
  117. package/dist/model/mappers.js.map +1 -1
  118. package/dist/model/serialize.d.ts +28 -0
  119. package/dist/model/serialize.js +80 -0
  120. package/dist/model/serialize.js.map +1 -0
  121. package/dist/model/when-sugar.d.ts +47 -0
  122. package/dist/model/when-sugar.js +45 -0
  123. package/dist/model/when-sugar.js.map +1 -0
  124. package/dist/read/area-view.d.ts +8 -1
  125. package/dist/read/area-view.js +55 -17
  126. package/dist/read/area-view.js.map +1 -1
  127. package/dist/read/detail.d.ts +1 -1
  128. package/dist/read/detail.js +11 -4
  129. package/dist/read/detail.js.map +1 -1
  130. package/dist/read/filter-contract.d.ts +117 -0
  131. package/dist/read/filter-contract.js +78 -0
  132. package/dist/read/filter-contract.js.map +1 -0
  133. package/dist/read/log-boundary.d.ts +1 -1
  134. package/dist/read/log-boundary.js +13 -3
  135. package/dist/read/log-boundary.js.map +1 -1
  136. package/dist/read/predicates.d.ts +30 -0
  137. package/dist/read/predicates.js +30 -0
  138. package/dist/read/predicates.js.map +1 -1
  139. package/dist/read/project-view.d.ts +12 -1
  140. package/dist/read/project-view.js +45 -12
  141. package/dist/read/project-view.js.map +1 -1
  142. package/dist/read/queries.d.ts +152 -7
  143. package/dist/read/queries.js +277 -36
  144. package/dist/read/queries.js.map +1 -1
  145. package/dist/read/sections.d.ts +51 -0
  146. package/dist/read/sections.js +37 -0
  147. package/dist/read/sections.js.map +1 -0
  148. package/dist/read/sidebar-order.js +2 -1
  149. package/dist/read/sidebar-order.js.map +1 -1
  150. package/dist/read/snapshot.d.ts +1 -1
  151. package/dist/read/snapshot.js +9 -2
  152. package/dist/read/snapshot.js.map +1 -1
  153. package/dist/read/tags.d.ts +27 -3
  154. package/dist/read/tags.js +83 -12
  155. package/dist/read/tags.js.map +1 -1
  156. package/dist/read/truncation.d.ts +71 -0
  157. package/dist/read/{pagination.js → truncation.js} +103 -94
  158. package/dist/read/truncation.js.map +1 -0
  159. package/dist/read/views.d.ts +147 -22
  160. package/dist/read/views.js +282 -80
  161. package/dist/read/views.js.map +1 -1
  162. package/dist/surface-copy.d.ts +19 -0
  163. package/dist/surface-copy.js +32 -0
  164. package/dist/surface-copy.js.map +1 -1
  165. package/dist/sync-health.d.ts +78 -0
  166. package/dist/sync-health.js +312 -0
  167. package/dist/sync-health.js.map +1 -0
  168. package/dist/write/accessibility-probe.d.ts +12 -0
  169. package/dist/write/accessibility-probe.js +71 -0
  170. package/dist/write/accessibility-probe.js.map +1 -0
  171. package/dist/write/automation-probe.d.ts +8 -1
  172. package/dist/write/automation-probe.js +16 -1
  173. package/dist/write/automation-probe.js.map +1 -1
  174. package/dist/write/batch.js +5 -2
  175. package/dist/write/batch.js.map +1 -1
  176. package/dist/write/capabilities.d.ts +8 -0
  177. package/dist/write/capabilities.js +13 -6
  178. package/dist/write/capabilities.js.map +1 -1
  179. package/dist/write/commands.d.ts +3 -1
  180. package/dist/write/commands.js +602 -49
  181. package/dist/write/commands.js.map +1 -1
  182. package/dist/write/edit-checklist.js +3 -2
  183. package/dist/write/edit-checklist.js.map +1 -1
  184. package/dist/write/guards.d.ts +2 -7
  185. package/dist/write/guards.js +87 -6
  186. package/dist/write/guards.js.map +1 -1
  187. package/dist/write/heading.js +2 -0
  188. package/dist/write/heading.js.map +1 -1
  189. package/dist/write/lock.d.ts +40 -2
  190. package/dist/write/lock.js +91 -14
  191. package/dist/write/lock.js.map +1 -1
  192. package/dist/write/make-repeating-project.d.ts +4 -0
  193. package/dist/write/make-repeating-project.js +253 -0
  194. package/dist/write/make-repeating-project.js.map +1 -0
  195. package/dist/write/operations.d.ts +145 -1
  196. package/dist/write/operations.js +48 -0
  197. package/dist/write/operations.js.map +1 -1
  198. package/dist/write/pipeline.d.ts +73 -2
  199. package/dist/write/pipeline.js +218 -43
  200. package/dist/write/pipeline.js.map +1 -1
  201. package/dist/write/planner.js +8 -1
  202. package/dist/write/planner.js.map +1 -1
  203. package/dist/write/pre-state.d.ts +105 -3
  204. package/dist/write/pre-state.js +144 -3
  205. package/dist/write/pre-state.js.map +1 -1
  206. package/dist/write/recurrence-rule-blob.d.ts +65 -0
  207. package/dist/write/recurrence-rule-blob.js +150 -0
  208. package/dist/write/recurrence-rule-blob.js.map +1 -0
  209. package/dist/write/reopen.js +3 -2
  210. package/dist/write/reopen.js.map +1 -1
  211. package/dist/write/reorder.js +27 -17
  212. package/dist/write/reorder.js.map +1 -1
  213. package/dist/write/repeat-rule.d.ts +22 -0
  214. package/dist/write/repeat-rule.js +258 -0
  215. package/dist/write/repeat-rule.js.map +1 -0
  216. package/dist/write/reversibility.js +49 -0
  217. package/dist/write/reversibility.js.map +1 -1
  218. package/dist/write/tag-refs.d.ts +47 -0
  219. package/dist/write/tag-refs.js +126 -0
  220. package/dist/write/tag-refs.js.map +1 -0
  221. package/dist/write/undo.d.ts +74 -5
  222. package/dist/write/undo.js +493 -80
  223. package/dist/write/undo.js.map +1 -1
  224. package/dist/write/vectors/registry.d.ts +15 -1
  225. package/dist/write/vectors/registry.js +65 -2
  226. package/dist/write/vectors/registry.js.map +1 -1
  227. package/dist/write/vectors/simulator.d.ts +44 -0
  228. package/dist/write/vectors/simulator.js +1136 -0
  229. package/dist/write/vectors/simulator.js.map +1 -0
  230. package/dist/write/vectors/types.d.ts +154 -3
  231. package/dist/write/vectors/ui-certification.d.ts +54 -0
  232. package/dist/write/vectors/ui-certification.js +43 -0
  233. package/dist/write/vectors/ui-certification.js.map +1 -0
  234. package/dist/write/vectors/ui-drag.d.ts +188 -0
  235. package/dist/write/vectors/ui-drag.js +1095 -0
  236. package/dist/write/vectors/ui-drag.js.map +1 -0
  237. package/dist/write/vectors/ui-recipes.d.ts +83 -0
  238. package/dist/write/vectors/ui-recipes.js +610 -0
  239. package/dist/write/vectors/ui-recipes.js.map +1 -0
  240. package/dist/write/vectors/ui.d.ts +152 -0
  241. package/dist/write/vectors/ui.js +704 -0
  242. package/dist/write/vectors/ui.js.map +1 -0
  243. package/dist/write/verify/delta.d.ts +141 -4
  244. package/dist/write/verify/delta.js +199 -21
  245. package/dist/write/verify/delta.js.map +1 -1
  246. package/dist/write/verify/poller.d.ts +7 -1
  247. package/dist/write/verify/poller.js +21 -1
  248. package/dist/write/verify/poller.js.map +1 -1
  249. package/package.json +18 -3
  250. package/skills/things-cli/SKILL.md +53 -0
  251. package/skills/things-cli/references/contracts.md +41 -0
  252. package/skills/things-cli/references/gui.md +11 -0
  253. package/skills/things-cli/references/model.md +51 -0
  254. package/dist/cli/exit-codes.d.ts +0 -26
  255. package/dist/cli/exit-codes.js +0 -26
  256. package/dist/cli/exit-codes.js.map +0 -1
  257. package/dist/cli/output.d.ts +0 -42
  258. package/dist/cli/output.js +0 -16
  259. package/dist/cli/output.js.map +0 -1
  260. package/dist/read/pagination.d.ts +0 -104
  261. package/dist/read/pagination.js.map +0 -1
@@ -1,20 +1,27 @@
1
1
  import { mapChecklistItem, mapHeading, mapProject, mapTodo, } from "../model/mappers.js";
2
2
  import { decodeRecurrenceRule } from "../model/recurrence.js";
3
+ import { encodePackedDate, localToday } from "../model/dates.js";
3
4
  import { fetchChecklistRows, fetchTagsForTasks, fetchTaskByUuid, makeHeadingProjectResolver, makeRefResolver, } from "./queries.js";
4
5
  import { logBoundary, markLogged } from "./log-boundary.js";
5
6
  import { inheritedTagsFor } from "./tags.js";
6
- export function byUuid(db, uuid) {
7
+ // `now`/`zone` supply the evaluation clock used to gate `todaySection` to
8
+ // Today members (see mappers.mapTodaySection). They default to the host clock —
9
+ // matching this module's existing logBoundary default; the client facade passes
10
+ // the injected clock so a pinned-clock `show` reads under the consumer's Today.
11
+ export function byUuid(db, uuid, now = new Date(), zone) {
7
12
  const row = fetchTaskByUuid(db, uuid);
8
13
  if (!row)
9
14
  return null;
10
- return materializeOne(db, row);
15
+ return materializeOne(db, row, encodePackedDate(localToday(now, zone)));
11
16
  }
12
- function materializeOne(db, row) {
17
+ function materializeOne(db, row, packedToday) {
13
18
  const refs = makeRefResolver(db);
14
19
  if (row.type === 2)
15
20
  return mapHeading(row, refs);
16
21
  const tags = fetchTagsForTasks(db, [row.uuid]).get(row.uuid) ?? [];
17
- const entity = row.type === 1 ? mapProject(row, refs, tags) : mapTodo(row, refs, tags);
22
+ const entity = row.type === 1
23
+ ? mapProject(row, refs, tags, packedToday)
24
+ : mapTodo(row, refs, tags, packedToday);
18
25
  markLogged([entity], logBoundary(db));
19
26
  entity.inheritedTags = inheritedTagsFor(db, row);
20
27
  if (entity.type === "to-do") {
@@ -1 +1 @@
1
- {"version":3,"file":"detail.js","sourceRoot":"","sources":["../../src/read/detail.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,OAAO,GAER,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,0BAA0B,EAC1B,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,UAAU,MAAM,CAAC,EAAgB,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,cAAc,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,cAAc,CAAC,EAAgB,EAAE,GAAY;IACpD,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACnE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvF,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,aAAa,GAAG,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,SAAS,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,uEAAuE;QACvE,sDAAsD;QACtD,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,0BAA0B,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9D,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,IAAI,GAAG,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,CAAC,SAAS,CAAC,IAAI,GAAG,oBAAoB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,6DAA6D;QAC/D,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAgB,EAAE,QAAgB;IAC7D,OAAO,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"detail.js","sourceRoot":"","sources":["../../src/read/detail.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,OAAO,GAER,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,0BAA0B,EAC1B,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,0EAA0E;AAC1E,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,MAAM,UAAU,MAAM,CACpB,EAAgB,EAChB,IAAY,EACZ,MAAY,IAAI,IAAI,EAAE,EACtB,IAAa;IAEb,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,cAAc,CAAC,EAAgB,EAAE,GAAY,EAAE,WAAmB;IACzE,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACnE,MAAM,MAAM,GACV,GAAG,CAAC,IAAI,KAAK,CAAC;QACZ,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC;QAC1C,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAC5C,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,aAAa,GAAG,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,SAAS,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,uEAAuE;QACvE,sDAAsD;QACtD,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,0BAA0B,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9D,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,IAAI,GAAG,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,CAAC,SAAS,CAAC,IAAI,GAAG,oBAAoB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACvE,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,6DAA6D;QAC/D,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAgB,EAAE,QAAgB;IAC7D,OAAO,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The per-view filter contract — the ONE declarative statement of which read
3
+ * filters each view honors, plus the shared predicates that enforce them. Both
4
+ * consumer surfaces (CLI commands, MCP tools) derive their per-view guards from
5
+ * this table instead of hand-coding view lists, so a filter's applicability is
6
+ * stated once and can never drift between surfaces.
7
+ *
8
+ * The table says, per view: whether the `overdue` content scope applies; what
9
+ * tag semantics the view carries (inheritance-inclusive `inherited`, container-
10
+ * direct `direct`, or `rejected` where the view has no per-row tags to filter);
11
+ * the bound model the view truncates under (`flat` row cap, `grouped` per-block
12
+ * caps, or `none`); and whether the view offers the status-widening flags
13
+ * (search's logged/trashed/all) that `overdue` refuses to combine with.
14
+ *
15
+ * The exact usage-error COPY stays surface-owned (consumer voice differs per
16
+ * surface — CLI `--tag`, MCP `tag`; docs/design/surface-copy.md): a surface
17
+ * hands {@link validateViewArgs} its own phrasing via {@link FilterVocab}, and
18
+ * this module owns only the DECISION of which message applies.
19
+ */
20
+ import type { ViewFilter } from "./views.ts";
21
+ /** Every read view whose filter applicability the contract governs. */
22
+ export type ViewName = "today" | "inbox" | "anytime" | "someday" | "upcoming" | "logbook" | "trash" | "search" | "changes" | "projects" | "areas" | "project-show" | "area-show";
23
+ /**
24
+ * How a view's tag filter behaves:
25
+ * - `inherited` — FLAT views: a `--tag` matches direct OR container-inherited
26
+ * membership (plus hierarchy descendants).
27
+ * - `direct` — CONTAINER views (`project show`, `area show`): a `--tag` matches
28
+ * a tag carried DIRECTLY on the row (the container's own inherited tags are
29
+ * suppressed, since every child inherits them).
30
+ * - `rejected` — the view has no per-row tag list to filter (an area list row,
31
+ * a tag list row, the changes feed); tag flags do not apply.
32
+ */
33
+ export type TagSemantics = "inherited" | "direct" | "rejected";
34
+ /** The truncation model a view bounds under. */
35
+ export type BoundModel = "flat" | "grouped" | "none";
36
+ /** One row of {@link FILTER_CONTRACT}: a single view's filter applicability. */
37
+ export interface ViewFilterSpec {
38
+ /** Whether the `overdue` content scope (open, past-deadline) applies. */
39
+ readonly overdue: boolean;
40
+ /** The view's tag-filter semantics. */
41
+ readonly tag: TagSemantics;
42
+ /** The bound model the view truncates under. */
43
+ readonly bound: BoundModel;
44
+ /**
45
+ * Whether the view offers the status-widening flags (logged/trashed/all).
46
+ * Only `search` does; `overdue` refuses to combine with them there.
47
+ */
48
+ readonly statusWidening: boolean;
49
+ }
50
+ /**
51
+ * The single source of truth for read-filter applicability, one row per view.
52
+ * Consumed by both surfaces' per-view guards (CLI command actions, MCP tool
53
+ * handlers) so no surface hand-maintains its own view list.
54
+ */
55
+ export declare const FILTER_CONTRACT: Record<ViewName, ViewFilterSpec>;
56
+ /**
57
+ * The three universal tag-filter inputs in their canonical (CLI-flag) spelling.
58
+ * The CLI's parsed options match this verbatim; the MCP surface maps its
59
+ * snake_case inputs (`exact_tag`) onto it before calling the shared predicates.
60
+ */
61
+ export interface TagPresence {
62
+ tag?: readonly string[] | undefined;
63
+ exactTag?: boolean | undefined;
64
+ untagged?: boolean | undefined;
65
+ }
66
+ /** True when any tag-PRESENCE flag was passed (a positive filter, not a negation). */
67
+ export declare function hasTagPresence(a: TagPresence): boolean;
68
+ /**
69
+ * True when the tag flags are mutually incoherent: the `untagged` negation
70
+ * inverts a tag presence, so it does not combine with a tag-presence flag. A
71
+ * pure predicate — each surface emits its own usage error in its own voice.
72
+ */
73
+ export declare function tagFlagConflict(a: TagPresence): boolean;
74
+ /** Build the {@link ViewFilter} tag fields from the parsed flags (empty keys omitted). */
75
+ export declare function tagFilterFields(a: TagPresence): ViewFilter;
76
+ /** The parsed read-filter inputs {@link validateViewArgs} inspects. */
77
+ export interface FilterArgs extends TagPresence {
78
+ overdue?: boolean | undefined;
79
+ /** search only: the status-widening flags overdue refuses to combine with. */
80
+ logged?: boolean | undefined;
81
+ trashed?: boolean | undefined;
82
+ all?: boolean | undefined;
83
+ }
84
+ /**
85
+ * The surface's exact usage-error copy for each conflict {@link validateViewArgs}
86
+ * can detect. Built per call by the surface (it knows the view/kind and its own
87
+ * flag spellings), so the SHARED module decides WHICH message applies while the
88
+ * message text stays consumer-voiced per surface.
89
+ */
90
+ export interface FilterVocab {
91
+ /** `untagged` combined with a tag-presence flag. */
92
+ untaggedConflict: string;
93
+ /** `overdue` passed to a view that does not honor it. */
94
+ overdueRejected: string;
95
+ /** `overdue` combined with a status-widening flag (search). */
96
+ overdueStatusWiden: string;
97
+ }
98
+ /** {@link validateViewArgs} outcome: the built filter, or the usage message to emit. */
99
+ export type ViewValidation = {
100
+ ok: true;
101
+ filter: ViewFilter;
102
+ } | {
103
+ ok: false;
104
+ message: string;
105
+ };
106
+ /**
107
+ * Validate a view's filter arguments against {@link FILTER_CONTRACT} and, when
108
+ * coherent, build the {@link ViewFilter} tag+overdue portion. The checks (and
109
+ * their precedence) live here so both surfaces stay in lockstep; the surface
110
+ * supplies its own exact copy via {@link FilterVocab}.
111
+ *
112
+ * Does NOT enforce tag-REJECTION (a view refusing tag flags outright): that
113
+ * lives at the two call sites that currently reject — the areas/projects/tags
114
+ * collection listers — so this stays a pure no-op for the flat/container views
115
+ * that merely ignore tags on a sub-path (e.g. `trash`).
116
+ */
117
+ export declare function validateViewArgs(view: ViewName, args: FilterArgs, vocab: FilterVocab): ViewValidation;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The single source of truth for read-filter applicability, one row per view.
3
+ * Consumed by both surfaces' per-view guards (CLI command actions, MCP tool
4
+ * handlers) so no surface hand-maintains its own view list.
5
+ */
6
+ export const FILTER_CONTRACT = {
7
+ // Current-work flat views: overdue applies, tags are inheritance-inclusive.
8
+ today: { overdue: true, tag: "inherited", bound: "flat", statusWidening: false },
9
+ inbox: { overdue: true, tag: "inherited", bound: "flat", statusWidening: false },
10
+ // Grouped catalogues: overdue applies, per-block caps.
11
+ anytime: { overdue: true, tag: "inherited", bound: "grouped", statusWidening: false },
12
+ someday: { overdue: true, tag: "inherited", bound: "grouped", statusWidening: false },
13
+ // Forward-looking / closed-item flat views: overdue deliberately does NOT apply.
14
+ upcoming: { overdue: false, tag: "inherited", bound: "flat", statusWidening: false },
15
+ logbook: { overdue: false, tag: "inherited", bound: "flat", statusWidening: false },
16
+ trash: { overdue: false, tag: "rejected", bound: "flat", statusWidening: false },
17
+ // Search: overdue applies but refuses the status-widening flags.
18
+ search: { overdue: true, tag: "inherited", bound: "flat", statusWidening: true },
19
+ // Sync feed: neither overdue nor tags apply.
20
+ changes: { overdue: false, tag: "rejected", bound: "flat", statusWidening: false },
21
+ // Projects LIST is a FLAT view — each project row filtered by its own
22
+ // (inheritance-inclusive) tags; overdue keeps past-deadline projects.
23
+ projects: { overdue: true, tag: "inherited", bound: "none", statusWidening: false },
24
+ // Areas LIST rows carry no deadline and no per-row tag filter.
25
+ areas: { overdue: false, tag: "rejected", bound: "none", statusWidening: false },
26
+ // Single-container views: overdue and DIRECT-tag filtering apply to children.
27
+ "project-show": { overdue: true, tag: "direct", bound: "grouped", statusWidening: false },
28
+ "area-show": { overdue: true, tag: "direct", bound: "grouped", statusWidening: false },
29
+ };
30
+ /** True when any tag-PRESENCE flag was passed (a positive filter, not a negation). */
31
+ export function hasTagPresence(a) {
32
+ return (a.tag?.length ?? 0) > 0 || a.exactTag === true;
33
+ }
34
+ /**
35
+ * True when the tag flags are mutually incoherent: the `untagged` negation
36
+ * inverts a tag presence, so it does not combine with a tag-presence flag. A
37
+ * pure predicate — each surface emits its own usage error in its own voice.
38
+ */
39
+ export function tagFlagConflict(a) {
40
+ return a.untagged === true && hasTagPresence(a);
41
+ }
42
+ /** Build the {@link ViewFilter} tag fields from the parsed flags (empty keys omitted). */
43
+ export function tagFilterFields(a) {
44
+ return {
45
+ ...(a.tag !== undefined && a.tag.length > 0 && { tags: [...a.tag] }),
46
+ ...(a.exactTag === true && { exactTag: true }),
47
+ ...(a.untagged === true && { untagged: true }),
48
+ };
49
+ }
50
+ /**
51
+ * Validate a view's filter arguments against {@link FILTER_CONTRACT} and, when
52
+ * coherent, build the {@link ViewFilter} tag+overdue portion. The checks (and
53
+ * their precedence) live here so both surfaces stay in lockstep; the surface
54
+ * supplies its own exact copy via {@link FilterVocab}.
55
+ *
56
+ * Does NOT enforce tag-REJECTION (a view refusing tag flags outright): that
57
+ * lives at the two call sites that currently reject — the areas/projects/tags
58
+ * collection listers — so this stays a pure no-op for the flat/container views
59
+ * that merely ignore tags on a sub-path (e.g. `trash`).
60
+ */
61
+ export function validateViewArgs(view, args, vocab) {
62
+ const spec = FILTER_CONTRACT[view];
63
+ if (tagFlagConflict(args))
64
+ return { ok: false, message: vocab.untaggedConflict };
65
+ if (args.overdue === true && !spec.overdue) {
66
+ return { ok: false, message: vocab.overdueRejected };
67
+ }
68
+ if (args.overdue === true &&
69
+ spec.statusWidening &&
70
+ (args.logged === true || args.trashed === true || args.all === true)) {
71
+ return { ok: false, message: vocab.overdueStatusWiden };
72
+ }
73
+ return {
74
+ ok: true,
75
+ filter: { ...tagFilterFields(args), ...(args.overdue === true && { overdue: true }) },
76
+ };
77
+ }
78
+ //# sourceMappingURL=filter-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-contract.js","sourceRoot":"","sources":["../../src/read/filter-contract.ts"],"names":[],"mappings":"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"}
@@ -20,7 +20,7 @@
20
20
  * FORWARD past the interval's own edge.
21
21
  */
22
22
  import type { DatabaseSync } from "node:sqlite";
23
- export declare function logBoundary(db: DatabaseSync, now?: Date): Date;
23
+ export declare function logBoundary(db: DatabaseSync, now?: Date, zone?: string): Date;
24
24
  /** Stamp `logged` on mapped entities (closed AND at/before the boundary). */
25
25
  export declare function markLogged<T extends {
26
26
  status: string;
@@ -1,8 +1,18 @@
1
- export function logBoundary(db, now = new Date()) {
1
+ import { dayBoundInstant, localToday } from "../model/dates.js";
2
+ // `zone` (optional IANA zone) is threaded so the daily/weekly/monthly sweep
3
+ // edge is the CONSUMER'S local midnight, not the host's — byte-identical to a
4
+ // bare `new Date(now); setHours(0,…)` when absent. logInterval=0 (immediately,
5
+ // the golden default) is zone-independent (the boundary is `now`).
6
+ export function logBoundary(db, now = new Date(), zone) {
2
7
  const row = db.prepare("SELECT logInterval, manualLogDate FROM TMSettings").get();
3
8
  const manual = row?.manualLogDate != null ? new Date(row.manualLogDate * 1000) : null;
4
- const startOfDay = new Date(now);
5
- startOfDay.setHours(0, 0, 0, 0);
9
+ const startOfDay = zone === undefined
10
+ ? (() => {
11
+ const d = new Date(now);
12
+ d.setHours(0, 0, 0, 0);
13
+ return d;
14
+ })()
15
+ : dayBoundInstant(localToday(now, zone), "start", zone);
6
16
  let auto;
7
17
  switch (row?.logInterval ?? 0) {
8
18
  case 0:
@@ -1 +1 @@
1
- {"version":3,"file":"log-boundary.js","sourceRoot":"","sources":["../../src/read/log-boundary.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,WAAW,CAAC,EAAgB,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;IAC5D,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC,GAAG,EAElE,CAAC;IACd,MAAM,MAAM,GAAG,GAAG,EAAE,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtF,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,IAAI,IAAU,CAAC;IACf,QAAQ,GAAG,EAAE,WAAW,IAAI,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC;YACJ,IAAI,GAAG,GAAG,CAAC;YACX,MAAM;QACR,KAAK,CAAC;YACJ,IAAI,GAAG,UAAU,CAAC;YAClB,MAAM;QACR,KAAK,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACpC,IAAI,GAAG,CAAC,CAAC;YACT,MAAM;QACR,CAAC;QACD,KAAK,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACb,IAAI,GAAG,CAAC,CAAC;YACT,MAAM;QACR,CAAC;QACD;YACE,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CACxB,KAAU,EACV,QAAc;IAEd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"log-boundary.js","sourceRoot":"","sources":["../../src/read/log-boundary.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEhE,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAC/E,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,EAAgB,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,EAAE,IAAa;IAC3E,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC,GAAG,EAElE,CAAC;IACd,MAAM,MAAM,GAAG,GAAG,EAAE,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACtF,MAAM,UAAU,GACd,IAAI,KAAK,SAAS;QAChB,CAAC,CAAC,CAAC,GAAS,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACvB,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,IAAU,CAAC;IACf,QAAQ,GAAG,EAAE,WAAW,IAAI,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC;YACJ,IAAI,GAAG,GAAG,CAAC;YACX,MAAM;QACR,KAAK,CAAC;YACJ,IAAI,GAAG,UAAU,CAAC;YAClB,MAAM;QACR,KAAK,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACpC,IAAI,GAAG,CAAC,CAAC;YACT,MAAM;QACR,CAAC;QACD,KAAK,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACb,IAAI,GAAG,CAAC,CAAC;YACT,MAAM;QACR,CAAC;QACD;YACE,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CACxB,KAAU,EACV,QAAc;IAEd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -2,6 +2,36 @@
2
2
  export declare const LIVE = "t.type IN (0, 1) AND t.trashed = 0 AND (t.rt1_recurrenceRule IS NULL AND t.repeater IS NULL)";
3
3
  /** {@link LIVE} restricted to open (status = 0) rows. */
4
4
  export declare const OPEN = "t.type IN (0, 1) AND t.trashed = 0 AND (t.rt1_recurrenceRule IS NULL AND t.repeater IS NULL) AND t.status = 0";
5
+ /**
6
+ * The GUI-visible set: open rows PLUS closed (completed/canceled) rows the
7
+ * periodic log-move sweep has NOT yet carried to the Logbook — completion ≠
8
+ * logged (src/read/log-boundary.ts). A closed row keeps its slot in its list
9
+ * until the sweep passes it, exactly as the GUI keeps it checked in place; it
10
+ * leaves when the sweep boundary advances past its stopDate (boundary-relative,
11
+ * no new state). This is {@link LIVE} widened to that set: swept iff
12
+ * status IN (2,3) AND stopDate IS NOT NULL AND stopDate <= boundary — the
13
+ * negation of the {@link markLogged} `logged` predicate, so an included closed
14
+ * row always materializes with `logged=false`. Mirrors the project/area card
15
+ * precedent (project-view.ts / area-view.ts keep a closed-but-unswept row
16
+ * checked in place). ONE bind: the log boundary as epoch seconds
17
+ * (logBoundary(db, now).getTime() / 1000). Ruling 2026-07-14 (Mike): GUI parity
18
+ * — `today` and `anytime` show checked-but-unswept rows.
19
+ */
20
+ export declare const OPEN_OR_UNSWEPT = "t.type IN (0, 1) AND t.trashed = 0 AND (t.rt1_recurrenceRule IS NULL AND t.repeater IS NULL) AND NOT (t.status IN (2, 3) AND t.stopDate IS NOT NULL AND t.stopDate <= ?)";
21
+ /**
22
+ * The `--overdue` content scope: OPEN items whose deadline falls strictly
23
+ * BEFORE today. Due-TODAY is deliberately NOT overdue (`<`, not `<=`) —
24
+ * mirroring the app's own Today badge split, where a deadline EQUAL to today
25
+ * reads as "due" and only an EARLIER deadline reads as "overdue". One bind:
26
+ * today as a packed-date int (encodePackedDate(localToday(now))), so the
27
+ * boundary rides the same injected clock every other view uses — never a
28
+ * hardcoded date. The `t.status = 0` clause re-tightens the OPEN_OR_UNSWEPT
29
+ * views (today/anytime) so a checked-but-unswept row that happens to sit past
30
+ * a deadline is excluded — overdue is remaining, OPEN work. Trash exclusion is
31
+ * the hosting view's job (every view this composes into already drops trashed
32
+ * and derived-trashed rows), so it is not repeated here.
33
+ */
34
+ export declare const OVERDUE = "t.deadline IS NOT NULL AND t.deadline < ? AND t.status = 0";
5
35
  /** An item's own anytime membership: unscheduled-active, or dated <= today. */
6
36
  export declare const ANYTIME_SELF: (col: string) => string;
7
37
  /**
@@ -12,6 +12,36 @@ import { NOT_TEMPLATE } from "./queries.js";
12
12
  export const LIVE = `t.type IN (0, 1) AND t.trashed = 0 AND ${NOT_TEMPLATE}`;
13
13
  /** {@link LIVE} restricted to open (status = 0) rows. */
14
14
  export const OPEN = `${LIVE} AND t.status = 0`;
15
+ /**
16
+ * The GUI-visible set: open rows PLUS closed (completed/canceled) rows the
17
+ * periodic log-move sweep has NOT yet carried to the Logbook — completion ≠
18
+ * logged (src/read/log-boundary.ts). A closed row keeps its slot in its list
19
+ * until the sweep passes it, exactly as the GUI keeps it checked in place; it
20
+ * leaves when the sweep boundary advances past its stopDate (boundary-relative,
21
+ * no new state). This is {@link LIVE} widened to that set: swept iff
22
+ * status IN (2,3) AND stopDate IS NOT NULL AND stopDate <= boundary — the
23
+ * negation of the {@link markLogged} `logged` predicate, so an included closed
24
+ * row always materializes with `logged=false`. Mirrors the project/area card
25
+ * precedent (project-view.ts / area-view.ts keep a closed-but-unswept row
26
+ * checked in place). ONE bind: the log boundary as epoch seconds
27
+ * (logBoundary(db, now).getTime() / 1000). Ruling 2026-07-14 (Mike): GUI parity
28
+ * — `today` and `anytime` show checked-but-unswept rows.
29
+ */
30
+ export const OPEN_OR_UNSWEPT = `${LIVE} AND NOT (t.status IN (2, 3) AND t.stopDate IS NOT NULL AND t.stopDate <= ?)`;
31
+ /**
32
+ * The `--overdue` content scope: OPEN items whose deadline falls strictly
33
+ * BEFORE today. Due-TODAY is deliberately NOT overdue (`<`, not `<=`) —
34
+ * mirroring the app's own Today badge split, where a deadline EQUAL to today
35
+ * reads as "due" and only an EARLIER deadline reads as "overdue". One bind:
36
+ * today as a packed-date int (encodePackedDate(localToday(now))), so the
37
+ * boundary rides the same injected clock every other view uses — never a
38
+ * hardcoded date. The `t.status = 0` clause re-tightens the OPEN_OR_UNSWEPT
39
+ * views (today/anytime) so a checked-but-unswept row that happens to sit past
40
+ * a deadline is excluded — overdue is remaining, OPEN work. Trash exclusion is
41
+ * the hosting view's job (every view this composes into already drops trashed
42
+ * and derived-trashed rows), so it is not repeated here.
43
+ */
44
+ export const OVERDUE = `t.deadline IS NOT NULL AND t.deadline < ? AND t.status = 0`;
15
45
  /** An item's own anytime membership: unscheduled-active, or dated <= today. */
16
46
  export const ANYTIME_SELF = (col) => `((${col}.start = 1 AND (${col}.startDate IS NULL OR ${col}.startDate <= ?))
17
47
  OR (${col}.start = 2 AND ${col}.startDate IS NOT NULL AND ${col}.startDate <= ?))`;
@@ -1 +1 @@
1
- {"version":3,"file":"predicates.js","sourceRoot":"","sources":["../../src/read/predicates.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,oFAAoF;AACpF,MAAM,CAAC,MAAM,IAAI,GAAG,0CAA0C,YAAY,EAAE,CAAC;AAE7E,yDAAyD;AACzD,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,IAAI,mBAAmB,CAAC;AAE/C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE,CAClD,KAAK,GAAG,mBAAmB,GAAG,yBAAyB,GAAG;UAClD,GAAG,kBAAkB,GAAG,8BAA8B,GAAG,mBAAmB,CAAC;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,gFAAgF,CAAC;AAE5G;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,WAAW;6CACR,WAAW;8CACV,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;QAE3B,WAAW;+CAC4B,WAAW,uBAAuB,CAAC"}
1
+ {"version":3,"file":"predicates.js","sourceRoot":"","sources":["../../src/read/predicates.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,oFAAoF;AACpF,MAAM,CAAC,MAAM,IAAI,GAAG,0CAA0C,YAAY,EAAE,CAAC;AAE7E,yDAAyD;AACzD,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,IAAI,mBAAmB,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,IAAI,8EAA8E,CAAC;AAErH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,4DAA4D,CAAC;AAEpF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE,CAClD,KAAK,GAAG,mBAAmB,GAAG,yBAAyB,GAAG;UAClD,GAAG,kBAAkB,GAAG,8BAA8B,GAAG,mBAAmB,CAAC;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,gFAAgF,CAAC;AAE5G;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,WAAW;6CACR,WAAW;8CACV,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;QAE3B,WAAW;+CAC4B,WAAW,uBAAuB,CAAC"}
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import type { DatabaseSync } from "node:sqlite";
11
11
  import type { Heading, IsoDateGroup, Project, Todo } from "../model/entities.ts";
12
+ import { type ViewFilter } from "./views.ts";
12
13
  export interface ProjectView {
13
14
  project: Project;
14
15
  /** Open, unscheduled/current children not under a heading, by index. */
@@ -27,8 +28,18 @@ export interface ProjectView {
27
28
  };
28
29
  logged: Todo[];
29
30
  trashed: Todo[];
31
+ /**
32
+ * PLOG1 (additive): count of untrashed OPEN (status=0) children this project
33
+ * still holds while it is ITSELF completed or canceled — including once swept
34
+ * to the Logbook. Such items are invisible in every live app view (Today /
35
+ * Anytime / Inbox / Upcoming), reachable only by drilling into this card
36
+ * (the app's GUI "Put Back" into a completed parent can strand them —
37
+ * docs/lab/plog1-research.md). 0 when the project is open, or holds no such
38
+ * child.
39
+ */
40
+ openChildrenWhileResolved: number;
30
41
  }
31
42
  export declare class ProjectNotFoundError extends Error {
32
43
  constructor(uuid: string);
33
44
  }
34
- export declare function projectView(db: DatabaseSync, uuid: string, now?: Date): ProjectView;
45
+ export declare function projectView(db: DatabaseSync, uuid: string, now?: Date, filter?: ViewFilter, zone?: string): ProjectView;
@@ -2,37 +2,58 @@ import { encodePackedDate, localToday, decodePackedDate } from "../model/dates.j
2
2
  import { mapHeading, mapProject, mapTodo } from "../model/mappers.js";
3
3
  import { fetchTagsForTasks, fetchTaskByUuid, fetchTaskRows, makeRefResolver } from "./queries.js";
4
4
  import { logBoundary, markLogged } from "./log-boundary.js";
5
+ import { OVERDUE } from "./predicates.js";
5
6
  import { inheritedTagsFor } from "./tags.js";
7
+ import { tagFilter } from "./views.js";
6
8
  export class ProjectNotFoundError extends Error {
7
9
  constructor(uuid) {
8
10
  super(`no project with uuid ${uuid}`);
9
11
  this.name = "ProjectNotFoundError";
10
12
  }
11
13
  }
12
- export function projectView(db, uuid, now) {
14
+ export function projectView(db, uuid, now, filter = {}, zone) {
15
+ const overdue = filter.overdue === true;
13
16
  const projectRow = fetchTaskByUuid(db, uuid);
14
17
  if (!projectRow || projectRow.type !== 1)
15
18
  throw new ProjectNotFoundError(uuid);
16
19
  const refs = makeRefResolver(db);
20
+ // The view's injected clock — gates `todaySection` to Today members in the
21
+ // mapper AND drives the scheduled/overdue bucketing below.
22
+ const packedToday = encodePackedDate(localToday(now, zone));
17
23
  const tagsOf = (rows) => fetchTagsForTasks(db, rows.map((r) => r.uuid));
18
24
  const projectTags = tagsOf([projectRow]);
19
- const project = mapProject(projectRow, refs, projectTags.get(projectRow.uuid) ?? []);
25
+ const project = mapProject(projectRow, refs, projectTags.get(projectRow.uuid) ?? [], packedToday);
20
26
  // The card view surfaces area-inherited tags (the UI's tag filter honors them).
21
27
  project.inheritedTags = inheritedTagsFor(db, projectRow);
22
28
  const headingRows = fetchTaskRows(db, `t.type = 2 AND t.project = ? AND t.trashed = 0 ORDER BY t."index" ASC`, [uuid]);
23
29
  const headings = headingRows.map((h) => mapHeading(h, refs));
30
+ // OWN-DEADLINE UNIFORM: `--overdue` narrows the child TO-DOS to those whose
31
+ // OWN deadline is overdue (open, strictly before today) via the shared
32
+ // OVERDUE predicate — NO recursion into anything, and the project header
33
+ // itself always renders. Headings that keep no surviving child collapse
34
+ // (below). Its single packed-today bind trails the two uuid binds.
35
+ const overdueSql = overdue ? ` AND ${OVERDUE}` : "";
36
+ const overdueBinds = overdue ? [encodePackedDate(localToday(now, zone))] : [];
37
+ // Tag scope (§9a): the child to-dos are filtered by a tag carried DIRECTLY on
38
+ // the row — the container semantics. The project's own tags are inherited by
39
+ // EVERY child, so an inheritance-inclusive `--tag` would be vacuous here;
40
+ // suppressing the container hop makes `--tag` mean "children with this tag on
41
+ // themselves" (still descendant-expanded), and `--untagged` "children with no
42
+ // direct tag". No recursion; the header always renders. The tag binds trail
43
+ // the two uuid binds and lead the overdue bind, matching their left-to-right
44
+ // order in the SQL.
45
+ const tf = tagFilter(db, filter, { container: true });
24
46
  const childRows = fetchTaskRows(db, `t.type = 0 AND (t.project = ? OR t.heading IN (
25
47
  SELECT uuid FROM TMTask WHERE type = 2 AND project = ?
26
- ))
27
- ORDER BY t."index" ASC`, [uuid, uuid]);
48
+ ))${tf.sql}${overdueSql}
49
+ ORDER BY t."index" ASC`, [uuid, uuid, ...tf.binds, ...overdueBinds]);
28
50
  const childTags = tagsOf(childRows);
29
- const boundary = logBoundary(db, now);
51
+ const boundary = logBoundary(db, now, zone);
30
52
  const todos = childRows.map((r) => ({
31
53
  row: r,
32
- todo: mapTodo(r, refs, childTags.get(r.uuid) ?? []),
54
+ todo: mapTodo(r, refs, childTags.get(r.uuid) ?? [], packedToday),
33
55
  }));
34
56
  markLogged([project, ...todos.map((t) => t.todo)], boundary);
35
- const packedToday = encodePackedDate(localToday(now));
36
57
  const active = [];
37
58
  const byHeading = new Map();
38
59
  const scheduledRows = [];
@@ -40,6 +61,10 @@ export function projectView(db, uuid, now) {
40
61
  const someday = [];
41
62
  const logged = [];
42
63
  const trashed = [];
64
+ // Every untrashed, non-template OPEN child, regardless of which bucket it
65
+ // lands in below — surfaced (only when the project is itself resolved) as
66
+ // the PLOG1 stranded-open-child count.
67
+ let openChildren = 0;
43
68
  for (const { row, todo } of todos) {
44
69
  if (row.trashed === 1) {
45
70
  trashed.push(todo);
@@ -49,6 +74,8 @@ export function projectView(db, uuid, now) {
49
74
  repeating.push(todo);
50
75
  continue;
51
76
  }
77
+ if (row.status === 0)
78
+ openChildren += 1;
52
79
  if (row.status !== 0) {
53
80
  // Completion ≠ logged: closed items the log-move sweep has not
54
81
  // passed stay checked IN PLACE (their heading / the active block),
@@ -90,23 +117,29 @@ export function projectView(db, uuid, now) {
90
117
  logged.sort((a, b) => (b.stopped?.getTime() ?? 0) - (a.stopped?.getTime() ?? 0));
91
118
  const scheduled = [];
92
119
  // Within a day the UI sorts by todayIndex ASC (Upcoming drag order).
93
- for (const { date, todo } of scheduledRows.sort((a, b) => a.date.localeCompare(b.date) || a.ti - b.ti)) {
120
+ for (const { date, todo } of scheduledRows.toSorted((a, b) => a.date.localeCompare(b.date) || a.ti - b.ti)) {
94
121
  const last = scheduled[scheduled.length - 1];
95
122
  if (last && last.date === date)
96
123
  last.items.push(todo);
97
124
  else
98
125
  scheduled.push({ date, items: [todo] });
99
126
  }
127
+ // Under any content scope (`--overdue` or a tag filter), a heading whose
128
+ // children were all filtered out collapses rather than rendering an empty
129
+ // section; a heading with a surviving child is kept. With no scope active
130
+ // every heading renders (its own empty state).
131
+ const contentScoped = overdue || tf.sql !== "";
132
+ const headingGroups = headings
133
+ .map((heading) => ({ heading, items: byHeading.get(heading.uuid) ?? [] }))
134
+ .filter((g) => !contentScoped || g.items.length > 0);
100
135
  return {
101
136
  project,
102
137
  active,
103
- headings: headings.map((heading) => ({
104
- heading,
105
- items: byHeading.get(heading.uuid) ?? [],
106
- })),
138
+ headings: headingGroups,
107
139
  later: { scheduled, repeating, someday },
108
140
  logged,
109
141
  trashed,
142
+ openChildrenWhileResolved: project.status === "open" ? 0 : openChildren,
110
143
  };
111
144
  }
112
145
  //# sourceMappingURL=project-view.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-view.js","sourceRoot":"","sources":["../../src/read/project-view.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-view.js","sourceRoot":"","sources":["../../src/read/project-view.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAgB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAmB,MAAM,YAAY,CAAC;AA6BxD,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,IAAY;QACtB,KAAK,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CACzB,EAAgB,EAChB,IAAY,EACZ,GAAU,EACV,SAAqB,EAAE,EACvB,IAAa;IAEb,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IACxC,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAE/E,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACjC,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,WAAW,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,CAAC,IAAe,EAAE,EAAE,CACjC,iBAAiB,CACf,EAAE,EACF,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACxB,CAAC;IACJ,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IAClG,gFAAgF;IAChF,OAAO,CAAC,aAAa,GAAG,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAEzD,MAAM,WAAW,GAAG,aAAa,CAC/B,EAAE,EACF,uEAAuE,EACvE,CAAC,IAAI,CAAC,CACP,CAAC;IACF,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAE7D,4EAA4E;IAC5E,uEAAuE;IACvE,yEAAyE;IACzE,wEAAwE;IACxE,mEAAmE;IACnE,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,0EAA0E;IAC1E,8EAA8E;IAC9E,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,oBAAoB;IACpB,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,aAAa,CAC7B,EAAE,EACF;;SAEK,EAAE,CAAC,GAAG,GAAG,UAAU;4BACA,EACxB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,YAAY,CAAC,CAC3C,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClC,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC;KACjE,CAAC,CAAC,CAAC;IACJ,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,aAAa,GAAoD,EAAE,CAAC;IAC1E,MAAM,SAAS,GAAW,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAW,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,MAAM,OAAO,GAAW,EAAE,CAAC;IAC3B,0EAA0E;IAC1E,0EAA0E;IAC1E,uCAAuC;IACvC,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QAClC,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;YAC9B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,YAAY,IAAI,CAAC,CAAC;QACxC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,+DAA+D;YAC/D,mEAAmE;YACnE,mEAAmE;YACnE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClB,SAAS;YACX,CAAC;YACD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChB,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,IAAI,GAAG,CAAC,SAAS,GAAG,WAAW,EAAE,CAAC;YAC1D,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE;gBAC3C,EAAE,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC;gBACvB,IAAI;aACL,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,SAAS,GAAyB,EAAE,CAAC;IAC3C,qEAAqE;IACrE,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,aAAa,CAAC,QAAQ,CACjD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CACtD,EAAE,CAAC;QACF,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;YACjD,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,0EAA0E;IAC1E,+CAA+C;IAC/C,MAAM,aAAa,GAAG,OAAO,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC;IAC/C,MAAM,aAAa,GAAG,QAAQ;SAC3B,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;SACzE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEvD,OAAO;QACL,OAAO;QACP,MAAM;QACN,QAAQ,EAAE,aAAa;QACvB,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE;QACxC,MAAM;QACN,OAAO;QACP,yBAAyB,EAAE,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;KACxE,CAAC;AACJ,CAAC"}