diagcalc 3.2.4 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -8
- package/bin/diagcalc.js +142 -41
- package/docs/PROVENANCE.md +17 -0
- package/index.html +430 -118
- package/lib/README.md +98 -0
- package/lib/diagcalc-case.js +148 -0
- package/lib/diagcalc-core.js +554 -89
- package/lib/diagcalc-datasets.js +140 -1
- package/lib/diagcalc-geometry.js +27 -0
- package/lib/diagcalc-i18n.js +584 -0
- package/lib/diagcalc-meta.js +9 -0
- package/lib/diagcalc-presentation.js +278 -0
- package/lib/diagcalc-storage.js +45 -0
- package/lib/diagcalc-types.d.ts +59 -0
- package/package.json +18 -4
- package/script.js +1269 -277
- package/styles.css +2231 -325
- package/tui/index.js +75 -272
- package/tui/input.js +24 -0
- package/tui/presentation.js +168 -0
- package/tui/report.js +130 -0
- package/web/charts.js +339 -0
- package/web/results.js +235 -0
package/lib/diagcalc-datasets.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
root.DiagcalcDatasets = factory();
|
|
8
|
-
}(typeof globalThis !== "undefined" ? globalThis : this, () => {
|
|
8
|
+
}(/** @type {any} */ (typeof globalThis !== "undefined" ? globalThis : this), () => {
|
|
9
9
|
const datasets = {
|
|
10
10
|
screening: {
|
|
11
11
|
tp: 42,
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
preTestProb: 28.6,
|
|
46
46
|
name: "D-dimer for pulmonary embolism",
|
|
47
47
|
description: "Low Wells score + D-dimer to rule out pulmonary embolism in the emergency department.",
|
|
48
|
+
lastReviewed: "2026-05-13",
|
|
48
49
|
reference: {
|
|
49
50
|
authors: "Righini M, et al.",
|
|
50
51
|
title: "Age-Adjusted D-Dimer Cutoff Levels to Rule Out Pulmonary Embolism",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
preTestProb: 15,
|
|
62
63
|
name: "High-sensitivity troponin for AMI",
|
|
63
64
|
description: "High-sensitivity troponin for diagnosis of acute myocardial infarction.",
|
|
65
|
+
lastReviewed: "2026-05-13",
|
|
64
66
|
reference: {
|
|
65
67
|
authors: "Reichlin T, et al.",
|
|
66
68
|
title: "Early Diagnosis of Myocardial Infarction with Sensitive Cardiac Troponin Assays",
|
|
@@ -77,6 +79,7 @@
|
|
|
77
79
|
preTestProb: 1,
|
|
78
80
|
name: "Screening mammography",
|
|
79
81
|
description: "Mammographic screening in women aged 50-69 (aggregated data).",
|
|
82
|
+
lastReviewed: "2026-05-13",
|
|
80
83
|
reference: {
|
|
81
84
|
authors: "Kopans DB, et al.",
|
|
82
85
|
title: "Screening Mammography Performance Metrics",
|
|
@@ -93,6 +96,7 @@
|
|
|
93
96
|
preTestProb: 42.9,
|
|
94
97
|
name: "Rapid COVID-19 antigen test",
|
|
95
98
|
description: "Rapid antigen test for SARS-CoV-2 in symptomatic patients (first 7 days).",
|
|
99
|
+
lastReviewed: "2026-05-13",
|
|
96
100
|
reference: {
|
|
97
101
|
authors: "Dinnes J, et al.",
|
|
98
102
|
title: "Rapid, Point-of-Care Antigen Tests for COVID-19",
|
|
@@ -109,6 +113,7 @@
|
|
|
109
113
|
preTestProb: 2,
|
|
110
114
|
name: "HIV ELISA",
|
|
111
115
|
description: "4th-generation ELISA for HIV screening in the general population.",
|
|
116
|
+
lastReviewed: "2026-05-13",
|
|
112
117
|
reference: {
|
|
113
118
|
authors: "Masciotra S, et al.",
|
|
114
119
|
title: "Performance of HIV Diagnostic Tests",
|
|
@@ -125,6 +130,7 @@
|
|
|
125
130
|
preTestProb: 32,
|
|
126
131
|
name: "Rapid Streptococcus test",
|
|
127
132
|
description: "Rapid antigen test for streptococcal pharyngitis in children with fever and sore throat.",
|
|
133
|
+
lastReviewed: "2026-05-13",
|
|
128
134
|
reference: {
|
|
129
135
|
authors: "Cohen JF, et al.",
|
|
130
136
|
title: "Rapid Antigen Detection Test for Group A Streptococcus in Children",
|
|
@@ -141,6 +147,7 @@
|
|
|
141
147
|
preTestProb: 33.3,
|
|
142
148
|
name: "Chest X-ray for pneumonia",
|
|
143
149
|
description: "Chest X-ray for community-acquired pneumonia in symptomatic adults.",
|
|
150
|
+
lastReviewed: "2026-05-13",
|
|
144
151
|
reference: {
|
|
145
152
|
authors: "Hagaman JT, et al.",
|
|
146
153
|
title: "Admission Chest Radiograph Lacks Sensitivity in Pneumonia",
|
|
@@ -149,8 +156,139 @@
|
|
|
149
156
|
url: "https://www.amjmedsci.org/",
|
|
150
157
|
},
|
|
151
158
|
},
|
|
159
|
+
wells_dvt: {
|
|
160
|
+
tp: 60,
|
|
161
|
+
fp: 85,
|
|
162
|
+
fn: 15,
|
|
163
|
+
tn: 340,
|
|
164
|
+
preTestProb: 15,
|
|
165
|
+
name: "Wells score (≥2) for DVT",
|
|
166
|
+
description: "Wells clinical prediction rule (cut-off ≥2 points = 'DVT likely') applied to outpatients with suspected lower-limb deep vein thrombosis.",
|
|
167
|
+
lastReviewed: "2026-05-13",
|
|
168
|
+
reference: {
|
|
169
|
+
authors: "Wells PS, et al.",
|
|
170
|
+
title: "Evaluation of D-Dimer in the Diagnosis of Suspected Deep-Vein Thrombosis",
|
|
171
|
+
journal: "N Engl J Med. 2003;349(13):1227-1235",
|
|
172
|
+
doi: "10.1056/NEJMoa023153",
|
|
173
|
+
url: "https://www.nejm.org/doi/full/10.1056/NEJMoa023153",
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
heart_acs: {
|
|
177
|
+
tp: 380,
|
|
178
|
+
fp: 1020,
|
|
179
|
+
fn: 20,
|
|
180
|
+
tn: 1020,
|
|
181
|
+
preTestProb: 17,
|
|
182
|
+
name: "HEART score (≥4) for MACE in chest pain",
|
|
183
|
+
description: "HEART score (History, ECG, Age, Risk factors, Troponin) ≥4 to predict 6-week major adverse cardiac events in undifferentiated ED chest pain.",
|
|
184
|
+
lastReviewed: "2026-05-13",
|
|
185
|
+
reference: {
|
|
186
|
+
authors: "Backus BE, et al.",
|
|
187
|
+
title: "A prospective validation of the HEART score for chest pain patients at the emergency department",
|
|
188
|
+
journal: "Int J Cardiol. 2013;168(3):2153-2158",
|
|
189
|
+
doi: "10.1016/j.ijcard.2013.01.255",
|
|
190
|
+
url: "https://www.internationaljournalofcardiology.com/article/S0167-5273(13)00253-2/fulltext",
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
curb65: {
|
|
194
|
+
tp: 72,
|
|
195
|
+
fp: 214,
|
|
196
|
+
fn: 24,
|
|
197
|
+
tn: 758,
|
|
198
|
+
preTestProb: 9,
|
|
199
|
+
name: "CURB-65 (≥2) for severe community-acquired pneumonia",
|
|
200
|
+
description: "CURB-65 score ≥2 as a marker of severe community-acquired pneumonia / 30-day mortality, derived/validated across UK, NZ and Netherlands cohorts.",
|
|
201
|
+
lastReviewed: "2026-05-13",
|
|
202
|
+
reference: {
|
|
203
|
+
authors: "Lim WS, et al.",
|
|
204
|
+
title: "Defining community acquired pneumonia severity on presentation to hospital: an international derivation and validation study",
|
|
205
|
+
journal: "Thorax. 2003;58(5):377-382",
|
|
206
|
+
doi: "10.1136/thorax.58.5.377",
|
|
207
|
+
url: "https://thorax.bmj.com/content/58/5/377",
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
qsofa: {
|
|
211
|
+
tp: 55,
|
|
212
|
+
fp: 180,
|
|
213
|
+
fn: 45,
|
|
214
|
+
tn: 720,
|
|
215
|
+
preTestProb: 10,
|
|
216
|
+
name: "qSOFA (≥2) for sepsis screening",
|
|
217
|
+
description: "Quick SOFA score ≥2 (SBP ≤100, RR ≥22, altered mentation) as a bedside screen for in-hospital mortality among patients with suspected infection outside the ICU.",
|
|
218
|
+
lastReviewed: "2026-05-13",
|
|
219
|
+
reference: {
|
|
220
|
+
authors: "Seymour CW, et al.",
|
|
221
|
+
title: "Assessment of Clinical Criteria for Sepsis (Sepsis-3)",
|
|
222
|
+
journal: "JAMA. 2016;315(8):762-774",
|
|
223
|
+
doi: "10.1001/jama.2016.0288",
|
|
224
|
+
url: "https://jamanetwork.com/journals/jama/fullarticle/2492875",
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
apgar_5min: {
|
|
228
|
+
tp: 20,
|
|
229
|
+
fp: 200,
|
|
230
|
+
fn: 60,
|
|
231
|
+
tn: 19720,
|
|
232
|
+
preTestProb: 0.4,
|
|
233
|
+
name: "APGAR < 7 at 5 min for severe neonatal outcome",
|
|
234
|
+
description: "Five-minute APGAR score below 7 as a predictor of neonatal death in term infants. Illustrates a highly specific but low-sensitivity test at very low disease prevalence.",
|
|
235
|
+
lastReviewed: "2026-05-13",
|
|
236
|
+
reference: {
|
|
237
|
+
authors: "Casey BM, McIntire DD, Leveno KJ.",
|
|
238
|
+
title: "The continuing value of the Apgar score for the assessment of newborn infants",
|
|
239
|
+
journal: "N Engl J Med. 2001;344(7):467-471",
|
|
240
|
+
doi: "10.1056/NEJM200102153440701",
|
|
241
|
+
url: "https://www.nejm.org/doi/full/10.1056/NEJM200102153440701",
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
fast_trauma: {
|
|
245
|
+
tp: 110,
|
|
246
|
+
fp: 28,
|
|
247
|
+
fn: 19,
|
|
248
|
+
tn: 1383,
|
|
249
|
+
preTestProb: 8,
|
|
250
|
+
name: "FAST ultrasound for blunt abdominal trauma",
|
|
251
|
+
description: "Focused Assessment with Sonography for Trauma (surgeon-performed) for intra-abdominal injury in blunt trauma patients.",
|
|
252
|
+
lastReviewed: "2026-05-13",
|
|
253
|
+
reference: {
|
|
254
|
+
authors: "Rozycki GS, et al.",
|
|
255
|
+
title: "A prospective study of surgeon-performed ultrasound as the primary adjuvant modality for injured patient assessment",
|
|
256
|
+
journal: "Ann Surg. 1998;228(4):557-567",
|
|
257
|
+
doi: "10.1097/00000658-199810000-00012",
|
|
258
|
+
url: "https://journals.lww.com/annalsofsurgery/Fulltext/1998/10000/A_Prospective_Study_of_Surgeon_Performed.12.aspx",
|
|
259
|
+
},
|
|
260
|
+
},
|
|
152
261
|
};
|
|
153
262
|
|
|
263
|
+
// Existing counts have no retained source-table extraction. Citations are
|
|
264
|
+
// background reading, not evidence that these exact counts were published.
|
|
265
|
+
for (const dataset of Object.values(datasets)) {
|
|
266
|
+
dataset.provenance = Object.freeze({
|
|
267
|
+
kind: "illustrative",
|
|
268
|
+
sourceLocation: null,
|
|
269
|
+
extraction: null,
|
|
270
|
+
population: dataset.description,
|
|
271
|
+
threshold: null,
|
|
272
|
+
referenceStandard: null,
|
|
273
|
+
outcome: null,
|
|
274
|
+
reviewStatus: "Extraction not verified",
|
|
275
|
+
note: dataset.reference
|
|
276
|
+
? "Illustrative teaching counts. The citation is background reading; these counts have not been verified against a published table."
|
|
277
|
+
: "Generic illustrative teaching scenario; not an empirical study.",
|
|
278
|
+
});
|
|
279
|
+
if (dataset.lastReviewed) {
|
|
280
|
+
dataset.referenceLastReviewed = dataset.lastReviewed;
|
|
281
|
+
delete dataset.lastReviewed;
|
|
282
|
+
}
|
|
283
|
+
Object.freeze(dataset.reference);
|
|
284
|
+
Object.freeze(dataset);
|
|
285
|
+
}
|
|
286
|
+
Object.freeze(datasets);
|
|
287
|
+
|
|
288
|
+
function buildDatasetWarnings(dataset) {
|
|
289
|
+
return dataset && dataset.provenance ? [dataset.provenance.note] : [];
|
|
290
|
+
}
|
|
291
|
+
|
|
154
292
|
function getDataset(key) {
|
|
155
293
|
if (!Object.prototype.hasOwnProperty.call(datasets, key)) {
|
|
156
294
|
return null;
|
|
@@ -168,6 +306,7 @@
|
|
|
168
306
|
|
|
169
307
|
return {
|
|
170
308
|
datasets,
|
|
309
|
+
buildDatasetWarnings,
|
|
171
310
|
getDataset,
|
|
172
311
|
listDatasets,
|
|
173
312
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof module === "object" && module.exports) {
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
root.DiagcalcGeometry = factory();
|
|
7
|
+
}(/** @type {any} */ (typeof globalThis !== "undefined" ? globalThis : this), () => {
|
|
8
|
+
const limit = Math.log(999);
|
|
9
|
+
function logit(probability) {
|
|
10
|
+
return Math.log(probability / (1 - probability));
|
|
11
|
+
}
|
|
12
|
+
function prePosition(probability) {
|
|
13
|
+
return 0.5 + logit(probability) / (2 * limit);
|
|
14
|
+
}
|
|
15
|
+
function postPosition(probability) {
|
|
16
|
+
return 0.5 - logit(probability) / (2 * limit);
|
|
17
|
+
}
|
|
18
|
+
function lrPosition(lr) {
|
|
19
|
+
return 0.5 - Math.log(lr) / (4 * limit);
|
|
20
|
+
}
|
|
21
|
+
/** Normalised calibrated Fagan coordinates; off-scale values are not clipped. */
|
|
22
|
+
function faganCoordinates(pre, lr, post) {
|
|
23
|
+
const positions = { pre: prePosition(pre), lr: lrPosition(lr), post: postPosition(post) };
|
|
24
|
+
return { ...positions, inRange: Object.values(positions).every((value) => Number.isFinite(value) && value >= 0 && value <= 1) };
|
|
25
|
+
}
|
|
26
|
+
return { prePosition, postPosition, lrPosition, faganCoordinates };
|
|
27
|
+
}));
|