cbrowser 20.2.2 → 21.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/README.md +2 -2
  2. package/dist/analysis/accessibility-empathy.d.ts +29 -1
  3. package/dist/analysis/accessibility-empathy.d.ts.map +1 -1
  4. package/dist/analysis/accessibility-empathy.js +69 -35
  5. package/dist/analysis/accessibility-empathy.js.map +1 -1
  6. package/dist/browser.d.ts.map +1 -1
  7. package/dist/browser.js +11 -7
  8. package/dist/browser.js.map +1 -1
  9. package/dist/cif-score.d.ts +56 -5
  10. package/dist/cif-score.d.ts.map +1 -1
  11. package/dist/cif-score.js +595 -346
  12. package/dist/cif-score.js.map +1 -1
  13. package/dist/cli.js +10 -8
  14. package/dist/cli.js.map +1 -1
  15. package/dist/cognitive/default-traits.d.ts +14 -0
  16. package/dist/cognitive/default-traits.d.ts.map +1 -0
  17. package/dist/cognitive/default-traits.js +36 -0
  18. package/dist/cognitive/default-traits.js.map +1 -0
  19. package/dist/cognitive/emotions.d.ts.map +1 -1
  20. package/dist/cognitive/emotions.js +104 -174
  21. package/dist/cognitive/emotions.js.map +1 -1
  22. package/dist/cognitive/index.d.ts +28 -0
  23. package/dist/cognitive/index.d.ts.map +1 -1
  24. package/dist/cognitive/index.js +353 -287
  25. package/dist/cognitive/index.js.map +1 -1
  26. package/dist/cognitive/temporal.d.ts +0 -24
  27. package/dist/cognitive/temporal.d.ts.map +1 -1
  28. package/dist/cognitive/temporal.js +45 -35
  29. package/dist/cognitive/temporal.js.map +1 -1
  30. package/dist/data/ctc-reference-v2-2026-10-24.d.ts +16 -0
  31. package/dist/data/ctc-reference-v2-2026-10-24.d.ts.map +1 -0
  32. package/dist/data/ctc-reference-v2-2026-10-24.js +1004 -0
  33. package/dist/data/ctc-reference-v2-2026-10-24.js.map +1 -0
  34. package/dist/ideal-profiles-gap.d.ts +1 -0
  35. package/dist/ideal-profiles-gap.d.ts.map +1 -1
  36. package/dist/ideal-profiles-gap.js +9 -1
  37. package/dist/ideal-profiles-gap.js.map +1 -1
  38. package/dist/ideal-profiles.d.ts +8 -0
  39. package/dist/ideal-profiles.d.ts.map +1 -1
  40. package/dist/ideal-profiles.js +28 -24
  41. package/dist/ideal-profiles.js.map +1 -1
  42. package/dist/mcp-server-remote.d.ts.map +1 -1
  43. package/dist/mcp-server-remote.js +7 -8
  44. package/dist/mcp-server-remote.js.map +1 -1
  45. package/dist/mcp-tools/account-personas.d.ts.map +1 -1
  46. package/dist/mcp-tools/account-personas.js +3 -1
  47. package/dist/mcp-tools/account-personas.js.map +1 -1
  48. package/dist/mcp-tools/base/answer-provenance.d.ts +28 -0
  49. package/dist/mcp-tools/base/answer-provenance.d.ts.map +1 -0
  50. package/dist/mcp-tools/base/answer-provenance.js +32 -0
  51. package/dist/mcp-tools/base/answer-provenance.js.map +1 -0
  52. package/dist/mcp-tools/base/audit-tools.d.ts +0 -3
  53. package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
  54. package/dist/mcp-tools/base/audit-tools.js +152 -84
  55. package/dist/mcp-tools/base/audit-tools.js.map +1 -1
  56. package/dist/mcp-tools/base/capture-tools.js +1 -1
  57. package/dist/mcp-tools/base/capture-tools.js.map +1 -1
  58. package/dist/mcp-tools/base/chain-values.d.ts +38 -0
  59. package/dist/mcp-tools/base/chain-values.d.ts.map +1 -0
  60. package/dist/mcp-tools/base/chain-values.js +85 -0
  61. package/dist/mcp-tools/base/chain-values.js.map +1 -0
  62. package/dist/mcp-tools/base/cognitive-tools.d.ts.map +1 -1
  63. package/dist/mcp-tools/base/cognitive-tools.js +126 -120
  64. package/dist/mcp-tools/base/cognitive-tools.js.map +1 -1
  65. package/dist/mcp-tools/base/gif-tools.d.ts.map +1 -1
  66. package/dist/mcp-tools/base/gif-tools.js +23 -5
  67. package/dist/mcp-tools/base/gif-tools.js.map +1 -1
  68. package/dist/mcp-tools/base/persona-comparison-tools.d.ts.map +1 -1
  69. package/dist/mcp-tools/base/persona-comparison-tools.js +229 -172
  70. package/dist/mcp-tools/base/persona-comparison-tools.js.map +1 -1
  71. package/dist/mcp-tools/base/site-familiarity.d.ts +31 -0
  72. package/dist/mcp-tools/base/site-familiarity.d.ts.map +1 -0
  73. package/dist/mcp-tools/base/site-familiarity.js +30 -0
  74. package/dist/mcp-tools/base/site-familiarity.js.map +1 -0
  75. package/dist/mcp-tools/base/site-knowledge-tools.js +1 -1
  76. package/dist/mcp-tools/base/site-knowledge-tools.js.map +1 -1
  77. package/dist/mcp-tools/base/story-narrative.d.ts +50 -0
  78. package/dist/mcp-tools/base/story-narrative.d.ts.map +1 -0
  79. package/dist/mcp-tools/base/story-narrative.js +88 -0
  80. package/dist/mcp-tools/base/story-narrative.js.map +1 -0
  81. package/dist/mcp-tools/base/values-tools.d.ts.map +1 -1
  82. package/dist/mcp-tools/base/values-tools.js +19 -5
  83. package/dist/mcp-tools/base/values-tools.js.map +1 -1
  84. package/dist/mcp-tools/base/visual-testing-tools.d.ts +5 -5
  85. package/dist/mcp-tools/base/visual-testing-tools.d.ts.map +1 -1
  86. package/dist/mcp-tools/base/visual-testing-tools.js +38 -11
  87. package/dist/mcp-tools/base/visual-testing-tools.js.map +1 -1
  88. package/dist/mcp-tools/persona-creation-tools.js +6 -6
  89. package/dist/mcp-tools/persona-creation-tools.js.map +1 -1
  90. package/dist/mcp-tools/persona-lifecycle-tools.d.ts.map +1 -1
  91. package/dist/mcp-tools/persona-lifecycle-tools.js +5 -1
  92. package/dist/mcp-tools/persona-lifecycle-tools.js.map +1 -1
  93. package/dist/mcp-tools/tier-gate.js +1 -1
  94. package/dist/mcp-tools/tool-result-saver.d.ts +7 -0
  95. package/dist/mcp-tools/tool-result-saver.d.ts.map +1 -1
  96. package/dist/mcp-tools/tool-result-saver.js +11 -0
  97. package/dist/mcp-tools/tool-result-saver.js.map +1 -1
  98. package/dist/mcp-tools/trait-provenance.d.ts +109 -0
  99. package/dist/mcp-tools/trait-provenance.d.ts.map +1 -0
  100. package/dist/mcp-tools/trait-provenance.js +187 -0
  101. package/dist/mcp-tools/trait-provenance.js.map +1 -0
  102. package/dist/mcp-tools/ui-resources.d.ts +6 -7
  103. package/dist/mcp-tools/ui-resources.d.ts.map +1 -1
  104. package/dist/mcp-tools/ui-resources.js +162 -12
  105. package/dist/mcp-tools/ui-resources.js.map +1 -1
  106. package/dist/mcp-tools/widget-kit.d.ts +129 -3
  107. package/dist/mcp-tools/widget-kit.d.ts.map +1 -1
  108. package/dist/mcp-tools/widget-kit.js +507 -28
  109. package/dist/mcp-tools/widget-kit.js.map +1 -1
  110. package/dist/performance/metrics.d.ts.map +1 -1
  111. package/dist/performance/metrics.js +4 -1
  112. package/dist/performance/metrics.js.map +1 -1
  113. package/dist/persona-age.d.ts +59 -0
  114. package/dist/persona-age.d.ts.map +1 -0
  115. package/dist/persona-age.js +84 -0
  116. package/dist/persona-age.js.map +1 -0
  117. package/dist/persona-questionnaire.js +1 -1
  118. package/dist/persona-questionnaire.js.map +1 -1
  119. package/dist/personas.d.ts +3 -1
  120. package/dist/personas.d.ts.map +1 -1
  121. package/dist/personas.js +154 -119
  122. package/dist/personas.js.map +1 -1
  123. package/dist/recording/engine.d.ts.map +1 -1
  124. package/dist/recording/engine.js +5 -2
  125. package/dist/recording/engine.js.map +1 -1
  126. package/dist/recording/saliency-overlay.d.ts +8 -3
  127. package/dist/recording/saliency-overlay.d.ts.map +1 -1
  128. package/dist/recording/saliency-overlay.js +14 -5
  129. package/dist/recording/saliency-overlay.js.map +1 -1
  130. package/dist/recording/types.js +1 -1
  131. package/dist/testing/nl-test-suite.d.ts.map +1 -1
  132. package/dist/testing/nl-test-suite.js +2 -1
  133. package/dist/testing/nl-test-suite.js.map +1 -1
  134. package/dist/trait-reference.d.ts +19 -2
  135. package/dist/trait-reference.d.ts.map +1 -1
  136. package/dist/trait-reference.js +19 -2
  137. package/dist/trait-reference.js.map +1 -1
  138. package/dist/types.d.ts +32 -21
  139. package/dist/types.d.ts.map +1 -1
  140. package/dist/types.js +62 -52
  141. package/dist/types.js.map +1 -1
  142. package/dist/values/persona-completeness.js +1 -1
  143. package/dist/values/persona-completeness.js.map +1 -1
  144. package/dist/visual/ab-comparison.d.ts.map +1 -1
  145. package/dist/visual/ab-comparison.js +4 -1
  146. package/dist/visual/ab-comparison.js.map +1 -1
  147. package/dist/visual/attention-quality.d.ts +1 -1
  148. package/dist/visual/attention-quality.js +1 -1
  149. package/dist/visual/attention-transport.d.ts +74 -10
  150. package/dist/visual/attention-transport.d.ts.map +1 -1
  151. package/dist/visual/attention-transport.js +353 -193
  152. package/dist/visual/attention-transport.js.map +1 -1
  153. package/dist/visual/cognitive-models.d.ts +77 -55
  154. package/dist/visual/cognitive-models.d.ts.map +1 -1
  155. package/dist/visual/cognitive-models.js +231 -104
  156. package/dist/visual/cognitive-models.js.map +1 -1
  157. package/dist/visual/cognitive-transport-chain.d.ts +328 -30
  158. package/dist/visual/cognitive-transport-chain.d.ts.map +1 -1
  159. package/dist/visual/cognitive-transport-chain.js +576 -353
  160. package/dist/visual/cognitive-transport-chain.js.map +1 -1
  161. package/dist/visual/cognitive-transport.d.ts +446 -13
  162. package/dist/visual/cognitive-transport.d.ts.map +1 -1
  163. package/dist/visual/cognitive-transport.js +1085 -245
  164. package/dist/visual/cognitive-transport.js.map +1 -1
  165. package/dist/visual/cross-browser.d.ts.map +1 -1
  166. package/dist/visual/cross-browser.js +8 -6
  167. package/dist/visual/cross-browser.js.map +1 -1
  168. package/dist/visual/ctc-bands.d.ts +91 -0
  169. package/dist/visual/ctc-bands.d.ts.map +1 -0
  170. package/dist/visual/ctc-bands.js +117 -0
  171. package/dist/visual/ctc-bands.js.map +1 -0
  172. package/dist/visual/ctc-reference.d.ts +287 -0
  173. package/dist/visual/ctc-reference.d.ts.map +1 -0
  174. package/dist/visual/ctc-reference.js +376 -0
  175. package/dist/visual/ctc-reference.js.map +1 -0
  176. package/dist/visual/demand-laws.d.ts +145 -0
  177. package/dist/visual/demand-laws.d.ts.map +1 -0
  178. package/dist/visual/demand-laws.js +220 -0
  179. package/dist/visual/demand-laws.js.map +1 -0
  180. package/dist/visual/distance-metrics.d.ts +23 -1
  181. package/dist/visual/distance-metrics.d.ts.map +1 -1
  182. package/dist/visual/distance-metrics.js +49 -18
  183. package/dist/visual/distance-metrics.js.map +1 -1
  184. package/dist/visual/dro-bound.d.ts +220 -0
  185. package/dist/visual/dro-bound.d.ts.map +1 -0
  186. package/dist/visual/dro-bound.js +341 -0
  187. package/dist/visual/dro-bound.js.map +1 -0
  188. package/dist/visual/exact-w1.d.ts +60 -0
  189. package/dist/visual/exact-w1.d.ts.map +1 -0
  190. package/dist/visual/exact-w1.js +247 -0
  191. package/dist/visual/exact-w1.js.map +1 -0
  192. package/dist/visual/human-input.d.ts.map +1 -1
  193. package/dist/visual/human-input.js +45 -41
  194. package/dist/visual/human-input.js.map +1 -1
  195. package/dist/visual/index.d.ts +2 -0
  196. package/dist/visual/index.d.ts.map +1 -1
  197. package/dist/visual/index.js +2 -0
  198. package/dist/visual/index.js.map +1 -1
  199. package/dist/visual/law-times-report.d.ts +49 -0
  200. package/dist/visual/law-times-report.d.ts.map +1 -0
  201. package/dist/visual/law-times-report.js +38 -0
  202. package/dist/visual/law-times-report.js.map +1 -0
  203. package/dist/visual/model-provenance.d.ts +151 -0
  204. package/dist/visual/model-provenance.d.ts.map +1 -0
  205. package/dist/visual/model-provenance.js +335 -0
  206. package/dist/visual/model-provenance.js.map +1 -0
  207. package/dist/visual/normal-cdf.d.ts +14 -0
  208. package/dist/visual/normal-cdf.d.ts.map +1 -0
  209. package/dist/visual/normal-cdf.js +26 -0
  210. package/dist/visual/normal-cdf.js.map +1 -0
  211. package/dist/visual/perceptual-transport.d.ts +28 -4
  212. package/dist/visual/perceptual-transport.d.ts.map +1 -1
  213. package/dist/visual/perceptual-transport.js +66 -32
  214. package/dist/visual/perceptual-transport.js.map +1 -1
  215. package/dist/visual/provenance/age.d.ts +30 -0
  216. package/dist/visual/provenance/age.d.ts.map +1 -0
  217. package/dist/visual/provenance/age.js +28 -0
  218. package/dist/visual/provenance/age.js.map +1 -0
  219. package/dist/visual/provenance/attention.d.ts +55 -0
  220. package/dist/visual/provenance/attention.d.ts.map +1 -0
  221. package/dist/visual/provenance/attention.js +188 -0
  222. package/dist/visual/provenance/attention.js.map +1 -0
  223. package/dist/visual/provenance/chain.d.ts +41 -0
  224. package/dist/visual/provenance/chain.d.ts.map +1 -0
  225. package/dist/visual/provenance/chain.js +66 -0
  226. package/dist/visual/provenance/chain.js.map +1 -0
  227. package/dist/visual/provenance/cif.d.ts +42 -0
  228. package/dist/visual/provenance/cif.d.ts.map +1 -0
  229. package/dist/visual/provenance/cif.js +116 -0
  230. package/dist/visual/provenance/cif.js.map +1 -0
  231. package/dist/visual/provenance/ctc-reference.d.ts +36 -0
  232. package/dist/visual/provenance/ctc-reference.d.ts.map +1 -0
  233. package/dist/visual/provenance/ctc-reference.js +96 -0
  234. package/dist/visual/provenance/ctc-reference.js.map +1 -0
  235. package/dist/visual/provenance/distance.d.ts +10 -0
  236. package/dist/visual/provenance/distance.d.ts.map +1 -0
  237. package/dist/visual/provenance/distance.js +72 -0
  238. package/dist/visual/provenance/distance.js.map +1 -0
  239. package/dist/visual/provenance/dro.d.ts +10 -0
  240. package/dist/visual/provenance/dro.d.ts.map +1 -0
  241. package/dist/visual/provenance/dro.js +2 -0
  242. package/dist/visual/provenance/dro.js.map +1 -0
  243. package/dist/visual/provenance/emotion.d.ts +26 -0
  244. package/dist/visual/provenance/emotion.d.ts.map +1 -0
  245. package/dist/visual/provenance/emotion.js +99 -0
  246. package/dist/visual/provenance/emotion.js.map +1 -0
  247. package/dist/visual/provenance/human-input.d.ts +19 -0
  248. package/dist/visual/provenance/human-input.d.ts.map +1 -0
  249. package/dist/visual/provenance/human-input.js +84 -0
  250. package/dist/visual/provenance/human-input.js.map +1 -0
  251. package/dist/visual/provenance/journey-group.d.ts +15 -0
  252. package/dist/visual/provenance/journey-group.d.ts.map +1 -0
  253. package/dist/visual/provenance/journey-group.js +15 -0
  254. package/dist/visual/provenance/journey-group.js.map +1 -0
  255. package/dist/visual/provenance/journey-mcp.d.ts +24 -0
  256. package/dist/visual/provenance/journey-mcp.d.ts.map +1 -0
  257. package/dist/visual/provenance/journey-mcp.js +54 -0
  258. package/dist/visual/provenance/journey-mcp.js.map +1 -0
  259. package/dist/visual/provenance/journey.d.ts +34 -0
  260. package/dist/visual/provenance/journey.d.ts.map +1 -0
  261. package/dist/visual/provenance/journey.js +184 -0
  262. package/dist/visual/provenance/journey.js.map +1 -0
  263. package/dist/visual/provenance/laws.d.ts +38 -0
  264. package/dist/visual/provenance/laws.d.ts.map +1 -0
  265. package/dist/visual/provenance/laws.js +40 -0
  266. package/dist/visual/provenance/laws.js.map +1 -0
  267. package/dist/visual/provenance/page-metrics.d.ts +42 -0
  268. package/dist/visual/provenance/page-metrics.d.ts.map +1 -0
  269. package/dist/visual/provenance/page-metrics.js +79 -0
  270. package/dist/visual/provenance/page-metrics.js.map +1 -0
  271. package/dist/visual/provenance/perceptual.d.ts +63 -0
  272. package/dist/visual/provenance/perceptual.d.ts.map +1 -0
  273. package/dist/visual/provenance/perceptual.js +115 -0
  274. package/dist/visual/provenance/perceptual.js.map +1 -0
  275. package/dist/visual/provenance/persona-rates.d.ts +84 -0
  276. package/dist/visual/provenance/persona-rates.d.ts.map +1 -0
  277. package/dist/visual/provenance/persona-rates.js +108 -0
  278. package/dist/visual/provenance/persona-rates.js.map +1 -0
  279. package/dist/visual/provenance/personas.d.ts +122 -0
  280. package/dist/visual/provenance/personas.d.ts.map +1 -0
  281. package/dist/visual/provenance/personas.js +298 -0
  282. package/dist/visual/provenance/personas.js.map +1 -0
  283. package/dist/visual/provenance/profiles.d.ts +39 -0
  284. package/dist/visual/provenance/profiles.d.ts.map +1 -0
  285. package/dist/visual/provenance/profiles.js +37 -0
  286. package/dist/visual/provenance/profiles.js.map +1 -0
  287. package/dist/visual/provenance/temporal.d.ts +21 -0
  288. package/dist/visual/provenance/temporal.d.ts.map +1 -0
  289. package/dist/visual/provenance/temporal.js +56 -0
  290. package/dist/visual/provenance/temporal.js.map +1 -0
  291. package/dist/visual/provenance/visual-distance.d.ts +22 -0
  292. package/dist/visual/provenance/visual-distance.d.ts.map +1 -0
  293. package/dist/visual/provenance/visual-distance.js +30 -0
  294. package/dist/visual/provenance/visual-distance.js.map +1 -0
  295. package/dist/visual/regression.d.ts.map +1 -1
  296. package/dist/visual/regression.js +14 -9
  297. package/dist/visual/regression.js.map +1 -1
  298. package/dist/visual/responsive.d.ts.map +1 -1
  299. package/dist/visual/responsive.js +4 -1
  300. package/dist/visual/responsive.js.map +1 -1
  301. package/dist/visual/scope-prose.js +2 -2
  302. package/dist/visual/scope-prose.js.map +1 -1
  303. package/dist/visual/seeded-random.d.ts +16 -0
  304. package/dist/visual/seeded-random.d.ts.map +1 -0
  305. package/dist/visual/seeded-random.js +25 -0
  306. package/dist/visual/seeded-random.js.map +1 -0
  307. package/dist/visual/stored-accessibility-traits.d.ts +27 -0
  308. package/dist/visual/stored-accessibility-traits.d.ts.map +1 -0
  309. package/dist/visual/stored-accessibility-traits.js +35 -0
  310. package/dist/visual/stored-accessibility-traits.js.map +1 -0
  311. package/package.json +1 -1
@@ -0,0 +1,376 @@
1
+ /**
2
+ * The reference set totalCTC is ranked against, and the curve that ranks it.
3
+ *
4
+ * WHAT totalCTC IS, as of 21.x: a percentile. A page's raw transport cost for
5
+ * a persona, placed among the raw costs of real pages for the built-in
6
+ * personas. 0.5 is the pooled median of the reference; 0.9 is costlier than
7
+ * nine in ten (page, persona) pairs in it; 1 is at least as costly as the
8
+ * costliest one.
9
+ *
10
+ * Until 21.x it was a logistic of the raw cost with a hand-set slope (2.5) and
11
+ * centre (1.2). Neither number was tied to anything, and on real pages it used
12
+ * little of its range: at viewport scope half of all (page, persona) scores sat
13
+ * between 0.055 and 0.133 and the logistic's floor at raw 0 was 0.047, so "0.2"
14
+ * read as low while it was costlier than most real first screens
15
+ * (research/ctc-21-deltas.md). A percentile has no free constant to set; its
16
+ * scale is the reference set, which is named and shipped.
17
+ *
18
+ * THE REFERENCE STORES RAW MEASUREMENTS, NOT METRICS OR SCORES.
19
+ * src/data/ctc-reference-v2-*.ts holds what measurePageRaw measured on each
20
+ * real page (research/ctc-reference/crawl-v2.ts): counts, length histograms
21
+ * and geometry, before any normaliser. The curve is derived from them through
22
+ * deriveMetrics and the live chain, so a change to a chain constant OR to a
23
+ * page-metric normaliser moves the curve with it. The first reference
24
+ * (2026-10-22, research/ctc-reference/v1/) stored normalised metrics, so a
25
+ * changed normaliser could not reach it. The constants that decide what is
26
+ * counted at all (PAGE_METRICS_MEASURE_IDS) are recorded with the data, and a
27
+ * live value that differs is refused: a stored measurement cannot follow them.
28
+ * For the same reason every record must be the raw layout this build measures
29
+ * (RAW_PAGE_FORMAT, 2: prose counted once, language pickers not read as the
30
+ * page's script); decodeReferenceRaw refuses any other.
31
+ *
32
+ * WHAT IS IN IT. About 500 graded pages from three sampling frames (the v1
33
+ * brand list, a random draw from a dated Tranco top-sites list, government and
34
+ * nonprofit directories) and six page types (landing, form, search, article,
35
+ * help, cart), crawled direct first and through a residential proxy only where
36
+ * the direct attempt was blocked. Every attempted page is listed with its
37
+ * outcome (referenceOutcomes), graded or not.
38
+ *
39
+ * WEIGHTING. Every graded page counts once. The crawl's quotas, not the
40
+ * curve, balance frames and types: each frame stopped at about a third of the
41
+ * pages and each inner type at a cap, so the counts are near balance by
42
+ * construction, and "ranked among N real pages" stays literally true.
43
+ * Weighting cells equally would let a handful of cart pages carry as much
44
+ * weight as the landing pages and widen every interval for it.
45
+ *
46
+ * POOLED OVER PERSONAS, so persona differences survive the mapping. One curve
47
+ * per persona would rank every persona against itself: an elderly user and a
48
+ * power user on the same page would both land near their own median and the
49
+ * difference the tool exists to report would be gone.
50
+ *
51
+ * UNCERTAINTY. A different draw of real pages would place the same raw cost at
52
+ * a somewhat different percentile. bootstrapPercentileInterval measures that:
53
+ * it resamples PAGES (each with all its personas, since a page's personas are
54
+ * not independent draws) and reports, for any raw cost, the central interval
55
+ * of its percentile across the resamples. It says nothing about whether the
56
+ * chain's costs are right; only how firmly the yardstick is fixed.
57
+ *
58
+ * This module holds the data, the population and the curve arithmetic. The
59
+ * chain (cognitive-transport-chain.ts) builds and caches the curves, because
60
+ * only it can compute a raw cost; nothing here imports it.
61
+ *
62
+ * @copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com https://cbrowser.ai
63
+ * @license MIT
64
+ */
65
+ import { brotliDecompressSync } from "node:zlib";
66
+ import { CTC_REFERENCE_META, CTC_REFERENCE_PAGES, CTC_REFERENCE_RAW } from "../data/ctc-reference-v2-2026-10-24.js";
67
+ import { BUILTIN_PERSONAS, ACCESSIBILITY_PERSONAS, EMOTIONAL_PERSONAS } from "../personas.js";
68
+ import { bridgeCapacityTraits } from "./cognitive-models.js";
69
+ import { RAW_PAGE_FORMAT, deriveMetrics } from "./cognitive-transport.js";
70
+ import { param } from "./model-provenance.js";
71
+ import { PAGE_METRICS_MEASURE_IDS } from "./provenance/page-metrics.js";
72
+ const META = CTC_REFERENCE_META;
73
+ const PAGES = CTC_REFERENCE_PAGES;
74
+ /** Where the reference came from: everything about the dataset except the pages. */
75
+ export const CTC_REFERENCE = Object.freeze({ ...META });
76
+ /** Every attempted page with its outcome, graded or not, so the exclusions stay visible. */
77
+ export function referenceOutcomes() {
78
+ return PAGES.map((p) => ({ ...p }));
79
+ }
80
+ let rawCache = null;
81
+ /**
82
+ * Decode a reference's packed raw measurements (brotli JSON, base64) and
83
+ * check them: one record per graded page, each scope a record of the layout
84
+ * this build measures (RAW_PAGE_FORMAT). A record of another layout is
85
+ * refused, not derived: a format-1 record counts nested prose again and reads
86
+ * some language pickers as CJK, so ranking a live page against it would rank
87
+ * one measurement against another.
88
+ */
89
+ /** What format 2 adds to format 1; a record without any of them is not format 2. */
90
+ const FORMAT_2_FIELDS = ["prose", "proseNested", "proseInNav", "navGroupCount", "navLinks", "groupedLinks", "groupedLinksWithText", "choiceNested"];
91
+ export function decodeReferenceRaw(packed, graded, id) {
92
+ const decoded = JSON.parse(brotliDecompressSync(Buffer.from(packed, "base64")).toString("utf8"));
93
+ if (decoded.length !== graded) {
94
+ throw new Error(`ctc reference ${id}: ${decoded.length} raw measurements for ${graded} graded pages`);
95
+ }
96
+ decoded.forEach((page, i) => {
97
+ for (const scope of META.scopes) {
98
+ const record = page[scope];
99
+ const format = record?.format;
100
+ if (format !== RAW_PAGE_FORMAT) {
101
+ throw new Error(`ctc reference ${id}: graded page ${i} ${scope} is raw format ${String(format)}; this build measures and ranks against format ${RAW_PAGE_FORMAT}. Re-crawl the reference (research/ctc-reference/crawl-v2.ts) rather than mixing layouts.`);
102
+ }
103
+ // Format 2 gained its nav totals, proseInNav and groupedLinksWithText
104
+ // before it left the branch it was made on, so an early format-2 record
105
+ // (crawled 2026-10-23 from fd28165, eaf3b36 or 711f0b4) carries the
106
+ // number without them: refused by its fields, not its number.
107
+ const missing = FORMAT_2_FIELDS.filter((k) => !(k in record));
108
+ if (missing.length) {
109
+ throw new Error(`ctc reference ${id}: graded page ${i} ${scope} is raw format ${RAW_PAGE_FORMAT} without ${missing.join(", ")}; re-crawl the reference (research/ctc-reference/crawl-v2.ts).`);
110
+ }
111
+ }
112
+ });
113
+ return decoded;
114
+ }
115
+ /**
116
+ * The graded pages' raw measurements, in outcome-list order, decoded once.
117
+ * Shipped brotli-compressed (base64 in a TS module, so it loads on every Node
118
+ * the package supports); the decoded count must equal the graded count.
119
+ */
120
+ function rawPages() {
121
+ if (!rawCache) {
122
+ const graded = PAGES.filter((p) => p.outcome === "graded").length;
123
+ if (graded !== META.outcomes.graded) {
124
+ throw new Error(`ctc reference ${META.id}: ${graded} graded pages listed, meta says ${META.outcomes.graded}`);
125
+ }
126
+ rawCache = decodeReferenceRaw(CTC_REFERENCE_RAW, graded, META.id);
127
+ }
128
+ return rawCache;
129
+ }
130
+ /**
131
+ * Refuse to derive the reference under a measure-stage constant other than
132
+ * the one its pages were measured with. Reads each through param(), so a curve
133
+ * built under withProvenance records that it rests on them.
134
+ */
135
+ function assertMeasuredWith() {
136
+ for (const id of PAGE_METRICS_MEASURE_IDS) {
137
+ const live = param(id);
138
+ const at = META.measureParams[id];
139
+ if (live !== at) {
140
+ throw new Error(`${id} is applied while a page is measured; the reference ${META.id} was measured with ${at}, not ${live}. A stored measurement cannot follow it: re-crawl the reference (research/ctc-reference/crawl-v2.ts) to change it.`);
141
+ }
142
+ }
143
+ }
144
+ /**
145
+ * The graded pages' raw measurements at one scope, in dataset order. Blocked,
146
+ * error, excluded and robots-disallowed pages are absent measurements and are
147
+ * never part of the reference: a bot challenge measures as a nearly empty
148
+ * page and would rank as the easiest page on the web.
149
+ */
150
+ export function referenceRaw(scope) {
151
+ if (!META.scopes.includes(scope))
152
+ throw new Error(`ctc reference ${META.id} carries no ${scope} measurements`);
153
+ assertMeasuredWith();
154
+ return rawPages().map((p, i) => {
155
+ const m = p[scope];
156
+ if (!m || m.scope !== scope)
157
+ throw new Error(`ctc reference ${META.id}: graded page ${i} has no ${scope} measurement`);
158
+ return m;
159
+ });
160
+ }
161
+ /** The graded pages' metrics at one scope, derived from their raw measurements under the live constants. */
162
+ export function referencePages(scope) {
163
+ return referenceRaw(scope).map(deriveMetrics);
164
+ }
165
+ /** The graded pages' records, in the order referenceRaw returns their measurements. */
166
+ export function referenceGraded() {
167
+ return PAGES.filter((p) => p.outcome === "graded").map((p) => ({ ...p }));
168
+ }
169
+ /**
170
+ * The built-in human personas, each built the way cognitive_effort builds it
171
+ * with no site model: its cognitive traits, siteFamiliarity 0 (first visit),
172
+ * and the reading, pointing and attention capacities bridged from the formal
173
+ * models. Since 21.0 the chain does not read the siteFamiliarity trait: a
174
+ * visit's familiarity is the demand's e (DemandOptions), and the curve is built
175
+ * at e = 0. The trait stays at 0 for what else reads a persona's 29 traits
176
+ * (the persona distance). The same 25 the golden matrix pins (tests/fixtures/ctc-golden-matrix.ts,
177
+ * ROSTER and toolProfile); a test holds the two to each other.
178
+ */
179
+ export function referencePopulation() {
180
+ const roster = { ...BUILTIN_PERSONAS, ...ACCESSIBILITY_PERSONAS, ...EMOTIONAL_PERSONAS };
181
+ return Object.entries(roster).map(([name, p]) => {
182
+ const traits = { ...(p.cognitiveTraits ?? {}) };
183
+ traits.siteFamiliarity = 0;
184
+ bridgeCapacityTraits(name, traits, p.accessibilityTraits);
185
+ return { name, traits };
186
+ });
187
+ }
188
+ let populationSize;
189
+ /** How many personas the reference pools: the length of referencePopulation(), counted once. */
190
+ export function referencePersonaCount() {
191
+ return (populationSize ??= referencePopulation().length);
192
+ }
193
+ export function percentileCurve(samples) {
194
+ const s = Float64Array.from(samples).sort();
195
+ const n = s.length;
196
+ for (const v of s)
197
+ if (!Number.isFinite(v))
198
+ throw new Error(`percentileCurve: sample ${v} is not finite`);
199
+ const xs = [];
200
+ const ps = [];
201
+ for (let i = 0; i < n;) {
202
+ let j = i;
203
+ while (j + 1 < n && s[j + 1] === s[i])
204
+ j++;
205
+ xs.push(s[i]);
206
+ ps.push((i + j) / 2 / (n - 1));
207
+ i = j + 1;
208
+ }
209
+ // One distinct value has no spread to rank against, and the only curve
210
+ // through it is a step.
211
+ if (xs.length < 2)
212
+ throw new Error(`percentileCurve: needs two distinct samples, got ${xs.length} from ${n}`);
213
+ ps[0] = 0;
214
+ ps[ps.length - 1] = 1;
215
+ return { xs: Float64Array.from(xs), ps: Float64Array.from(ps), samples: n };
216
+ }
217
+ /**
218
+ * The curve at x: 0 at or below the lowest sample, 1 at or above the highest,
219
+ * linear between knots. NaN in, NaN out, so a broken cost is not reported as
220
+ * a rank.
221
+ */
222
+ export function percentileAt(curve, x) {
223
+ const { xs, ps } = curve;
224
+ if (Number.isNaN(x))
225
+ return Number.NaN;
226
+ const last = xs.length - 1;
227
+ if (x <= xs[0])
228
+ return 0;
229
+ if (x >= xs[last])
230
+ return 1;
231
+ // Largest k with xs[k] <= x; xs[0] <= x < xs[last] holds here.
232
+ let lo = 0, hi = last;
233
+ while (hi - lo > 1) {
234
+ const mid = (lo + hi) >> 1;
235
+ if (xs[mid] <= x)
236
+ lo = mid;
237
+ else
238
+ hi = mid;
239
+ }
240
+ return ps[lo] + ((ps[hi] - ps[lo]) * (x - xs[lo])) / (xs[hi] - xs[lo]);
241
+ }
242
+ /**
243
+ * The largest slope of the curve over [lo, hi]: its Lipschitz constant there.
244
+ * Outside the sampled range the curve is flat, so only segments meeting
245
+ * [lo, hi] count. With knots close together this can be large; it is the
246
+ * honest constant of a curve that follows the data.
247
+ */
248
+ export function curveSlope(curve, lo = -Infinity, hi = Infinity) {
249
+ const { xs, ps } = curve;
250
+ let max = 0;
251
+ for (let k = 0; k + 1 < xs.length; k++) {
252
+ if (xs[k + 1] < lo || xs[k] > hi)
253
+ continue;
254
+ const slope = (ps[k + 1] - ps[k]) / (xs[k + 1] - xs[k]);
255
+ if (slope > max)
256
+ max = slope;
257
+ }
258
+ return max;
259
+ }
260
+ /** A small, fast, seeded generator (mulberry32): the same seed gives the same resamples on every run. */
261
+ function mulberry32(seed) {
262
+ let a = seed >>> 0;
263
+ return () => {
264
+ a = (a + 0x6d2b79f5) >>> 0;
265
+ let t = a;
266
+ t = Math.imul(t ^ (t >>> 15), t | 1);
267
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
268
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
269
+ };
270
+ }
271
+ /** The type-7 quantile of sorted values (numpy's default), the inverse of percentileCurve. */
272
+ function quantileSorted(sorted, q) {
273
+ const h = q * (sorted.length - 1);
274
+ const f = Math.floor(h);
275
+ const c = Math.min(sorted.length - 1, f + 1);
276
+ return sorted[f] + (h - f) * (sorted[c] - sorted[f]);
277
+ }
278
+ /**
279
+ * Bootstrap over PAGES. `costs` is page-major: page i's costs for every
280
+ * persona sit at [i * perPage, (i + 1) * perPage). A resample draws as many
281
+ * pages as there are, with replacement, and keeps each drawn page's costs for
282
+ * all personas together, because a page's personas share the page and are
283
+ * not independent draws. A grid cost's percentile in a resample is its
284
+ * mid-rank share of the resampled costs (below, plus half of the ties), which
285
+ * differs from the interpolated curve by at most one sample's share.
286
+ *
287
+ * Cost: grid x pages x replicates additions (101 x 500 x 1000 is about 50
288
+ * million), once per curve build.
289
+ */
290
+ export function bootstrapPercentileInterval(costs, perPage, opts) {
291
+ const N = costs.length;
292
+ const n = N / perPage;
293
+ if (!Number.isInteger(n) || n < 2)
294
+ throw new Error(`bootstrapPercentileInterval: ${N} costs are not whole pages of ${perPage}`);
295
+ const B = opts.replicates;
296
+ const sorted = Float64Array.from(costs).sort();
297
+ // The grid: the pooled sample's quantiles at even steps, duplicates dropped.
298
+ const gridXs = [];
299
+ for (let g = 0; g < opts.grid; g++) {
300
+ const x = quantileSorted(sorted, g / (opts.grid - 1));
301
+ if (gridXs.length === 0 || x > gridXs[gridXs.length - 1])
302
+ gridXs.push(x);
303
+ }
304
+ const G = gridXs.length;
305
+ // Per page and grid cost: twice the costs below it plus the ties, so a sum
306
+ // over drawn pages divided by twice the sample size is the mid-rank share.
307
+ const D = new Int32Array(n * G);
308
+ const page = new Float64Array(perPage);
309
+ for (let i = 0; i < n; i++) {
310
+ for (let j = 0; j < perPage; j++)
311
+ page[j] = costs[i * perPage + j];
312
+ page.sort();
313
+ let below = 0;
314
+ for (let g = 0; g < G; g++) {
315
+ const x = gridXs[g];
316
+ while (below < perPage && page[below] < x)
317
+ below++;
318
+ let ties = 0;
319
+ while (below + ties < perPage && page[below + ties] === x)
320
+ ties++;
321
+ D[i * G + g] = 2 * below + ties;
322
+ }
323
+ }
324
+ const rng = mulberry32(opts.seed);
325
+ const F = new Float64Array(G * B);
326
+ const acc = new Int32Array(G);
327
+ const twoN = 2 * N;
328
+ for (let b = 0; b < B; b++) {
329
+ acc.fill(0);
330
+ for (let k = 0; k < n; k++) {
331
+ const off = Math.floor(rng() * n) * G;
332
+ for (let g = 0; g < G; g++)
333
+ acc[g] += D[off + g];
334
+ }
335
+ for (let g = 0; g < G; g++)
336
+ F[g * B + b] = acc[g] / twoN;
337
+ }
338
+ const lo = new Float64Array(G);
339
+ const hi = new Float64Array(G);
340
+ const tail = (1 - opts.level) / 2;
341
+ for (let g = 0; g < G; g++) {
342
+ const reps = F.subarray(g * B, (g + 1) * B).sort();
343
+ lo[g] = quantileSorted(reps, tail);
344
+ hi[g] = quantileSorted(reps, 1 - tail);
345
+ }
346
+ return { xs: Float64Array.from(gridXs), lo, hi, replicates: B, level: opts.level };
347
+ }
348
+ /**
349
+ * The interval at raw cost x, for the point estimate p = percentileAt(curve, x).
350
+ * Interpolated between grid costs; [0, 0] below the reference and [1, 1]
351
+ * above it; widened if needed to contain p, which the mid-rank resamples can
352
+ * miss by at most one sample's share. NaN in, [NaN, NaN] out.
353
+ */
354
+ export function intervalAt(iv, x, p) {
355
+ if (Number.isNaN(x) || Number.isNaN(p))
356
+ return [Number.NaN, Number.NaN];
357
+ const { xs } = iv;
358
+ const last = xs.length - 1;
359
+ if (x < xs[0])
360
+ return [0, 0];
361
+ if (x > xs[last])
362
+ return [1, 1];
363
+ let k = 0, top = last;
364
+ while (top - k > 1) {
365
+ const mid = (k + top) >> 1;
366
+ if (xs[mid] <= x)
367
+ k = mid;
368
+ else
369
+ top = mid;
370
+ }
371
+ const t = top === k ? 0 : (x - xs[k]) / (xs[top] - xs[k]);
372
+ const lo = iv.lo[k] + t * (iv.lo[top] - iv.lo[k]);
373
+ const hi = iv.hi[k] + t * (iv.hi[top] - iv.hi[k]);
374
+ return [Math.min(lo, p), Math.max(hi, p)];
375
+ }
376
+ //# sourceMappingURL=ctc-reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctc-reference.js","sourceRoot":"","sources":["../../src/visual/ctc-reference.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import type { MetricScope } from "./cognitive-transport.js";
2
+ /**
3
+ * Fitts' index of difficulty, bits, in the Shannon form ID = log2(D / W + 1)
4
+ * (Soukoreff & MacKenzie 2004, section 3.3). W is floored at law.fitts.minWidth,
5
+ * where ID would otherwise be undefined.
6
+ */
7
+ export declare function fittsIndexOfDifficulty(distance: number, width: number): number;
8
+ /**
9
+ * Movement time, seconds, to acquire one target: MT = a + b ID, the regression
10
+ * MacKenzie & Buxton (1992) fit with the SMALLER-OF width. Predicted from the
11
+ * regression, not as ID / throughput, because the regression is what predicts
12
+ * time (Soukoreff & MacKenzie 2004).
13
+ */
14
+ export declare function fittsMovementTime(distance: number, width: number): number;
15
+ /** The width a two-dimensional target enters Fitts' law with: the smaller of its width and height (SMALLER-OF). */
16
+ export declare function smallerOfWidth(width: number, height: number): number;
17
+ export interface PointingTarget {
18
+ /** From where the pointer starts to the target's centre, CSS px. */
19
+ distance: number;
20
+ width: number;
21
+ height: number;
22
+ }
23
+ /**
24
+ * Seconds to acquire every target once: the sum of each target's movement
25
+ * time. `totalTargets` is the uncapped count when the targets given are the
26
+ * first N of it; the sum is then scaled by totalTargets / N, assuming the
27
+ * targets not given are as hard on average as those given (a definition).
28
+ */
29
+ export declare function pointingSeconds(targets: readonly PointingTarget[], totalTargets?: number): number;
30
+ /** A target's box, CSS px in document coordinates. */
31
+ export interface TargetBox {
32
+ x: number;
33
+ y: number;
34
+ width: number;
35
+ height: number;
36
+ }
37
+ /**
38
+ * Distance, CSS px, from a target's centre to the centre of the screen it is
39
+ * seen on, the pointer's assumed start (a definition). At viewport scope that
40
+ * screen is the one scrolled to; at full_page it is the screen-sized band, tiled
41
+ * from the top of the document, that holds the target's centre. The motor
42
+ * audits measure from the same point.
43
+ */
44
+ export declare function distanceToScreenCentre(box: TargetBox, view: {
45
+ viewportWidth: number;
46
+ viewportHeight: number;
47
+ scrollY: number;
48
+ }, scope: MetricScope): number;
49
+ /**
50
+ * Seconds to find an item in a group of `items` by linear visual search, the
51
+ * novice limit of Cockburn et al.'s menu model: T = a + b n. A group of 0
52
+ * offers no choice and takes 0.
53
+ */
54
+ export declare function noviceSearchSeconds(items: number): number;
55
+ /** The expert limit of the same model, Hick-Hyman: T = a + b log2 n. cognitiveLoad's demand weights it by the run's siteFamiliarity e (Eq. 4); a first visit reads none of it. */
56
+ export declare function hickHymanSeconds(items: number): number;
57
+ export interface ChoiceGroup {
58
+ /** Items offered. */
59
+ size: number;
60
+ /**
61
+ * True when every item is its own yes/no decision (a checkbox group): the
62
+ * group costs `size` decisions of one item each, one item inspected by search
63
+ * and one bit by Hick-Hyman (a definition). False or absent: one decision
64
+ * among `size` items.
65
+ */
66
+ each?: boolean;
67
+ }
68
+ /**
69
+ * Seconds to make every choice the groups offer once: the sum over groups.
70
+ * `law` picks novice search (the first-visit demand) or Hick-Hyman (the expert limit, weighted by siteFamiliarity).
71
+ * `totalGroups` scales a capped list as in pointingSeconds.
72
+ */
73
+ export declare function choosingSeconds(groups: readonly ChoiceGroup[], law?: "novice" | "expert", totalGroups?: number): number;
74
+ /** Seconds to read `words` at `wpm` words per minute. */
75
+ export declare function wordsReadingSeconds(words: number, wpm: number): number;
76
+ /**
77
+ * Seconds to read `letters` letters of alphabetic text: Brysbaert's equation
78
+ * for a text, wpm = 238 x 4.6 / mean word length, is a constant rate of
79
+ * 238 x 4.6 letters per minute, so time depends on letters, not words.
80
+ */
81
+ export declare function lettersReadingSeconds(letters: number): number;
82
+ export interface ReadingCounts {
83
+ /** Letters of alphabetic words (on any page: the Latin words of an abjad or CJK page too). */
84
+ letters: number;
85
+ /** Abjad words, read at the Arabic rate. */
86
+ abjadWords?: number;
87
+ /**
88
+ * CJK characters, read at the Chinese character rate (260 wpm x 1.5
89
+ * characters per word). Japanese and Korean read at that rate is an
90
+ * assumption: Brysbaert's Table 5 has no Japanese row and counts Korean in
91
+ * space-separated words.
92
+ */
93
+ cjkChars?: number;
94
+ }
95
+ /** Seconds to read all of the prose once, at the reference rate of each script. */
96
+ export declare function readingSeconds(counts: ReadingCounts): number;
97
+ /**
98
+ * Seconds to read `labels` menu labels for the first time: the one-off cost
99
+ * Cockburn et al. kept out of their visual-search fit, charged per label in
100
+ * place of reading the labels' prose (law.reading.labelFirstRead, a hypothesis
101
+ * read off their Figure 2).
102
+ */
103
+ export declare function labelReadingSeconds(labels: number): number;
104
+ /**
105
+ * Seconds of mental preparation for `entrySteps` entry steps: KLM's M per
106
+ * step. One M per field is a definition borrowing KLM's operator; KLM places
107
+ * M by rules applied to a task method, which a page does not give.
108
+ */
109
+ export declare function klmSeconds(entrySteps: number): number;
110
+ /** A time as a demand, d = T / (T + tau): 0 at no work, 0.5 at the budget, below 1 for any finite time. */
111
+ export declare function timeDemand(seconds: number): number;
112
+ /**
113
+ * A rate as a capacity, c = r_p / (r_p + r_ref): 0.5 at the reference rate.
114
+ * Under timeDemand this is the share of the budget's reference-user work the
115
+ * persona gets through, so tau does not appear in it.
116
+ */
117
+ export declare function rateCapacity(rate: number, referenceRate: number): number;
118
+ /** Pointing capacity from a Fitts throughput, bits/s, against the reference mouse throughput. */
119
+ export declare function pointingCapacity(throughput: number): number;
120
+ /** Reading capacity from a silent reading rate, wpm, against the reference rate the reading time uses. */
121
+ export declare function readingCapacity(wpm: number): number;
122
+ /**
123
+ * The populations with a measured rate in provenance/laws.ts. Adults 65+, adults
124
+ * with ADHD and adults with intellectual disability have none.
125
+ */
126
+ export type MeasuredPopulation = "motionImpaired" | "dyslexiaAdults" | "lowVisionCentralLoss" | "lowVisionIntactFields" | "aphasiaReadingImpaired";
127
+ export interface MeasuredRate {
128
+ channel: "pointing" | "reading";
129
+ /**
130
+ * The population's measurement: bits/s for pointing, wpm for reading, or
131
+ * seconds for one text when `timed` (Stage C: aphasia, Webster et al. 2018).
132
+ */
133
+ rate: number;
134
+ /** What it is compared with, in the same unit. */
135
+ control: number;
136
+ /** True when the control group was measured in the same study and method; false when it is the reference law rate. */
137
+ sameStudyControl: boolean;
138
+ /** True when rate and control are times on the same text, so the faster group has the smaller number. */
139
+ timed: boolean;
140
+ /** The population's rate as a share of typical, the r_p / r_ref a capacity is built from: rate / control, or control / rate when timed. */
141
+ ratio: number;
142
+ }
143
+ /** A population's measured rate and its ratio to a control, from the registered sources. */
144
+ export declare function measuredRate(population: MeasuredPopulation): MeasuredRate;
145
+ //# sourceMappingURL=demand-laws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demand-laws.d.ts","sourceRoot":"","sources":["../../src/visual/demand-laws.ts"],"names":[],"mappings":"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"}