diff --git a/IMPROVEMENTS.md b/IMPROVEMENTS.md new file mode 100644 index 0000000..19b6a15 --- /dev/null +++ b/IMPROVEMENTS.md @@ -0,0 +1,188 @@ +# Pediatric AI Scribe — Improvement Roadmap + +A non-technical overview of what the app does today and how it can be taken further. + +--- + +## What the App Does Today + +Pediatric AI Scribe is a clinical documentation tool for pediatric physicians. It listens to doctor-patient encounters (or accepts typed/pasted notes) and uses AI to generate structured medical notes — HPIs, SOAP notes, hospital courses, chart reviews, well visit and sick visit documentation. + +It also includes pediatric calculators (blood pressure percentiles, BMI, growth charts, bilirubin nomograms, vital signs reference), a Learning Hub for educational content and quizzes, and a full security layer (two-factor authentication, session management, audit logging, single sign-on). + +The app runs as a self-hosted web application with a mobile-friendly PWA interface. + +--- + +## Areas for Improvement + +### 1. Visual Growth Charts + +**Current state:** Growth percentiles are displayed as numbers (e.g., "75th percentile, Z-score 0.67"). + +**Improvement:** Plot actual WHO/CDC percentile curves (the familiar growth chart lines pediatricians use) with the patient's data point shown on the chart. This would make results immediately interpretable at a glance, matching the paper charts physicians are trained on. Support for plotting multiple visits over time would make it even more useful for tracking growth trends. + +### 2. Blood Pressure Calculator Accuracy + +**Current state:** The BP calculator uses simplified reference values at the 50th height percentile only. + +**Improvement:** Implement the full Rosner quantile spline regression method (the same math used by the Baylor College of Medicine reference calculator). This would give exact BP percentiles adjusted for the patient's actual height, not just an approximation. The regression coefficients are publicly available and can be integrated directly. + +### 3. Multi-Visit Tracking + +**Current state:** Each encounter is independent. There is no way to see a patient's history across visits. + +**Improvement:** Allow physicians to associate notes with a patient identifier (MRN, initials, or a pseudonym) and view previous encounters for that patient. This would enable: +- Growth tracking over time (plot multiple points on growth curves) +- Trend monitoring (weight gain/loss, blood pressure trends) +- Quick access to past notes during follow-up visits + +This would need careful design around data retention and privacy since it changes the app from a transient tool to one that stores longitudinal data. + +### 4. EHR Integration + +**Current state:** Notes are copied manually and pasted into the EHR. + +**Improvement:** Direct integration with common EHR systems: +- **FHIR API** — connect to Epic, Cerner, or other FHIR-enabled EHRs to push notes directly into the patient chart +- **HL7 messaging** — for institutions using traditional interfaces +- **Smart on FHIR** — launch the app from within the EHR as an embedded tool + +This is the highest-impact improvement for adoption but also the most complex to implement (requires EHR vendor partnerships and institutional approval). + +### 5. Offline Mode + +**Current state:** The app requires an internet connection for AI generation and cloud-based transcription. Browser Whisper works offline for transcription only. + +**Improvement:** Add a local AI model option (e.g., a small medical LLM running on the device or local server) so the entire workflow — record, transcribe, generate note — can happen without any network calls. This would be valuable for: +- Rural clinics with unreliable internet +- Maximum privacy (no data leaves the building) +- Disaster/field medicine scenarios + +### 6. Specialty Expansion + +**Current state:** Focused on general pediatrics with some subspecialty support in chart review. + +**Improvement:** Add specialty-specific note templates and AI prompts for: +- Pediatric cardiology (echo reports, cath summaries) +- Pediatric neurology (EEG reports, seizure logs) +- Neonatology (daily progress notes, discharge summaries) +- Pediatric surgery (operative notes, pre-op assessments) +- Pediatric psychiatry (intake assessments, progress notes) + +Each specialty has unique documentation requirements that could be addressed with tailored prompts and input forms. + +### 7. Billing Code Suggestions + +**Current state:** The well visit tab includes some billing code references. + +**Improvement:** Automatically suggest ICD-10 and CPT codes based on the generated note content. After the AI generates a note, it could analyze the diagnoses, procedures, and visit complexity to suggest appropriate billing codes. This saves time on coding and reduces missed charges. + +### 8. Quality Metrics Dashboard + +**Current state:** Admin panel shows basic usage statistics (total API calls, users). + +**Improvement:** Add a dashboard showing: +- Average note generation time by type +- Most-used AI models and their accuracy (based on how often users edit the output) +- Transcription accuracy metrics (if corrections are tracked) +- Usage patterns by time of day and day of week +- Cost tracking across AI providers + +This would help administrators optimize model selection and identify training opportunities. + +### 9. Patient Education Materials + +**Current state:** The Learning Hub serves educational content to physicians. + +**Improvement:** Add a patient-facing education module that generates age-appropriate handouts based on the diagnosis. For example, after generating a note for a child with asthma, the app could produce a parent-friendly handout explaining the diagnosis, medications, and when to seek emergency care — in the parent's preferred language. + +### 10. Multi-Language Support + +**Current state:** English only. + +**Improvement:** Add support for: +- Generating notes in other languages (Spanish, French, Arabic, etc.) +- Transcribing encounters conducted in other languages +- Patient education materials in the family's language +- UI translation for non-English-speaking staff + +Medical Spanish alone would significantly expand the app's reach in the United States. + +### 11. Voice Commands During Recording + +**Current state:** Recording is continuous — the physician presses start and stop. + +**Improvement:** Add voice command recognition during recording: +- "New section" — marks a section break in the transcript +- "Off the record" — pauses transcription temporarily (for sidebar conversations) +- "Add diagnosis: [condition]" — tags a diagnosis without typing +- "Skip" — ignores the last segment + +This would make the recording workflow more natural and reduce post-generation editing. + +### 12. Collaborative Notes + +**Current state:** Single-user editing. Notes are created and edited by one physician. + +**Improvement:** Allow multiple team members to work on the same encounter: +- Attending reviews and co-signs a resident's note +- Nurse adds vital signs and chief complaint before the physician sees the patient +- Specialist adds their consultation note to the same encounter + +This mirrors the real workflow in training institutions and group practices. + +### 13. Mobile-Optimized Recording + +**Current state:** Recording works on mobile but stops when the screen locks or the app is backgrounded (browser limitation). + +**Improvement:** Build a native mobile wrapper (using Capacitor or React Native) that can record audio in the background even when the screen is off. This is the single biggest usability improvement for mobile users and removes the most common complaint. + +### 14. Template Library + +**Current state:** Physician memories and corrections provide some personalization. + +**Improvement:** Add a shared template library where physicians can create, share, and browse note templates: +- "My asthma follow-up template" +- "Standard newborn discharge summary" +- "ED laceration repair template" +- Import/export templates between institutions + +### 15. Audit and Compliance Reporting + +**Current state:** Audit logs exist in the database but there is no reporting UI. + +**Improvement:** Add an admin-facing compliance dashboard: +- Who accessed what, when (filterable by user, date, action) +- Export audit logs to CSV/PDF for compliance reviews +- Automated alerts for unusual access patterns +- HIPAA compliance checklist with green/red status indicators +- BAA tracking (which providers have signed BAAs) + +--- + +## Priority Recommendations + +If resources are limited, focus on these high-impact improvements first: + +| Priority | Improvement | Impact | Effort | +|----------|-------------|--------|--------| +| 1 | Visual growth charts | High — physicians expect visual curves | Medium | +| 2 | Accurate BP calculator | High — clinical accuracy matters | Medium | +| 3 | Billing code suggestions | High — direct revenue impact | Medium | +| 4 | Multi-language support | High — expands reach significantly | Large | +| 5 | Audit/compliance reporting | Medium — required for institutional adoption | Small | +| 6 | EHR integration (FHIR) | Very high — but requires partnerships | Very large | + +--- + +## What Makes This App Unique + +Compared to existing medical scribes and documentation tools: + +- **Pediatric-specific** — prompts, calculators, milestones, and growth charts designed for children, not adapted from adult tools +- **Self-hosted** — runs on your own infrastructure, not a SaaS that holds your data +- **Provider-agnostic** — works with any AI provider (swap between them without changing anything) +- **Privacy-first** — optional fully offline transcription, auto-expiring data, no permanent PHI storage +- **Learning system** — AI improves its output based on each physician's editing patterns +- **All-in-one** — documentation, calculators, education, and administration in a single platform diff --git a/public/components/calculators.html b/public/components/calculators.html index 6cf3030..12d1c10 100644 --- a/public/components/calculators.html +++ b/public/components/calculators.html @@ -48,6 +48,36 @@
+ + +Hypertension Classification (AAP 2017)
+| Category | Ages 1 to <13 years | Ages ≥13 years |
|---|---|---|
| Normal | <90th percentile | <120/<80 mmHg |
| Elevated BP | ≥90th to <95th percentile OR 120/80 mmHg to <95th (whichever lower) | 120-129/<80 mmHg |
| Stage 1 HTN | ≥95th percentile to <95th + 12 mmHg OR 130/80-139/89 mmHg (whichever lower) | 130/80 to 139/89 mmHg |
| Stage 2 HTN | ≥95th + 12 mmHg OR ≥140/90 mmHg (whichever lower) | ≥140/90 mmHg |
Hypertensive Urgency vs Emergency (Nelson)
+Hypotension (AAP/PALS)
+Sources: Flynn JT et al., Pediatrics 2017;140(3). Nelson Textbook of Pediatrics, 21st ed. PALS Provider Manual.
+The Calculators tab includes clinical tools commonly used in pediatric practice:
+The BP calculator uses the same Rosner quantile spline regression method as the Baylor College of Medicine reference calculator. It computes exact percentiles (1st-99th) based on your patient's age, sex, and height using published regression coefficients. This is the same methodology underlying the AAP 2017 normative tables. Results are height-adjusted and clinically accurate.
+The growth charts display WHO/CDC percentile curves (3rd, 5th, 10th, 25th, 50th, 75th, 90th, 95th, 97th percentiles) with your patient's measurement plotted as a blue dot. The 50th percentile is shown as a bold green line. Shaded bands show the normal range between symmetric percentiles.
+For Length/Height-for-Age, you can optionally enter both parents' heights to see the mid-parental target height range plotted on the chart.
+AI-powered clinical documentation for pediatric medicine. Generate HPIs, SOAP notes, hospital courses, chart reviews, well/sick visit notes, and developmental milestone assessments from voice or text.
+Includes pediatric calculators (BP percentile, BMI, growth charts, bilirubin nomograms, vital signs), Learning Hub with quizzes and AI-generated content, and comprehensive security (2FA, SSO, session management, audit logging).
+All AI providers support BAA for HIPAA compliance. Audio and encounters auto-expire. AI learns from your edits over time.
+Suggestions only. Always verify codes against your institution\'s coding guidelines.
'; + + container.innerHTML = html; + + // Wire click-to-copy on chips + container.querySelectorAll('.billing-code-chip').forEach(function(chip) { + chip.addEventListener('click', function() { + var code = chip.dataset.code; + if (code && navigator.clipboard) { + navigator.clipboard.writeText(code); + showToast('Copied: ' + code, 'info'); + } + }); + }); + }) + .catch(function() { + container.classList.add('hidden'); + }); +} + +function escHtml(s) { return String(s || '').replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } + function refineDocument(outputElementId, inputElementId) { var doc = document.getElementById(outputElementId); var input = document.getElementById(inputElementId); diff --git a/public/js/auth.js b/public/js/auth.js index 65c59e2..8489882 100644 --- a/public/js/auth.js +++ b/public/js/auth.js @@ -234,6 +234,18 @@ document.addEventListener('DOMContentLoaded', function() { showToast('Logged out', 'info'); } + // About modal + if (target.id === 'btn-show-about' || target.closest('#btn-show-about')) { + e.preventDefault(); + var aboutModal = document.getElementById('about-modal'); + if (aboutModal) aboutModal.classList.remove('hidden'); + } + if (target.id === 'btn-close-about' || target.closest('#btn-close-about')) { + e.preventDefault(); + var aboutModal = document.getElementById('about-modal'); + if (aboutModal) aboutModal.classList.add('hidden'); + } + // Settings button — navigate to settings tab if (target.id === 'btn-settings' || target.closest('#btn-settings')) { e.preventDefault(); diff --git a/public/js/calculators.js b/public/js/calculators.js index a3051ba..dd47483 100644 --- a/public/js/calculators.js +++ b/public/js/calculators.js @@ -23,57 +23,501 @@ }); // ═══════════════════════════════════════════════════════════ - // BP PERCENTILE — AAP 2017 (simplified percentile lookup) - // Uses 50th height percentile reference values by age/sex + // BP PERCENTILE — BCM/Rosner Quantile Spline Regression + // AAP 2017 classification with exact percentile computation // ═══════════════════════════════════════════════════════════ - // AAP 2017 BP reference values at 50th height percentile (boys) - // Format: age -> { sys50, sys90, sys95, sys95p12, dia50, dia90, dia95, dia95p12 } - var bpBoys = { - 1: { sys50:85, sys90:98, sys95:102, dia50:40, dia90:52, dia95:54 }, - 2: { sys50:87, sys90:100,sys95:104, dia50:42, dia90:55, dia95:57 }, - 3: { sys50:88, sys90:101,sys95:105, dia50:44, dia90:57, dia95:59 }, - 4: { sys50:90, sys90:102,sys95:106, dia50:47, dia90:60, dia95:62 }, - 5: { sys50:91, sys90:103,sys95:107, dia50:50, dia90:63, dia95:65 }, - 6: { sys50:93, sys90:105,sys95:108, dia50:53, dia90:66, dia95:68 }, - 7: { sys50:94, sys90:106,sys95:110, dia50:55, dia90:68, dia95:70 }, - 8: { sys50:95, sys90:107,sys95:111, dia50:57, dia90:69, dia95:71 }, - 9: { sys50:96, sys90:108,sys95:112, dia50:58, dia90:70, dia95:72 }, - 10: { sys50:97, sys90:109,sys95:113, dia50:59, dia90:71, dia95:73 }, - 11: { sys50:99, sys90:111,sys95:115, dia50:60, dia90:72, dia95:74 }, - 12: { sys50:101,sys90:113,sys95:117, dia50:61, dia90:73, dia95:75 }, - 13: { sys50:104,sys90:115,sys95:120, dia50:61, dia90:73, dia95:75 }, - 14: { sys50:106,sys90:118,sys95:122, dia50:62, dia90:74, dia95:76 }, - 15: { sys50:109,sys90:120,sys95:124, dia50:63, dia90:75, dia95:77 }, - 16: { sys50:111,sys90:122,sys95:126, dia50:64, dia90:76, dia95:78 }, - 17: { sys50:114,sys90:124,sys95:128, dia50:65, dia90:77, dia95:79 } - }; + // Height LMS parameters (218 entries, index 0 = month 24 / age 2y, index 217 = month 241) + var _htLMS_F_L=[1.07244896,1.051272912,1.041951175,1.012592236,0.970541909,0.921129988,0.868221392,0.81454413,0.761957977,0.711660228,0.664323379,0.620285102,0.57955631,0.54198094,0.511429832,0.482799937,0.455521041,0.429150288,0.403351725,0.377878239,0.352555862,0.327270297,0.301955463,0.276583851,0.251158446,0.225705996,0.20027145,0.174913356,0.149700081,0.12470671,0.100012514,0.075698881,0.051847635,0.02853967,0.005853853,-0.016133871,-0.037351181,-0.057729947,-0.077206672,-0.09572283,-0.113225128,-0.129665689,-0.145002179,-0.159197885,-0.172221748,-0.184048358,-0.194660215,-0.204030559,-0.212174408,-0.219069129,-0.224722166,-0.229140412,-0.232335686,-0.234324563,-0.235128195,-0.234772114,-0.233286033,-0.230703633,-0.227062344,-0.222403111,-0.216770161,-0.210210748,-0.202774891,-0.194515104,-0.185486099,-0.175744476,-0.165348396,-0.15435722,-0.142831123,-0.130830669,-0.118416354,-0.105648092,-0.092584657,-0.079283065,-0.065797888,-0.0521805,-0.03847825,-0.024733545,-0.010982868,0.002744306,0.016426655,0.030052231,0.043619747,0.05713988,0.070636605,0.08414848,0.097729873,0.111452039,0.125404005,0.13969316,0.154445482,0.169805275,0.185934346,0.203010488,0.2212252,0.240780542,0.261885086,0.284748919,0.309577733,0.336566048,0.365889711,0.397699038,0.432104409,0.46917993,0.508943272,0.551354277,0.596307363,0.643626542,0.693062173,0.744289752,0.79691098,0.85045728,0.904395871,0.958138449,1.011054559,1.062474568,1.111727029,1.158135105,1.201050821,1.239852328,1.274006058,1.303044695,1.326605954,1.344443447,1.356437773,1.362602695,1.363085725,1.358162799,1.348227142,1.333772923,1.315374704,1.293664024,1.269304678,1.242968236,1.21531127,1.186955477,1.158471522,1.130367088,1.103079209,1.076970655,1.052329922,1.029374161,1.008254396,0.989062282,0.971837799,0.95657215,0.94324228,0.931767062,0.922058291,0.914012643,0.907516917,0.902452436,0.898698641,0.896143482,0.894659668,0.89413892,0.894475371,0.895569834,0.897330209,0.899671635,0.902516442,0.905793969,0.909440266,0.913397733,0.91761471,0.922045055,0.926647697,0.931386217,0.93622842,0.941145943,0.94611388,0.95111043,0.956116576,0.961115792,0.966093766,0.971038162,0.975938391,0.980785418,0.985571579,0.99029042,0.994936555,0.999505539,1.003993753,1.0083983,1.012716921,1.016947912,1.021090055,1.025142554,1.029104983,1.032977233,1.036759475,1.040452117,1.044055774,1.047571238,1.050999451,1.054341482,1.057598512,1.060771808,1.063862715,1.066872639,1.069803036,1.072655401,1.075431258,1.078132156,1.080759655,1.083315329,1.085800751,1.088217496,1.090567133,1.092851222,1.095071313,1.097228939,1.099325619,1.101362852,1.103342119,1.105264876,1.107132561,1.108046193]; + var _htLMS_F_M=[84.97555512,85.3973169,86.29026318,87.15714182,87.9960184,88.8055115,89.58476689,90.33341722,91.0515436,91.7396352,92.39854429,93.02945392,93.63382278,94.21335709,94.79643239,95.37391918,95.94692677,96.51644912,97.08337211,97.6484807,98.21246579,98.77593069,99.33939735,99.9033122,100.4680516,101.033927,101.6011898,102.1700358,102.7406094,103.3130077,103.8872839,104.4634511,105.0414853,105.6213287,106.2028921,106.7860583,107.3706841,107.9566031,108.5436278,109.1315521,109.7201531,110.3091934,110.8984228,111.4875806,112.0763967,112.6645943,113.2518902,113.8380006,114.4226317,115.0054978,115.5863089,116.1647782,116.7406221,117.3135622,117.8833259,118.4496481,119.0122722,119.5709513,120.1254495,120.6755427,121.22102,121.7616844,122.2973542,122.827864,123.3530652,123.8728276,124.38704,124.8956114,125.398472,125.895574,126.3868929,126.8724284,127.3522056,127.8262759,128.2947187,128.757642,129.2151839,129.6675143,130.1148354,130.5573839,130.995432,131.4292887,131.8593015,132.2858574,132.7093845,133.1303527,133.5492749,133.9667073,134.3832499,134.7995463,135.2162826,135.634186,136.0540223,136.4765925,136.9027281,137.3332846,137.7691339,138.2111552,138.6602228,139.1171933,139.5828898,140.0580848,140.5434787,141.0396832,141.5471945,142.0663731,142.59742,143.1403553,143.6949981,144.2609497,144.8375809,145.4240246,146.0191748,146.621692,147.2300177,147.8423918,148.4568879,149.0714413,149.6838943,150.2920328,150.8936469,151.4865636,152.0686985,152.6380955,153.1929631,153.7317031,154.2529332,154.755501,155.2384904,155.7012216,156.1432438,156.564323,156.9644258,157.3436995,157.7024507,158.0411233,158.3602756,158.6605588,158.9426964,159.2074654,159.455679,159.688172,159.9057871,160.1093647,160.299733,160.4776996,160.6440526,160.7995428,160.9448916,161.0807857,161.2078755,161.3267744,161.4380593,161.5422726,161.639917,161.7314645,161.8173534,161.8979913,161.9737558,162.0449969,162.1120386,162.17518,162.2346979,162.2908474,162.343864,162.3939652,162.4413513,162.4862071,162.5287029,162.5689958,162.6072309,162.6435418,162.6780519,162.7108751,162.7421168,162.7718741,162.8002371,162.8272889,162.8531067,162.8777619,162.9013208,162.9238449,162.9453912,162.9660131,162.9857599,163.0046776,163.0228094,163.0401953,163.0568727,163.0728768,163.0882404,163.1029943,163.1171673,163.1307866,163.1438776,163.1564644,163.1685697,163.1802146,163.1914194,163.202203,163.2125835,163.2225779,163.2322024,163.2414722,163.2504019,163.2590052,163.2672954,163.2752848,163.2829854,163.2904086,163.297565,163.304465,163.3111185,163.3175349,163.3237231,163.3296918,163.3354491,163.338251]; + var _htLMS_F_S=[0.040791394,0.040859727,0.041142161,0.041349399,0.041500428,0.041610508,0.041691761,0.04175368,0.041803562,0.041846882,0.041887626,0.041928568,0.041971514,0.042017509,0.042104522,0.042199507,0.042300333,0.042405225,0.042512706,0.042621565,0.042730809,0.042839638,0.042947412,0.043053626,0.043157889,0.043259907,0.043359463,0.043456406,0.043550638,0.043642107,0.043730791,0.043816701,0.043899867,0.043980337,0.044058171,0.04413344,0.044206218,0.044276588,0.044344632,0.044410436,0.044474084,0.044535662,0.044595254,0.044652942,0.044708809,0.044762936,0.044815402,0.044866288,0.044915672,0.044963636,0.045010259,0.045055624,0.045099817,0.045142924,0.045185036,0.045226249,0.045266662,0.045306383,0.045345524,0.045384203,0.045422551,0.045460702,0.045498803,0.045537012,0.045575495,0.045614432,0.045654016,0.04569445,0.045735953,0.045778759,0.045823114,0.04586928,0.045917535,0.045968169,0.04602149,0.046077818,0.046137487,0.046200842,0.04626824,0.046340046,0.046416629,0.046498361,0.046585611,0.046678741,0.046778099,0.04688401,0.046996769,0.047116633,0.047243801,0.047378413,0.047520521,0.047670085,0.047826946,0.04799081,0.048161228,0.04833757,0.048519011,0.048704503,0.048892759,0.049082239,0.049271137,0.049457371,0.049638596,0.049812203,0.049975355,0.050125012,0.050257992,0.050371024,0.050460835,0.050524236,0.050558224,0.050560083,0.050527494,0.050458634,0.050352269,0.050207825,0.050025434,0.049805967,0.049551023,0.049262895,0.048944504,0.048599314,0.048231224,0.047844442,0.047443362,0.04703243,0.046616026,0.046198356,0.04578335,0.045374597,0.044975281,0.044588148,0.044215488,0.043859135,0.04352048,0.043200497,0.042899776,0.042618565,0.042356812,0.042114211,0.041890247,0.04168424,0.041495379,0.041322765,0.041165437,0.041022401,0.040892651,0.040775193,0.040669052,0.040573288,0.040487005,0.040409354,0.040339537,0.040276811,0.040220488,0.040169932,0.040124562,0.040083845,0.040047295,0.040014473,0.03998498,0.039958458,0.039934584,0.039913066,0.039893644,0.039876087,0.039860185,0.039845754,0.039832629,0.039820663,0.039809725,0.0397997,0.039790485,0.039781991,0.039774136,0.03976685,0.03976007,0.039753741,0.039747815,0.039742249,0.039737004,0.039732048,0.039727352,0.03972289,0.03971864,0.039714581,0.039710697,0.039706971,0.039703391,0.039699945,0.039696623,0.039693415,0.039690313,0.039687311,0.039684402,0.039681581,0.039678842,0.039676182,0.039673596,0.039671082,0.039668635,0.039666254,0.039663936,0.039661679,0.039659481,0.039657339,0.039655252,0.039653218,0.039651237,0.039649306,0.039647424,0.039645591,0.039643804,0.039642063,0.039640367,0.039638715,0.039637105,0.039636316]; + var _htLMS_M_L=[0.941523967,1.00720807,0.837251351,0.681492975,0.538779654,0.407697153,0.286762453,0.174489485,0.069444521,-0.029720564,-0.124251789,-0.215288396,-0.30385434,-0.390918369,-0.254801167,-0.125654535,-0.00316735,0.11291221,0.222754969,0.326530126,0.42436156,0.516353108,0.602595306,0.683170764,0.758158406,0.827636736,0.891686306,0.95039153,1.003830006,1.05213569,1.0953669,1.133652119,1.167104213,1.195845353,1.220004233,1.239715856,1.255121285,1.266367398,1.273606657,1.276996893,1.276701119,1.272887366,1.265728536,1.255402281,1.242090871,1.225981067,1.207263978,1.186140222,1.162796198,1.137442868,1.110286487,1.081536236,1.05140374,1.020102497,0.987847213,0.954853043,0.921334742,0.887505723,0.85357703,0.819756239,0.786246296,0.753244292,0.720940222,0.689515708,0.659142731,0.629997853,0.602203984,0.575908038,0.55123134,0.528279901,0.507143576,0.487895344,0.470590753,0.455267507,0.441945241,0.430625458,0.421291648,0.413909588,0.408427813,0.404778262,0.402877077,0.402625561,0.40391127,0.406609232,0.410583274,0.415687443,0.421767514,0.428662551,0.436206531,0.44423,0.45256176,0.461030578,0.469466904,0.477704608,0.48558272,0.492947182,0.499652617,0.505564115,0.510559047,0.514528903,0.517381177,0.519041285,0.519454524,0.518588072,0.516433004,0.513006312,0.508352901,0.502547502,0.495696454,0.487939275,0.479449924,0.470437652,0.461147305,0.451858946,0.442886661,0.434576385,0.427302633,0.421464027,0.417477538,0.415771438,0.416777012,0.420919142,0.428606007,0.440218167,0.456097443,0.476536014,0.501766234,0.531951655,0.567179725,0.607456565,0.652704121,0.702759868,0.757379106,0.816239713,0.878947416,0.945053486,1.014046108,1.085383319,1.158487278,1.232768816,1.307628899,1.382473225,1.456720479,1.529810247,1.601219573,1.670433444,1.736995571,1.800483802,1.860518777,1.916765525,1.968934444,2.016781776,2.060109658,2.098765817,2.132642948,2.16167779,2.185849904,2.205180153,2.219728869,2.2295937,2.234907144,2.235833767,2.232567138,2.2253265,2.214353232,2.199905902,2.182262864,2.161704969,2.138524662,2.113023423,2.085490286,2.0562195,2.025496648,1.993598182,1.960789092,1.927320937,1.89343024,1.859337259,1.825245107,1.791339209,1.757787065,1.724738292,1.692324905,1.660661815,1.629847495,1.599964788,1.571081817,1.543252982,1.516519998,1.490912963,1.466451429,1.44314546,1.420996665,1.399999187,1.380140651,1.361403047,1.343763564,1.327195355,1.311668242,1.297149359,1.283603728,1.270994782,1.25928483,1.248435461,1.23840791,1.229163362,1.220663228,1.212869374,1.20574431,1.199251356,1.19335477,1.188019859,1.183213059,1.178901998,1.175055543,1.171643828,1.16863827,1.167279219]; + var _htLMS_M_M=[86.45220101,86.86160934,87.65247282,88.42326434,89.17549228,89.91040853,90.62907762,91.33242379,92.02127167,92.69637946,93.35846546,94.00822923,94.64636981,95.27359106,95.91474929,96.54734328,97.17191309,97.78897727,98.3990283,99.00254338,99.599977,100.191764,100.7783198,101.3600411,101.9373058,102.5104735,103.0798852,103.645864,104.208713,104.7687256,105.3261638,105.8812823,106.4343146,106.9854769,107.534968,108.0829695,108.6296457,109.1751441,109.7195954,110.2631136,110.8057967,111.3477265,111.8889694,112.4295761,112.9695827,113.5090108,114.0478678,114.5861486,115.1238315,115.6608862,116.1972691,116.732925,117.2677879,117.8017819,118.3348215,118.8668123,119.397652,119.9272309,120.455433,120.9821362,121.5072136,122.0305342,122.5519634,123.0713645,123.588599,124.1035312,124.6160161,125.1259182,125.6331012,126.1374319,126.6387804,127.1370217,127.6320362,128.1237104,128.6119383,129.096622,129.5776723,130.0550101,130.5285669,130.9982857,131.4641218,131.9260439,132.3840348,132.838092,133.2882291,133.7344759,134.1768801,134.6155076,135.0504433,135.4817925,135.9096813,136.3342577,136.7556923,137.1741794,137.5899378,138.0032114,138.4142703,138.8234114,139.2309592,139.6372663,140.042714,140.4477127,140.8527022,141.2581515,141.6645592,142.072452,142.4823852,142.8949403,143.3107241,143.7303663,144.1545167,144.5838414,145.0190192,145.4607359,145.9096784,146.3665278,146.8319513,147.3065929,147.7910635,148.2859294,148.7917006,149.3088178,149.8376391,150.3784267,150.9313331,151.4963887,152.0734897,152.6623878,153.2626819,153.8738124,154.495058,155.1255365,155.7642086,156.4098858,157.0612415,157.7168289,158.3750929,159.034399,159.6930501,160.3493168,161.0014586,161.6477515,162.2865119,162.9161202,163.535045,164.1418486,164.7352199,165.3139755,165.8770715,166.4236087,166.9528354,167.4641466,167.9570814,168.4313175,168.8866644,169.3230548,169.7405351,170.139255,170.5194567,170.881464,171.2256717,171.5525345,171.8625576,172.1562865,172.4342983,172.6971935,172.9455898,173.180112,173.4013896,173.6100518,173.8067179,173.9919998,174.1664951,174.3307855,174.4854344,174.6309856,174.7679617,174.8968634,175.0181691,175.1323345,175.2397926,175.340954,175.4362071,175.5259191,175.6104358,175.690083,175.7651671,175.8359757,175.9027788,175.9658293,176.0253641,176.081605,176.1347593,176.1850208,176.2325707,176.2775781,176.3202008,176.3605864,176.3988725,176.4351874,176.469651,176.5023751,176.533464,176.5630153,176.5911197,176.6178621,176.6433219,176.6675729,176.6906844,176.712721,176.733743,176.753807,176.7729657,176.7912687,176.8087622,176.8254895,176.8414914,176.8492322]; + var _htLMS_M_S=[0.040321528,0.040395626,0.040577525,0.040723122,0.040833194,0.040909059,0.040952433,0.04096533,0.040949976,0.040908737,0.040844062,0.040758431,0.040654312,0.04053412,0.040572876,0.04061691,0.040666414,0.040721467,0.040782045,0.040848042,0.040919281,0.040995524,0.041076485,0.041161838,0.041251224,0.041344257,0.041440534,0.041539635,0.041641136,0.041744602,0.041849607,0.041955723,0.042062532,0.042169628,0.042276619,0.042383129,0.042488804,0.042593311,0.042696342,0.042797615,0.042896877,0.042993904,0.043088503,0.043180513,0.043269806,0.043356287,0.043439893,0.043520597,0.043598407,0.043673359,0.043745523,0.043815003,0.043881929,0.043946461,0.044008785,0.044069112,0.044127675,0.044184725,0.044240532,0.044295379,0.044349559,0.044403374,0.04445713,0.044511135,0.044565693,0.044621104,0.044677662,0.044735646,0.044795322,0.044856941,0.04492073,0.044986899,0.045055632,0.045127088,0.045201399,0.045278671,0.045358979,0.045442372,0.045528869,0.045618459,0.045711105,0.045806742,0.045905281,0.046006604,0.046110573,0.046217028,0.04632579,0.046436662,0.04654943,0.046663871,0.046779748,0.046896817,0.047014827,0.047133525,0.047252654,0.047371961,0.047491194,0.047610108,0.047728463,0.04784603,0.047962592,0.048077942,0.048191889,0.048304259,0.048414893,0.048523648,0.048630402,0.04873505,0.048837504,0.048937694,0.049035564,0.049131073,0.049224189,0.049314887,0.049403145,0.049488934,0.049572216,0.049652935,0.049731004,0.0498063,0.04987865,0.049947823,0.050013518,0.050075353,0.050132858,0.050185471,0.050232532,0.050273285,0.050306885,0.050332406,0.05034886,0.050355216,0.050350423,0.050333444,0.050303283,0.050259018,0.050199837,0.050125062,0.05003418,0.049926861,0.049802977,0.04966261,0.049506051,0.049333801,0.049146553,0.04894519,0.048730749,0.048504404,0.048267442,0.04802123,0.047767192,0.047506783,0.047241456,0.04697265,0.046701759,0.046430122,0.046159004,0.045889585,0.045622955,0.045360101,0.045101913,0.044849174,0.044602566,0.044362674,0.044129985,0.043904897,0.043687723,0.043478698,0.043277987,0.043085685,0.042901835,0.042726424,0.042559396,0.042400652,0.042250063,0.042107465,0.041972676,0.041845488,0.041725679,0.041613015,0.041507249,0.041408129,0.041315398,0.041228796,0.04114806,0.041072931,0.04100315,0.040938463,0.040878617,0.040823368,0.040772475,0.040725706,0.040682834,0.04064364,0.040607913,0.040575448,0.040546051,0.040519532,0.040495713,0.040474421,0.040455493,0.040438773,0.040424111,0.040411366,0.040400405,0.040391101,0.040383334,0.04037699,0.040371962,0.040368149,0.040365456,0.040363795,0.04036308,0.040363233,0.040364179,0.04036585,0.04036818,0.040369574]; - // AAP 2017 BP reference values at 50th height percentile (girls) - var bpGirls = { - 1: { sys50:84, sys90:97, sys95:100, dia50:41, dia90:53, dia95:55 }, - 2: { sys50:87, sys90:99, sys95:102, dia50:43, dia90:55, dia95:58 }, - 3: { sys50:88, sys90:100,sys95:104, dia50:45, dia90:58, dia95:60 }, - 4: { sys50:89, sys90:101,sys95:105, dia50:48, dia90:60, dia95:63 }, - 5: { sys50:90, sys90:102,sys95:106, dia50:51, dia90:63, dia95:65 }, - 6: { sys50:91, sys90:103,sys95:107, dia50:53, dia90:65, dia95:67 }, - 7: { sys50:92, sys90:104,sys95:108, dia50:55, dia90:67, dia95:69 }, - 8: { sys50:93, sys90:105,sys95:109, dia50:57, dia90:68, dia95:71 }, - 9: { sys50:95, sys90:107,sys95:110, dia50:58, dia90:70, dia95:72 }, - 10: { sys50:96, sys90:108,sys95:112, dia50:59, dia90:71, dia95:73 }, - 11: { sys50:98, sys90:110,sys95:114, dia50:60, dia90:72, dia95:74 }, - 12: { sys50:100,sys90:112,sys95:116, dia50:61, dia90:73, dia95:75 }, - 13: { sys50:102,sys90:114,sys95:118, dia50:62, dia90:74, dia95:76 }, - 14: { sys50:103,sys90:115,sys95:119, dia50:63, dia90:75, dia95:77 }, - 15: { sys50:104,sys90:116,sys95:120, dia50:64, dia90:76, dia95:78 }, - 16: { sys50:105,sys90:117,sys95:121, dia50:64, dia90:76, dia95:78 }, - 17: { sys50:105,sys90:117,sys95:121, dia50:64, dia90:76, dia95:78 } - }; + // BP Rosner spline coefficients (99 percentiles x 13 coefficients) + var _bpCoeff_F_SYS=[ +[-7.4855,-1.2252,1.2643,-6.8797,20.4744,0.7114,-0.0066,-0.0667,0.3564,-0.0012,0.5278,-0.6927,0.1388], +[8.4462,-0.9598,0.9046,-5.1098,15.1548,0.5919,-0.0029,-0.065,0.2495,-0.003,0.4421,-0.5724,0.0997], +[26.6223,-1.1479,1.2134,-8.4665,28.0408,0.475,0.0001,-0.0643,0.2062,-0.023,0.5561,-0.7467,0.185], +[31.8947,-0.867,1.1693,-8.2932,26.0849,0.4251,-0.0002,-0.0535,0.1718,-0.008,0.3954,-0.5402,0.1473], +[30.9472,-1.1288,1.5926,-11.7371,34.5934,0.4578,-0.0019,-0.0341,0.1144,-0.0167,0.6897,-1.0025,0.3867], +[23.152,-1.1368,1.751,-13.8556,41.2104,0.527,-0.0048,-0.0149,0.0623,0.0062,0.4347,-0.6509,0.2798], +[19.3036,-0.923,1.6566,-14.2294,42.9522,0.5494,-0.0062,-0.0051,0.0555,0.0242,0.1295,-0.1986,0.0876], +[20.0191,-1.0378,1.6928,-13.6476,40.8615,0.5596,-0.0071,0.0146,-0.03,0.0135,0.1632,-0.2423,0.1013], +[21.6515,-0.9745,1.5964,-13.0096,38.8309,0.5462,-0.0063,0.0087,-0.0183,0.0093,0.2644,-0.3848,0.1477], +[22.6952,-0.8665,1.4799,-11.8203,34.2277,0.537,-0.0066,0.0176,-0.0648,0.0046,0.3226,-0.4689,0.1811], +[23.1615,-0.8132,1.4422,-11.8893,34.8542,0.5329,-0.0063,0.013,-0.0367,0.008,0.34,-0.5072,0.2171], +[27.9,-0.8288,1.4257,-11.5803,33.7393,0.4995,-0.0049,0.0013,0.0117,-0.0014,0.4954,-0.7333,0.3051], +[34.8678,-0.801,1.429,-11.2835,32.3656,0.4469,-0.0037,-0.0037,0.0274,-0.0004,0.3936,-0.5873,0.251], +[37.7557,-0.9638,1.5603,-11.545,31.5671,0.4392,-0.0035,0.0024,-0.0164,-0.0087,0.395,-0.575,0.2238], +[39.9509,-1.0185,1.6189,-11.6485,31.009,0.4284,-0.0032,0.0051,-0.0452,-0.0101,0.3516,-0.5073,0.1906], +[40.8576,-0.9313,1.5386,-11.5031,31.8413,0.418,-0.0029,0.0019,-0.0291,-0.0081,0.3507,-0.5094,0.1968], +[42.1455,-0.9104,1.5356,-11.4411,31.5567,0.4098,-0.0029,0.0038,-0.0368,-0.006,0.2848,-0.4155,0.1642], +[44.0009,-1.0103,1.6565,-11.8711,31.8672,0.4038,-0.0026,0.0007,-0.0172,-0.0017,0.1877,-0.2802,0.1211], +[42.9483,-0.9479,1.6532,-12.4439,34.3937,0.4097,-0.0029,0.0023,-0.0231,-0.0003,0.1892,-0.2761,0.1077], +[43.4489,-0.9355,1.5751,-11.4463,30.9525,0.4076,-0.0027,0,-0.0199,0.0013,0.1619,-0.2376,0.0949], +[42.0432,-0.9668,1.5892,-11.2769,29.6658,0.4235,-0.003,0.0009,-0.0194,0.0051,0.1181,-0.1781,0.0784], +[43.3921,-0.9251,1.5125,-10.669,27.8566,0.4122,-0.0025,-0.0008,-0.0269,-0.0003,0.178,-0.2571,0.0962], +[43.1823,-0.9153,1.5502,-11.2058,29.7148,0.4154,-0.0028,0.0025,-0.0386,0.0053,0.0679,-0.0977,0.0352], +[43.5111,-0.8427,1.4724,-10.8634,29.5168,0.4107,-0.0027,0.0019,-0.0416,-0.0023,0.1644,-0.2282,0.0711], +[44.8115,-0.9195,1.5496,-10.7815,27.8384,0.4087,-0.003,0.012,-0.0908,-0.0063,0.1451,-0.1957,0.053], +[45.1153,-0.8419,1.4685,-10.4821,27.7389,0.404,-0.003,0.0148,-0.1094,-0.0047,0.1524,-0.2131,0.0715], +[45.0184,-0.9109,1.4637,-9.8769,25.3956,0.4124,-0.0031,0.0163,-0.1196,-0.0095,0.2128,-0.3015,0.1084], +[46.8396,-0.9336,1.4913,-10.0409,25.5791,0.4004,-0.0025,0.0087,-0.0854,-0.0083,0.207,-0.2945,0.1065], +[46.3627,-1.0691,1.6403,-10.8997,27.3749,0.4156,-0.003,0.0128,-0.0892,-0.006,0.1891,-0.2783,0.1168], +[46.056,-1.0253,1.6174,-10.8914,27.6133,0.4169,-0.0032,0.0134,-0.0831,-0.0015,0.1168,-0.1751,0.0794], +[45.8707,-1.0687,1.6929,-11.5282,29.3823,0.4234,-0.0035,0.0189,-0.1052,-0.002,0.0549,-0.0766,0.0279], +[46.225,-1.0493,1.6305,-11.0002,28.295,0.4212,-0.0032,0.015,-0.0892,0.001,0.0192,-0.0279,0.014], +[49.7043,-1.1168,1.6687,-10.6909,26.5418,0.4005,-0.0027,0.0175,-0.1166,-0.0029,-0.0064,0.0124,-0.0056], +[52.501,-1.2283,1.7174,-10.288,24.6009,0.39,-0.0025,0.0229,-0.1413,-0.0055,-0.0773,0.1151,-0.0428], +[52.638,-1.2668,1.7982,-10.7251,24.8323,0.393,-0.0027,0.0233,-0.1352,-0.0037,-0.1218,0.1797,-0.0678], +[52.9451,-1.2987,1.8214,-10.8739,25.4383,0.3952,-0.0028,0.0249,-0.1365,-0.0026,-0.1753,0.2588,-0.1002], +[51.6977,-1.2275,1.7723,-10.6355,24.5465,0.4024,-0.0032,0.0273,-0.1377,0.0023,-0.2334,0.3428,-0.1327], +[51.5803,-1.1856,1.7323,-10.549,24.7169,0.4027,-0.0033,0.029,-0.1504,0.004,-0.2752,0.4081,-0.1658], +[52.5542,-1.1951,1.7357,-10.3953,23.5706,0.3978,-0.0032,0.0312,-0.1661,0.0005,-0.2249,0.34,-0.1482], +[54.7146,-1.2604,1.8028,-10.773,24.4075,0.3869,-0.0029,0.0332,-0.1862,-0.002,-0.2181,0.3306,-0.1449], +[56.735,-1.199,1.8011,-11.3328,26.8609,0.3684,-0.0025,0.0319,-0.1874,0.0002,-0.2443,0.3686,-0.1611], +[57.7385,-1.2515,1.8588,-11.3519,25.8098,0.3657,-0.0024,0.0287,-0.1704,-0.0009,-0.2306,0.3502,-0.1567], +[57.7098,-1.257,1.9037,-11.8077,27.0173,0.3677,-0.0024,0.0271,-0.1572,-0.0012,-0.1965,0.298,-0.1324], +[58.0736,-1.2363,1.9353,-12.317,28.6066,0.3643,-0.0024,0.0253,-0.1507,0.002,-0.178,0.2641,-0.1092], +[62.0223,-1.2128,1.9237,-12.157,27.903,0.3343,-0.0016,0.0242,-0.1555,-0.0004,-0.21,0.315,-0.136], +[62.1221,-1.1404,1.8555,-11.839,27.3698,0.3308,-0.0017,0.026,-0.1685,-0.0024,-0.1452,0.2208,-0.0993], +[62.7962,-1.113,1.8421,-11.7266,26.7715,0.3253,-0.0016,0.0282,-0.1884,-0.0019,-0.1808,0.2766,-0.1276], +[61.7073,-1.2183,1.9323,-12.0462,26.8742,0.3435,-0.0022,0.0321,-0.2009,-0.0018,-0.1943,0.2958,-0.1342], +[61.7636,-1.1885,1.9597,-12.4946,27.9124,0.342,-0.0022,0.0308,-0.1956,0.003,-0.234,0.3493,-0.149], +[63.7493,-1.2055,1.96,-12.5069,28.0089,0.3283,-0.0012,0.0195,-0.1595,-0.002,-0.1708,0.2634,-0.1258], +[62.2586,-1.077,1.8646,-12.2702,27.8184,0.3328,-0.0012,0.0137,-0.1292,-0.0024,-0.0705,0.1151,-0.0646], +[64.2911,-1.0805,1.8431,-11.8647,26.3816,0.3191,-0.0007,0.0088,-0.1057,-0.007,-0.0325,0.0621,-0.0471], +[68.9778,-1.2187,1.888,-11.2553,23.9127,0.294,0.0003,0.0053,-0.0991,-0.0123,-0.0668,0.1121,-0.0648], +[70.4806,-1.165,1.8218,-10.7395,22.4622,0.2801,0.0009,0.0001,-0.0853,-0.0136,-0.0702,0.1225,-0.0781], +[70.6109,-1.1182,1.8262,-11.2854,24.8046,0.2768,0.001,-0.0007,-0.084,-0.01,-0.1092,0.1806,-0.1041], +[69.8975,-1.1611,1.8731,-11.7046,26.3452,0.287,0.0007,0.0018,-0.0954,-0.0067,-0.1524,0.2386,-0.1185], +[69.191,-1.1401,1.9015,-12.217,27.9129,0.2928,0.0003,0.0055,-0.111,-0.0035,-0.2103,0.3262,-0.1586], +[69.9619,-1.1195,1.8816,-11.9235,26.817,0.2873,0.0005,0.0046,-0.1118,-0.0053,-0.1918,0.3015,-0.1525], +[68.3161,-1.0128,1.7759,-11.6001,26.6764,0.2951,0.0003,0.0028,-0.1008,-0.0022,-0.2321,0.3639,-0.1831], +[68.0555,-0.9162,1.6469,-10.7107,24.2868,0.2927,0.0006,-0.0014,-0.0813,-0.0004,-0.236,0.3707,-0.1882], +[65.6124,-0.7989,1.5036,-9.8072,21.9786,0.3055,0.0004,-0.0054,-0.0567,-0.0017,-0.1403,0.2328,-0.1369], +[65.1636,-0.7707,1.457,-9.5828,21.8374,0.3086,0.0005,-0.0086,-0.0391,-0.0024,-0.0941,0.1647,-0.109], +[66.6766,-0.913,1.5894,-9.8498,21.1477,0.3073,0.0008,-0.0116,-0.029,-0.0052,-0.0645,0.1189,-0.0865], +[65.4537,-0.895,1.5329,-9.3616,19.7235,0.3178,0.0007,-0.0136,-0.0176,-0.0044,-0.0173,0.0444,-0.0479], +[64.8596,-0.9404,1.6229,-9.8355,19.8054,0.3274,0.0002,-0.0077,-0.0396,-0.006,0.0077,0.0094,-0.0359], +[64.7808,-0.935,1.5826,-9.392,18.2771,0.3302,0.0002,-0.0082,-0.0324,-0.009,0.0629,-0.0712,-0.0032], +[65.5762,-0.9693,1.558,-8.833,16.6679,0.3289,0.0003,-0.009,-0.0304,-0.0092,0.0526,-0.0599,-0.0011], +[64.0451,-1.1203,1.7205,-9.4755,16.9051,0.3537,-0.0007,0.0019,-0.0701,-0.0041,-0.1202,0.1997,-0.1156], +[66.825,-1.1964,1.8333,-10.0226,17.9273,0.3397,-0.0006,0.0056,-0.0822,-0.0081,-0.1245,0.2047,-0.1138], +[65.6846,-1.2525,1.9018,-10.459,18.6882,0.3537,-0.0009,0.0036,-0.066,-0.0057,-0.113,0.1831,-0.0985], +[65.3052,-1.2617,1.9135,-10.5223,18.771,0.3604,-0.0013,0.0085,-0.0848,-0.0046,-0.1438,0.2265,-0.112], +[64.899,-1.2245,1.8584,-10.1192,17.7416,0.3641,-0.0016,0.0138,-0.1073,-0.0048,-0.1372,0.2161,-0.1063], +[65.3578,-1.2248,1.8289,-9.7674,16.8046,0.3627,-0.0014,0.0124,-0.1066,-0.0057,-0.1576,0.2502,-0.1263], +[64.5514,-1.1783,1.7442,-9.4075,16.9106,0.3687,-0.0013,0.0091,-0.0924,-0.0076,-0.0787,0.1365,-0.0847], +[66.0885,-1.1878,1.7936,-9.5264,16.3425,0.3605,-0.0016,0.0179,-0.1274,-0.0072,-0.185,0.2994,-0.1608], +[67.302,-1.1912,1.725,-8.4639,12.8607,0.3551,-0.0016,0.0212,-0.1358,-0.0076,-0.2055,0.3238,-0.1601], +[69.6151,-1.1726,1.7606,-8.9219,14.4437,0.3387,-0.0015,0.026,-0.1521,-0.0094,-0.1704,0.2659,-0.1257], +[70.5901,-1.2426,1.8162,-8.921,13.7988,0.3388,-0.0016,0.0283,-0.1619,-0.016,-0.066,0.1157,-0.069], +[74.0399,-1.3696,1.9736,-9.9705,16.4081,0.322,-0.001,0.0261,-0.1607,-0.0211,0.054,-0.068,0.017], +[78.1837,-1.4118,1.9659,-9.2285,13.6521,0.2962,-0.0004,0.0279,-0.176,-0.0236,0.0265,-0.035,0.0171], +[77.8733,-1.5496,2.1217,-10.0164,15.085,0.3117,-0.0013,0.041,-0.234,-0.0167,-0.141,0.2059,-0.0717], +[78.6258,-1.5819,2.1292,-10.2662,16.5876,0.311,-0.0011,0.0374,-0.2191,-0.0181,-0.0881,0.1294,-0.044], +[78.1114,-1.6551,2.2258,-11.1197,18.7127,0.3231,-0.0016,0.0421,-0.2369,-0.0174,-0.0626,0.0903,-0.0264], +[79.7562,-1.6836,2.2862,-11.9207,21.9312,0.3146,-0.0013,0.038,-0.2147,-0.0164,-0.0397,0.0537,-0.0083], +[81.1825,-1.7413,2.3012,-11.7683,21.4169,0.3106,-0.0011,0.0381,-0.2099,-0.0197,0.0394,-0.07,0.0551], +[82.4317,-1.7326,2.3369,-11.7377,20.8323,0.3043,-0.0014,0.0468,-0.2545,-0.0145,-0.1069,0.1451,-0.0329], +[83.4279,-1.7479,2.3341,-12.1336,23.8773,0.3009,-0.0009,0.0394,-0.2205,-0.0159,-0.0384,0.039,0.0189], +[87.5318,-1.8801,2.4042,-11.8201,21.5,0.2804,0,0.0344,-0.215,-0.0208,-0.0131,0.0053,0.0276], +[91.5471,-1.9424,2.5247,-12.4507,21.7964,0.2576,0.0005,0.0374,-0.2444,-0.0294,-0.0119,0.0227,-0.01], +[92.4497,-1.8508,2.5523,-13.6421,26.226,0.2495,0,0.0494,-0.305,-0.0184,-0.1813,0.2673,-0.1041], +[92.8328,-1.7523,2.5128,-13.17,23.6191,0.2436,0.0005,0.0322,-0.2188,-0.0162,-0.1657,0.2435,-0.0938], +[100.346,-1.9852,2.7015,-12.334,16.8429,0.2061,0.0016,0.0236,-0.1616,-0.0093,-0.4796,0.6954,-0.2616], +[106.8231,-1.8617,2.4704,-10.3756,11.994,0.1537,0.0038,0.0071,-0.1169,-0.0192,-0.4992,0.7439,-0.3113], +[111.3953,-1.9833,2.5967,-11.4122,16.0199,0.1324,0.0046,0.0068,-0.1417,-0.0242,-0.6418,0.9712,-0.431], +[117.6411,-2.0964,2.6981,-11.2572,13.4182,0.0991,0.0053,0.0132,-0.1836,-0.0338,-0.4799,0.719,-0.3037], +[121.3735,-2.3828,2.9534,-12.2263,14.8292,0.0974,0.0055,0.0085,-0.1487,-0.0205,-0.6271,0.9041,-0.3313], +[115.9126,-2.5317,3.2788,-15.2093,22.0287,0.1601,0.0028,0.0231,-0.181,0.0006,-0.7258,1.0194,-0.3341], +[125.5877,-1.6743,2.6055,-13.4481,23.2621,0.0405,0.006,-0.0009,-0.0707,0.0296,-1.1873,1.6794,-0.5743], +[135.675,-1.8473,2.0605,-8.0487,16.9201,-0.0112,0.0136,-0.0896,0.1678,-0.0337,0.3359,-0.5938,0.4196] +]; - function classifyBP(age, sys, dia, ref) { - var r = ref[Math.round(age)]; - if (!r) return null; + var _bpCoeff_F_DIA=[ +[36.3363,-0.4513,-0.2328,28.8499,-129.833,-0.0182,0.0007,0.0464,-0.2691,-0.0622,-0.2979,0.6276,-0.5522], +[30.6534,-1.0645,-0.5369,30.836,-125.69,0.1058,0.0021,0.039,-0.2859,-0.0568,-0.8988,1.5116,-0.9035], +[46.6521,-0.8427,-0.8134,29.0051,-109.524,-0.0091,0.0049,0.0484,-0.379,-0.0684,-0.6066,1.0179,-0.5945], +[34.7995,-1.0943,-0.5132,24.8976,-93.9462,0.1143,0.0006,0.0856,-0.4757,-0.03,-0.9349,1.424,-0.6362], +[15.9095,-0.3518,-0.6484,19.5391,-72.0796,0.2253,-0.0045,0.1041,-0.5073,0.007,-1.3455,2.0777,-0.9953], +[12.8878,-0.0974,-1.0427,20.0319,-66.1203,0.2379,-0.002,0.0402,-0.2008,-0.0112,-0.4679,0.7618,-0.4226], +[3.2759,-0.1741,-0.7763,16.2511,-53.8662,0.3223,-0.0044,0.0485,-0.2089,-0.0061,-0.2448,0.4092,-0.2385], +[12.846,-0.0649,-0.8792,16.2183,-50.693,0.2474,-0.0022,0.0311,-0.123,-0.0255,0.239,-0.3265,0.1012], +[12.8668,0.1716,-1.0619,16.2814,-49.2028,0.2361,-0.002,0.0293,-0.1263,-0.0322,0.5303,-0.7561,0.2762], +[9.112,0.1408,-1.0811,16.1015,-48.0962,0.2737,-0.0032,0.0416,-0.1676,-0.0278,0.5837,-0.8523,0.3437], +[11.7225,-0.2667,-0.674,14.1978,-45.5872,0.284,-0.0034,0.0505,-0.203,-0.0368,0.5673,-0.8255,0.3314], +[19.5753,-0.4609,-0.4453,12.7133,-41.9359,0.2384,-0.002,0.0503,-0.2232,-0.0503,0.7475,-1.0987,0.4581], +[21.1297,-0.7489,-0.2784,12.1653,-40.6521,0.2491,-0.0015,0.0462,-0.2201,-0.0415,0.5736,-0.8537,0.3742], +[17.5087,-0.5589,-0.5804,13.6135,-42.3595,0.2699,-0.0017,0.0438,-0.2286,-0.0325,0.5451,-0.8138,0.3581], +[19.125,-0.6931,-0.358,11.3984,-35.5973,0.2679,-0.0009,0.0341,-0.1992,-0.0272,0.3386,-0.5034,0.2204], +[12.3312,-0.7307,-0.2314,9.1993,-27.9046,0.3246,-0.002,0.0272,-0.1474,-0.0218,0.4218,-0.6267,0.2695], +[8.7933,-0.5755,-0.2574,8.5358,-26.1118,0.3473,-0.0031,0.0313,-0.1447,-0.0249,0.4514,-0.6549,0.2572], +[6.8234,-0.7262,-0.0687,7.7821,-26.4927,0.3781,-0.0044,0.0462,-0.203,-0.0214,0.2612,-0.3714,0.1375], +[6.5708,-0.6226,-0.1738,8.0763,-26.5849,0.3759,-0.0041,0.0378,-0.1688,-0.0223,0.3339,-0.475,0.1725], +[12.4952,-0.781,0.0532,6.8239,-24.2698,0.3431,-0.0032,0.0368,-0.1732,-0.0262,0.1513,-0.1909,0.0331], +[16.8254,-0.4175,-0.2206,7.4894,-23.9702,0.2885,-0.0021,0.0295,-0.1608,-0.0154,-0.0241,0.0763,-0.095], +[17.8811,-0.4367,-0.1266,7.0389,-24.15,0.2868,-0.0028,0.0392,-0.1928,-0.0081,-0.278,0.4577,-0.2641], +[16.5734,-0.2666,-0.2542,7.0108,-22.3832,0.2899,-0.0032,0.0387,-0.1806,-0.0041,-0.2653,0.436,-0.2519], +[19.9011,-0.2317,-0.3427,7.6601,-23.4789,0.2636,-0.002,0.0303,-0.1519,-0.0146,-0.0788,0.162,-0.1394], +[21.7218,-0.2625,-0.2345,6.6903,-20.9185,0.2553,-0.0023,0.0347,-0.1547,-0.023,0.0302,0.0052,-0.0801], +[21.9955,-0.4947,-0.0505,6.3827,-21.7936,0.2719,-0.0028,0.0392,-0.1593,-0.0334,0.1394,-0.1536,-0.0152], +[25.2014,-0.5716,0.0877,5.7268,-21.1119,0.2566,-0.0032,0.0512,-0.2028,-0.0358,0.0855,-0.0747,-0.0456], +[24.9355,-0.6578,0.231,4.6551,-18.8514,0.2671,-0.0039,0.0592,-0.2224,-0.0268,-0.0489,0.114,-0.1096], +[23.5259,-0.5069,0.1119,4.7744,-18.0734,0.2698,-0.004,0.0557,-0.2087,-0.0263,0.0265,0.0098,-0.0803], +[22.6538,-0.3685,-0.0683,5.5225,-18.8175,0.2682,-0.0033,0.0439,-0.1629,-0.0299,0.2232,-0.2808,0.039], +[25.1343,-0.4732,0.0854,3.9605,-13.912,0.2571,-0.0028,0.0398,-0.1488,-0.038,0.4146,-0.5644,0.1571], +[26.0776,-0.4748,0.0973,4.2405,-15.6978,0.2526,-0.0028,0.0409,-0.1485,-0.0398,0.4214,-0.5758,0.1652], +[27.7828,-0.4017,0.07,4.258,-15.4754,0.2367,-0.0027,0.0432,-0.1635,-0.035,0.3149,-0.4222,0.1074], +[33.321,-0.5491,0.2782,3.9722,-17.4641,0.2081,-0.0028,0.0559,-0.2079,-0.0453,0.3091,-0.4165,0.114], +[34.8309,-0.6942,0.426,3.3318,-16.8497,0.2081,-0.003,0.0647,-0.2508,-0.0416,0.1445,-0.1779,0.0236], +[37.5926,-0.6443,0.3677,3.4067,-16.42,0.1823,-0.0015,0.0474,-0.1947,-0.0411,0.2234,-0.2936,0.0668], +[39.4412,-0.5625,0.2263,4.2984,-18.3087,0.1635,-0.0003,0.0348,-0.1585,-0.0452,0.3142,-0.4246,0.1158], +[40.6765,-0.6234,0.3141,3.8208,-17.9457,0.1599,-0.0002,0.0372,-0.1782,-0.041,0.1452,-0.1684,-0.0017], +[38.5263,-0.6294,0.3817,3.0897,-16.2418,0.1784,-0.0007,0.0354,-0.1608,-0.0439,0.2718,-0.3597,0.0853], +[38.8799,-0.7551,0.4856,2.734,-15.7989,0.186,-0.0008,0.037,-0.1615,-0.0449,0.292,-0.3993,0.1186], +[41.2743,-0.9011,0.6699,2.2512,-16.8137,0.1795,-0.0009,0.042,-0.1746,-0.0484,0.2216,-0.293,0.0726], +[42.2558,-1.0062,0.7158,2.6789,-19.1943,0.1817,-0.0009,0.0441,-0.1858,-0.0468,0.0978,-0.112,0.002], +[40.2612,-0.9872,0.7444,1.7973,-16.1566,0.1974,-0.0012,0.0445,-0.1857,-0.0476,0.1203,-0.1402,0.0055], +[43.6457,-1.0069,0.734,1.9082,-15.776,0.1751,-0.0005,0.0411,-0.1774,-0.054,0.2098,-0.2758,0.0684], +[37.4261,-1.0061,0.8119,0.7582,-12.6239,0.2262,-0.0023,0.0517,-0.2087,-0.0439,0.0866,-0.0919,-0.0122], +[39.6219,-1.2657,1.1924,-1.7105,-7.6258,0.228,-0.0027,0.0582,-0.2341,-0.047,-0.0208,0.0811,-0.1069], +[40.843,-1.2324,1.2238,-1.9885,-7.0689,0.2204,-0.0032,0.0673,-0.2749,-0.0429,-0.1374,0.2503,-0.1721], +[43.5592,-1.2444,1.2281,-1.7233,-8.2869,0.2012,-0.0024,0.0607,-0.2564,-0.0432,-0.1732,0.3033,-0.1943], +[44.6015,-1.2557,1.2143,-1.1069,-11.0077,0.197,-0.0025,0.062,-0.2557,-0.0368,-0.2817,0.4521,-0.2374], +[43.431,-1.4836,1.4844,-2.8301,-7.691,0.2221,-0.0031,0.0664,-0.2718,-0.0343,-0.3518,0.5529,-0.2744], +[40.2503,-1.5293,1.5113,-3.3498,-5.9574,0.2524,-0.0038,0.0674,-0.2644,-0.0307,-0.3766,0.5899,-0.2912], +[38.7912,-1.4248,1.4482,-3.6476,-4.2826,0.2581,-0.0037,0.0597,-0.2243,-0.033,-0.308,0.4967,-0.266], +[43.1602,-1.3762,1.3057,-2.4967,-6.1669,0.2217,-0.0018,0.0357,-0.1265,-0.0409,-0.031,0.0745,-0.0711], +[44.7535,-1.2714,1.1636,-1.6742,-7.0124,0.2031,-0.0006,0.0171,-0.0429,-0.0436,0.1573,-0.2169,0.0706], +[44.9528,-1.1354,1.0103,-0.6896,-9.5126,0.1953,-0.0005,0.0153,-0.0298,-0.0404,0.1044,-0.1372,0.0343], +[39.8113,-0.9011,0.8911,-1.1437,-6.6547,0.2237,-0.002,0.0227,-0.0406,-0.0358,0.093,-0.1099,0.0051], +[37.8989,-1.0051,1.0055,-1.5428,-6.9588,0.2482,-0.0029,0.031,-0.0735,-0.0328,-0.0609,0.1319,-0.119], +[35.1924,-0.8104,0.8253,-0.5962,-9.35,0.2601,-0.0037,0.0368,-0.0925,-0.0269,-0.1549,0.2764,-0.1888], +[35.6873,-0.7372,0.8448,-1.3541,-6.8503,0.254,-0.0041,0.0431,-0.1168,-0.023,-0.2589,0.4332,-0.2593], +[32.6133,-0.5491,0.7277,-1.3961,-5.5317,0.2691,-0.0053,0.0532,-0.1439,-0.0153,-0.3595,0.5813,-0.3205], +[34.8437,-0.4711,0.6905,-1.4542,-4.7991,0.2492,-0.0052,0.0579,-0.1655,-0.0189,-0.3396,0.557,-0.3175], +[35.5381,-0.4317,0.6593,-1.2682,-5.2622,0.2433,-0.0053,0.063,-0.1896,-0.0217,-0.3173,0.5302,-0.316], +[36.1777,-0.4466,0.641,-0.9947,-5.8087,0.2409,-0.0052,0.0631,-0.1933,-0.022,-0.1927,0.3323,-0.2121], +[41.2921,-0.4612,0.5856,-0.5033,-6.0372,0.2021,-0.0034,0.0497,-0.1573,-0.0331,0.0525,-0.035,-0.0513], +[43.0646,-0.3308,0.3256,1.3124,-9.9318,0.1798,-0.0016,0.0281,-0.0904,-0.0459,0.3232,-0.4202,0.0842], +[44.3551,-0.1948,0.1835,1.9859,-10.8501,0.1628,-0.0011,0.0241,-0.0832,-0.0524,0.5032,-0.684,0.19], +[41.152,0.0212,-0.0243,2.9817,-12.3905,0.1771,-0.0019,0.0273,-0.0838,-0.047,0.5514,-0.7673,0.2434], +[40.7747,0.1804,-0.1901,4.1333,-15.4608,0.1742,-0.0025,0.0343,-0.0976,-0.0441,0.5815,-0.8266,0.2933], +[42.6723,0.2057,-0.2093,4.492,-16.8094,0.1599,-0.0024,0.0353,-0.0956,-0.0449,0.6759,-0.9819,0.3834], +[44.4726,0.1842,-0.1287,4.2111,-17.151,0.1485,-0.0024,0.0365,-0.0871,-0.036,0.5025,-0.7363,0.2978], +[44.4307,0.0412,0.0455,3.5578,-17.0706,0.1602,-0.0031,0.0461,-0.1195,-0.0272,0.2636,-0.3881,0.1611], +[46.146,-0.1944,0.3303,2.0667,-14.4506,0.1634,-0.0032,0.0504,-0.1357,-0.0212,0.0591,-0.0927,0.0497], +[48.5522,-0.2845,0.4266,2.1896,-16.3502,0.1537,-0.0035,0.0626,-0.1955,-0.0152,-0.2111,0.308,-0.1179], +[47.5272,-0.3843,0.5027,1.5489,-14.8051,0.1683,-0.0032,0.0566,-0.179,-0.0162,-0.1752,0.2648,-0.1172], +[42.3688,-0.2544,0.359,1.5821,-13.3586,0.2003,-0.0031,0.0394,-0.1,-0.023,0.1762,-0.2505,0.0889], +[40.419,-0.1244,0.2024,2.2651,-13.8723,0.2085,-0.0028,0.0242,-0.027,-0.0263,0.4803,-0.717,0.3102], +[41.2786,-0.4001,0.5512,0.3246,-9.9661,0.2234,-0.0037,0.0333,-0.0397,-0.0258,0.411,-0.6274,0.2957], +[44.5475,-0.4095,0.5884,0.3313,-11.0779,0.202,-0.0036,0.0417,-0.0815,-0.024,0.2501,-0.3889,0.1968], +[48.1433,-0.5054,0.6845,0.6598,-14.3615,0.1854,-0.0038,0.0599,-0.1887,-0.0266,0.0236,-0.0355,0.0216], +[36.6027,-0.2846,0.4948,0.5126,-11.9027,0.2648,-0.0058,0.0611,-0.1823,-0.0318,0.3126,-0.4516,0.177], +[32.668,-0.2953,0.5385,-0.5236,-7.6933,0.2977,-0.0064,0.0584,-0.1674,-0.0333,0.4917,-0.7205,0.2953], +[34.2675,-0.3725,0.6712,-1.4456,-4.71,0.2927,-0.0065,0.0568,-0.1384,-0.0262,0.4807,-0.7367,0.354], +[34.5736,-0.5184,0.8798,-2.5558,-3.2479,0.3039,-0.0074,0.0666,-0.1528,-0.013,0.1827,-0.311,0.2009], +[38.2705,-0.8498,1.178,-3.1281,-5.8888,0.2993,-0.0068,0.0702,-0.2122,-0.0147,-0.202,0.2993,-0.1195], +[27.2619,-0.709,1.1524,-4.729,0.3025,0.3797,-0.0092,0.0796,-0.2446,-0.0222,0.1254,-0.163,0.0363], +[30.6429,-0.6031,1.1239,-5.8827,7.3287,0.3476,-0.0081,0.0684,-0.2186,-0.027,0.4252,-0.6274,0.2628], +[38.2584,-0.5815,1.057,-5.5212,7.7327,0.2884,-0.0057,0.0424,-0.1141,-0.0255,0.4732,-0.7143,0.3218], +[34.2063,-0.6992,1.3687,-7.5293,9.9367,0.33,-0.0072,0.0412,-0.0552,-0.0037,0.0265,-0.062,0.0645], +[28.3761,-0.5032,1.1656,-6.5035,7.3478,0.3702,-0.009,0.0557,-0.0992,0.0012,-0.2162,0.3295,-0.1511], +[31.5473,-0.191,0.8482,-4.995,5.5448,0.333,-0.0093,0.0772,-0.2338,-0.0012,-0.3665,0.5893,-0.3214], +[28.0599,-0.1241,0.7701,-4.7329,5.1931,0.3597,-0.0102,0.0796,-0.2161,-0.0098,0.0298,-0.0073,-0.0557], +[23.6587,0.3036,0.2722,-3.1305,5.7577,0.3693,-0.0097,0.0627,-0.1368,-0.0164,0.4595,-0.6438,0.21], +[30.6936,0.0131,0.6061,-3.5047,1.8377,0.3406,-0.0098,0.0776,-0.195,-0.0166,0.1956,-0.2534,0.0492], +[36.2121,-0.1094,0.7833,-3.9736,0.5351,0.3083,-0.0089,0.0774,-0.1975,-0.0148,0.091,-0.0977,-0.0189], +[42.9427,-0.2087,1.2659,-7.7504,8.427,0.2634,-0.0082,0.0706,-0.1836,0.0138,-0.4419,0.6751,-0.3217], +[35.6163,-0.3308,1.3791,-8.3941,8.0466,0.3365,-0.0098,0.0787,-0.2043,-0.0005,-0.1455,0.2492,-0.1613], +[52.6206,0.342,0.8903,-5.8391,3.6866,0.1778,-0.0082,0.0886,-0.2524,0.0117,-0.5949,0.9156,-0.4441], +[73.797,-0.1315,1.1805,-3.1333,-12.7158,0.0592,-0.0043,0.0809,-0.2789,-0.052,0.1674,-0.2079,0.0315], +[106.9205,-0.8638,1.9387,-5.949,-7.0235,-0.131,0.0011,0.064,-0.2761,-0.1211,0.5938,-0.7577,0.1352] +]; + var _bpCoeff_M_SYS=[ +[-15.1614,0.1585,0.7927,-16.2445,64.9588,0.7016,-0.0159,0.0803,-0.1501,0.0109,0.1002,-0.1603,0.0565], +[7.1181,0.1808,0.1658,-8.1838,41.4072,0.5512,-0.0095,0.054,-0.1228,0.0057,0.0042,0.0299,-0.0661], +[16.6833,-0.0164,0.2766,-6.0204,29.5897,0.5,-0.0072,0.037,-0.0808,-0.0092,0.0673,-0.0993,0.0246], +[4.2312,0.3344,0.0389,-4.8857,26.2991,0.583,-0.0104,0.0473,-0.0885,0.0009,0.0958,-0.155,0.0586], +[7.5365,-0.0042,0.4065,-5.8405,25.1459,0.5865,-0.0109,0.0523,-0.0938,0.001,0.0934,-0.1598,0.0738], +[9.1488,-0.3319,0.8441,-9.4288,35.3411,0.6019,-0.0121,0.0661,-0.1243,-0.0028,0.105,-0.187,0.0975], +[8.942,-0.0756,0.7374,-10.0163,38.7888,0.5921,-0.0126,0.0712,-0.1373,0.013,0.076,-0.1417,0.0814], +[7.6195,0.0671,0.6085,-8.8982,34.0775,0.5961,-0.0127,0.0706,-0.1365,0.0147,0.0961,-0.1812,0.1062], +[4.7191,0.0248,0.8039,-10.5118,37.6146,0.6241,-0.014,0.074,-0.1321,0.0285,0.0747,-0.1503,0.0994], +[-3.7807,0.2569,0.5926,-10.5763,40.4022,0.6754,-0.0144,0.0649,-0.1065,0.0265,0.1273,-0.2395,0.1377], +[-4.3588,0.5128,0.4441,-11.0057,43.9366,0.6643,-0.0141,0.0598,-0.0914,0.0297,0.1526,-0.2899,0.1703], +[0.9793,0.277,0.5168,-10.2491,40.6962,0.6426,-0.0127,0.0539,-0.0858,0.0133,0.1639,-0.2987,0.1604], +[4.1744,0.2919,0.5211,-10.2719,41.0334,0.6197,-0.0121,0.0528,-0.0869,0.0122,0.1661,-0.3033,0.1633], +[6.8468,0.1938,0.5369,-9.8873,39.859,0.6088,-0.0115,0.0517,-0.0889,0.0046,0.1768,-0.321,0.1715], +[11.1461,0.2378,0.3678,-8.151,35.8557,0.5761,-0.01,0.044,-0.0795,-0.0007,0.1778,-0.321,0.1698], +[12.4221,0.276,0.2488,-6.8316,31.9031,0.5662,-0.0092,0.0391,-0.073,-0.0089,0.2003,-0.3583,0.1859], +[10.6386,0.5028,0.0451,-6.0581,30.8189,0.5675,-0.0093,0.0395,-0.0789,-0.0048,0.1885,-0.3309,0.1625], +[11.895,0.4259,0.0403,-5.1913,27.4155,0.5654,-0.0088,0.0351,-0.0686,-0.0151,0.216,-0.3783,0.1854], +[15.6199,0.2947,0.1255,-4.8706,25.2474,0.5485,-0.0083,0.0349,-0.0709,-0.0153,0.1958,-0.3402,0.1631], +[19.1961,0.2043,0.1214,-4.058,22.8341,0.5297,-0.0074,0.031,-0.0656,-0.025,0.2093,-0.3615,0.171], +[24.9014,0.1164,0.1324,-3.0351,18.7307,0.4951,-0.0063,0.0283,-0.0649,-0.0265,0.1862,-0.3184,0.1463], +[27.7411,-0.0002,0.251,-3.251,17.9354,0.4835,-0.0062,0.0313,-0.073,-0.026,0.1667,-0.2835,0.1289], +[26.5408,-0.0132,0.3133,-3.6487,17.7499,0.4961,-0.0068,0.0361,-0.0837,-0.0188,0.1384,-0.2306,0.0976], +[24.9608,0.0679,0.2933,-3.7963,17.8167,0.5066,-0.0077,0.043,-0.0991,-0.0102,0.1136,-0.1873,0.0762], +[30.7628,-0.0404,0.3473,-3.514,16.9902,0.4711,-0.0065,0.0402,-0.0991,-0.0135,0.1043,-0.172,0.0705], +[32.9166,-0.0712,0.3957,-3.9,17.9467,0.4584,-0.0062,0.0397,-0.0994,-0.0111,0.0905,-0.1473,0.0576], +[35.8384,-0.154,0.4647,-4.0996,18.2022,0.4447,-0.0061,0.0445,-0.1155,-0.0116,0.0725,-0.1148,0.0406], +[35.8936,-0.2601,0.5885,-4.4079,17.6393,0.4551,-0.0069,0.0522,-0.1317,-0.0062,0.042,-0.0594,0.0107], +[35.6599,-0.2948,0.6396,-4.5403,17.3049,0.4616,-0.0074,0.0559,-0.1397,-0.0065,0.0482,-0.0732,0.0217], +[34.2326,-0.3816,0.7322,-4.795,17.0262,0.4801,-0.0079,0.0573,-0.1393,-0.0049,0.0527,-0.0851,0.0332], +[38.436,-0.518,0.8471,-5.2375,18.6249,0.4592,-0.0074,0.0594,-0.1493,-0.0109,0.0578,-0.0961,0.042], +[37.4759,-0.3108,0.6669,-4.487,17.3228,0.4543,-0.0072,0.0558,-0.1401,-0.0071,0.0668,-0.1148,0.0546], +[38.2626,-0.2565,0.595,-3.8813,15.733,0.4471,-0.0072,0.0565,-0.1436,-0.0047,0.058,-0.0993,0.0468], +[40.1654,-0.373,0.7286,-4.669,17.4341,0.4421,-0.0071,0.0576,-0.1469,-0.0005,0.0365,-0.0612,0.0272], +[42.9794,-0.5548,0.8878,-5.2907,18.8227,0.4348,-0.0069,0.0595,-0.1514,-0.0022,0.033,-0.0585,0.0309], +[45.6449,-0.6118,0.8823,-5.0487,18.8985,0.4196,-0.0061,0.0555,-0.1462,-0.0051,0.0381,-0.069,0.0387], +[46.6551,-0.5689,0.866,-5.0611,19.3856,0.41,-0.0059,0.0537,-0.1435,-0.0027,0.039,-0.0728,0.0431], +[47.5003,-0.5697,0.8793,-5.203,19.8144,0.4057,-0.0059,0.0563,-0.1527,-0.0019,0.0291,-0.0538,0.0314], +[45.403,-0.5065,0.8608,-5.5153,21.0092,0.4195,-0.0064,0.0585,-0.1569,0.0032,0.0197,-0.0361,0.0204], +[44.8971,-0.395,0.8017,-5.6222,21.9379,0.4168,-0.0064,0.0554,-0.147,0.0027,0.0376,-0.069,0.0382], +[47.5247,-0.4291,0.8436,-5.8317,22.6883,0.3999,-0.0058,0.0527,-0.1421,0.0015,0.0382,-0.0702,0.0389], +[46.463,-0.3679,0.8717,-6.4206,23.9766,0.4049,-0.006,0.0518,-0.1372,0.0093,0.0233,-0.0445,0.0258], +[43.9842,-0.1919,0.792,-6.7209,25.4109,0.4126,-0.0063,0.0508,-0.1325,0.0119,0.037,-0.0693,0.0383], +[43.2939,-0.2722,0.8627,-7.0319,25.6372,0.4253,-0.0066,0.052,-0.1346,0.0151,0.022,-0.0414,0.0222], +[44.9267,-0.3058,0.9029,-7.1291,25.4723,0.4173,-0.0066,0.054,-0.1396,0.0166,0.008,-0.0161,0.0087], +[45.3659,-0.1577,0.7596,-6.3854,23.8924,0.4047,-0.006,0.0477,-0.1258,0.015,0.0245,-0.0444,0.0212], +[45.5821,-0.0245,0.5923,-5.4731,22.294,0.3963,-0.0056,0.046,-0.1251,0.0164,0.0239,-0.0431,0.0201], +[47.1433,-0.0461,0.591,-5.2852,21.7529,0.3877,-0.0053,0.0449,-0.1222,0.0153,0.0223,-0.0412,0.0208], +[51.495,-0.1432,0.644,-5.3385,21.775,0.3619,-0.0042,0.0417,-0.1223,0.0089,0.0218,-0.0369,0.0143], +[49.2507,-0.0452,0.5634,-5.0092,21.3118,0.3735,-0.0044,0.0403,-0.1176,0.0104,0.0345,-0.0607,0.0278], +[48.723,-0.0088,0.5464,-5.0086,21.4246,0.3773,-0.0046,0.0403,-0.114,0.0144,0.0211,-0.0365,0.0147], +[46.2919,0.137,0.4328,-4.7097,21.0581,0.387,-0.0047,0.0368,-0.1041,0.0171,0.0335,-0.0595,0.027], +[47.5969,0.1489,0.3829,-4.2807,20.076,0.3772,-0.0039,0.0315,-0.0941,0.0134,0.0397,-0.0681,0.0283], +[48.5103,0.1248,0.3886,-4.0219,19.1219,0.3741,-0.0039,0.0318,-0.0943,0.0115,0.0417,-0.0714,0.03], +[47.0617,0.2003,0.3427,-3.9935,19.2648,0.3815,-0.0041,0.0313,-0.0915,0.0121,0.0505,-0.0878,0.0394], +[47.9002,0.1572,0.3732,-3.8154,17.8605,0.3802,-0.0041,0.032,-0.0944,0.0113,0.0408,-0.067,0.024], +[49.115,0.0782,0.4887,-4.5668,19.8764,0.3783,-0.0042,0.0339,-0.0974,0.0137,0.0304,-0.0508,0.019], +[49.9451,0.1037,0.4323,-3.9989,18.2108,0.3716,-0.0039,0.0318,-0.0942,0.0126,0.0354,-0.0602,0.0246], +[50.1287,0.2012,0.3324,-3.2058,15.608,0.3664,-0.0039,0.0327,-0.0981,0.0177,0.0133,-0.0189,0.0001], +[49.51,0.1993,0.3903,-3.8043,17.1157,0.3729,-0.0042,0.0344,-0.1008,0.0221,0.0041,-0.0038,-0.0061], +[47.0301,0.2961,0.3665,-3.9702,17.4284,0.3864,-0.0047,0.0328,-0.0906,0.0207,0.0246,-0.0408,0.0138], +[46.9571,0.2268,0.4324,-4.3249,18.4933,0.3932,-0.0048,0.0332,-0.0914,0.0225,0.0162,-0.0255,0.0051], +[45.7187,0.319,0.3143,-3.5355,16.3535,0.3986,-0.0048,0.0327,-0.0905,0.0195,0.039,-0.0672,0.0285], +[46.6338,0.3294,0.3122,-3.6994,16.9404,0.3928,-0.0047,0.0327,-0.0892,0.02,0.0422,-0.0754,0.036], +[46.796,0.2184,0.4173,-4.2913,18.3125,0.4005,-0.0048,0.0316,-0.0843,0.0138,0.0632,-0.1146,0.0591], +[45.6059,0.2609,0.3536,-3.7119,16.4744,0.409,-0.005,0.0313,-0.0814,0.0161,0.0671,-0.1239,0.0669], +[46.2843,0.1969,0.384,-3.6001,15.9912,0.4103,-0.005,0.0321,-0.0828,0.0153,0.0735,-0.139,0.08], +[42.7066,0.3391,0.2772,-3.5789,16.5957,0.4304,-0.0057,0.0333,-0.0798,0.0158,0.0981,-0.1852,0.1067], +[42.8015,0.3061,0.3293,-3.7417,16.4765,0.4348,-0.0061,0.0357,-0.0812,0.0203,0.0909,-0.1775,0.1098], +[44.6588,0.3589,0.2756,-3.1211,14.5181,0.4196,-0.0059,0.0374,-0.0881,0.0175,0.0943,-0.1832,0.1126], +[45.4978,0.2369,0.3198,-2.8753,12.9699,0.4238,-0.0058,0.0377,-0.09,0.0126,0.0997,-0.1911,0.1148], +[44.3791,0.247,0.2747,-2.2776,10.7861,0.4342,-0.0061,0.0387,-0.0918,0.0106,0.1113,-0.2121,0.1265], +[44.5213,0.3308,0.2335,-2.5761,12.6357,0.4295,-0.006,0.0393,-0.0953,0.015,0.1005,-0.192,0.1141], +[43.3339,0.3496,0.2289,-2.6952,12.6151,0.4397,-0.0064,0.0411,-0.0987,0.0118,0.1138,-0.2135,0.1223], +[45.7745,0.2806,0.323,-3.0124,12.5836,0.4279,-0.0062,0.0429,-0.1061,0.0132,0.0996,-0.1888,0.1104], +[46.2858,0.2501,0.3239,-2.6897,11.1237,0.4274,-0.0059,0.0399,-0.1008,0.0086,0.1214,-0.2293,0.1336], +[47.1461,0.0565,0.3804,-1.9028,7.5777,0.4368,-0.0058,0.0399,-0.1016,-0.0042,0.1495,-0.2777,0.1579], +[49.8411,-0.0213,0.4353,-2.2574,9.0572,0.4224,-0.0051,0.0374,-0.0989,-0.0067,0.1499,-0.2787,0.1591], +[54.41,-0.2754,0.6713,-3.3139,10.8614,0.4065,-0.0045,0.0392,-0.1059,-0.0134,0.1536,-0.2881,0.1687], +[59.0571,-0.3916,0.714,-3.2563,11.6335,0.3792,-0.0031,0.0313,-0.0925,-0.0235,0.1848,-0.3462,0.2023], +[61.5501,-0.4923,0.8257,-3.7049,12.2735,0.3688,-0.0028,0.0301,-0.0892,-0.0258,0.1974,-0.3735,0.2231], +[62.0991,-0.5602,0.8523,-3.3702,9.855,0.371,-0.0025,0.0277,-0.085,-0.0253,0.1895,-0.3572,0.2113], +[63.7402,-0.7486,1.0333,-4.0639,10.5288,0.3743,-0.0026,0.0296,-0.0853,-0.0264,0.1907,-0.3647,0.2234], +[63.1912,-0.7684,1.0572,-4.1343,10.1666,0.3825,-0.0028,0.0301,-0.0846,-0.0226,0.1752,-0.3347,0.204], +[65.29,-0.9003,1.2109,-4.7056,10.0344,0.3789,-0.0031,0.0353,-0.0982,-0.0171,0.1415,-0.2745,0.173], +[69.7586,-0.9059,1.1421,-3.8514,8.3464,0.3466,-0.0015,0.0272,-0.0852,-0.0254,0.1633,-0.3147,0.1963], +[68.7204,-0.7413,1.161,-4.8929,11.4709,0.347,-0.0023,0.0323,-0.0945,-0.0166,0.1384,-0.2677,0.1676], +[70.0709,-0.7105,1.1845,-4.9763,11.0263,0.3366,-0.0017,0.0271,-0.0857,-0.0132,0.1197,-0.2317,0.1451], +[71.2247,-0.6095,1.0475,-4.2244,9.2028,0.3239,-0.0008,0.022,-0.0796,-0.0212,0.1383,-0.2581,0.1496], +[71.0728,-0.5897,0.954,-3.2255,5.828,0.3275,-0.0005,0.0181,-0.0707,-0.02,0.1457,-0.2721,0.1573], +[70.0217,-0.3531,0.6571,-1.1748,0.806,0.3265,-0.0006,0.0201,-0.0785,-0.0091,0.1053,-0.1976,0.115], +[70.5203,-0.3866,0.7711,-1.2734,-1.0004,0.3319,-0.0017,0.0287,-0.092,0.009,0.0424,-0.0915,0.0678], +[76.3547,-0.7212,0.9341,-1.3303,-1.6526,0.314,-0.0002,0.0247,-0.0938,-0.0122,0.0896,-0.174,0.1101], +[90.6025,-1.3557,1.1746,0.1551,-7.729,0.2521,0.0034,0.0132,-0.0881,-0.0357,0.0885,-0.1674,0.1033], +[102.6662,-1.2263,0.8589,3.2534,-15.7885,0.1576,0.0072,-0.0076,-0.0516,-0.0325,0.0706,-0.1432,0.1009], +[102.9154,-1.5899,1.4523,-0.5061,-7.5933,0.1871,0.0055,0.002,-0.0596,-0.0411,0.1113,-0.2264,0.1604], +[125.2207,-3.3398,2.9466,-5.4863,-1.908,0.1438,0.0076,0.0111,-0.0959,-0.1006,0.1222,-0.2249,0.1376], +[125.8697,-3.2997,3.1051,-7.3155,3.4281,0.1505,0.0067,0.0193,-0.1148,-0.0879,0.0819,-0.1569,0.1076], +[99.6314,-2.8535,3.065,-6.4997,-4.9829,0.3473,-0.001,0.0499,-0.1346,-0.0354,-0.0379,0.0681,-0.0284] +]; + + var _bpCoeff_M_DIA=[ +[-13.567,-1.1325,-1.7078,28.8607,-81.1719,0.4118,0.0003,-0.0263,0.0507,-0.0087,-0.1202,0.2977,-0.2691], +[-43.7777,1.9512,-3.8763,28.8717,-57.6407,0.4741,-0.0029,-0.0496,0.1518,-0.0191,0.1992,-0.2879,0.0508], +[-35.5221,1.6542,-3.2001,22.4882,-41.299,0.4425,-0.0025,-0.0428,0.1269,-0.0674,0.3133,-0.465,0.1062], +[-25.9772,2.0924,-3.8188,24.4956,-38.8551,0.3556,0.0003,-0.0543,0.1499,-0.0796,0.4423,-0.7299,0.2906], +[-16.9931,2.2497,-3.7873,23.1323,-35.1791,0.2916,0.0006,-0.0481,0.1416,-0.0641,0.3962,-0.6572,0.2638], +[-19.6683,2.3137,-3.7117,22.8638,-35.7152,0.3203,-0.0015,-0.0388,0.1406,-0.0689,0.4499,-0.7699,0.3469], +[-33.2858,2.7679,-4.0941,22.3138,-27.6548,0.3986,-0.0021,-0.0592,0.2053,-0.0938,0.6243,-1.0803,0.5056], +[-42.522,3.0229,-4.2155,22.1584,-27.6854,0.4632,-0.0051,-0.0392,0.1567,-0.0631,0.512,-0.8671,0.3759], +[-34.2517,2.7721,-3.6109,17.4453,-15.4161,0.4233,-0.0055,-0.0269,0.1286,-0.0371,0.366,-0.6077,0.2427], +[-42.4833,3.1554,-3.8233,16.9605,-12.0012,0.466,-0.0072,-0.0191,0.1105,-0.0294,0.3572,-0.5855,0.2225], +[-54.4375,3.0764,-3.5785,15.2542,-9.8518,0.569,-0.0112,-0.0014,0.0879,-0.034,0.4004,-0.6627,0.2631], +[-38.5925,2.3768,-3.1326,15.4931,-14.1216,0.5015,-0.0094,0.0059,0.0528,-0.0475,0.355,-0.5818,0.2245], +[-40.8119,2.5241,-3.3547,16.1453,-12.993,0.5119,-0.0092,0.0039,0.0554,-0.0504,0.3968,-0.6637,0.2771], +[-46.3014,2.6717,-3.5156,16.4588,-11.9729,0.5495,-0.0106,0.0106,0.0468,-0.0493,0.4299,-0.7314,0.3246], +[-47.6314,2.9586,-3.758,16.7192,-10.3567,0.5434,-0.0102,0.0067,0.0518,-0.0595,0.4837,-0.8241,0.3686], +[-41.6665,2.9392,-3.8754,17.5857,-10.8233,0.4983,-0.0073,-0.0149,0.0964,-0.0817,0.5737,-0.987,0.4563], +[-45.7369,2.9396,-3.8633,17.231,-10.561,0.5321,-0.008,-0.0146,0.1016,-0.0765,0.5824,-1.0084,0.4748], +[-51.929,2.9378,-3.7832,15.9238,-7.0752,0.586,-0.0101,-0.0013,0.0747,-0.0647,0.5498,-0.9515,0.4469], +[-45.8559,3.0516,-3.9216,17.0729,-10.1336,0.5356,-0.0086,-0.0063,0.0786,-0.0616,0.5196,-0.8956,0.415], +[-39.5605,2.8551,-3.5847,14.9465,-5.3128,0.5025,-0.0082,-0.003,0.0687,-0.0683,0.5134,-0.8848,0.4109], +[-33.7657,2.9223,-3.533,14.1257,-2.6863,0.4575,-0.0075,-0.0012,0.0596,-0.0664,0.4876,-0.8388,0.3872], +[-32.281,2.6018,-3.2278,12.8399,-0.8793,0.472,-0.0081,0.0063,0.0419,-0.062,0.4496,-0.7751,0.3605], +[-31.5797,2.3929,-2.9101,11.2038,1.5782,0.4845,-0.0091,0.0143,0.0265,-0.0586,0.4152,-0.712,0.3258], +[-32.2816,2.6349,-3.0487,11.5875,0.5188,0.4779,-0.0097,0.0203,0.0104,-0.044,0.3694,-0.6297,0.2818], +[-25.44,2.7183,-3.2535,13.5284,-4.0414,0.421,-0.007,0.0038,0.0396,-0.0469,0.3676,-0.6261,0.2792], +[-22.8873,2.5652,-3.2543,13.672,-3.1603,0.4141,-0.0056,-0.0066,0.0583,-0.0566,0.3787,-0.6382,0.2747], +[-20.7911,2.6849,-3.4699,14.9131,-5.2628,0.3921,-0.0042,-0.015,0.0686,-0.0663,0.3974,-0.6642,0.2789], +[-18.557,2.4292,-3.0989,12.2737,1.0228,0.3937,-0.0045,-0.0121,0.0655,-0.073,0.4005,-0.667,0.277], +[-17.5306,2.5085,-3.1093,11.7413,3.3022,0.3838,-0.0047,-0.009,0.0598,-0.0637,0.3744,-0.6243,0.2595], +[-14.3488,2.3673,-3.0068,11.4653,3.7471,0.3712,-0.004,-0.0129,0.0679,-0.0681,0.3759,-0.6244,0.2561], +[-16.6395,2.3516,-2.9622,11.2382,3.1551,0.3924,-0.0047,-0.0114,0.0678,-0.0675,0.3777,-0.6258,0.2543], +[-10.6475,2.2971,-2.8656,10.1755,7.4446,0.3509,-0.0034,-0.0169,0.0752,-0.0763,0.3958,-0.6548,0.2643], +[-10.0847,2.4662,-2.9361,10.2311,6.9534,0.3368,-0.0033,-0.0182,0.08,-0.073,0.3922,-0.6484,0.2607], +[-9.646,2.4037,-2.8587,10.171,5.6614,0.3398,-0.0036,-0.0141,0.0709,-0.0667,0.3688,-0.6116,0.2487], +[-5.5,2.2058,-2.7946,11.4006,-0.0691,0.3246,-0.003,-0.0129,0.0635,-0.0713,0.3492,-0.5757,0.231], +[-3.1184,2.0845,-2.7566,11.9122,-2.7527,0.3161,-0.0025,-0.0137,0.0596,-0.0779,0.347,-0.5661,0.2186], +[-1.8889,1.938,-2.5612,10.5284,0.4557,0.3178,-0.0027,-0.01,0.0505,-0.0868,0.3703,-0.6072,0.2401], +[1.3652,1.8159,-2.5509,11.3987,-2.5982,0.3031,-0.002,-0.0117,0.0496,-0.095,0.3856,-0.6354,0.2568], +[4.1129,1.8155,-2.5332,11.0415,-0.7368,0.2849,-0.0018,-0.0081,0.038,-0.0883,0.364,-0.6035,0.2493], +[1.4862,1.9999,-2.7504,12.2222,-3.4789,0.295,-0.0018,-0.0113,0.0461,-0.0881,0.3736,-0.6168,0.2503], +[-2.474,2.0859,-2.8319,12.5224,-3.8212,0.3229,-0.0028,-0.0094,0.0487,-0.086,0.392,-0.6551,0.2772], +[-0.415,1.9078,-2.6838,12.7489,-6.852,0.3217,-0.0029,-0.0082,0.0472,-0.0801,0.3635,-0.6077,0.2576], +[-0.0497,1.8113,-2.6253,12.8018,-7.7129,0.3277,-0.0029,-0.0071,0.0414,-0.0794,0.3497,-0.5807,0.2402], +[-1.5833,1.7827,-2.6894,13.4925,-9.1732,0.3439,-0.003,-0.0061,0.0371,-0.0845,0.3665,-0.6098,0.2548], +[1.209,1.7298,-2.6076,12.8518,-6.9268,0.3277,-0.0027,-0.0052,0.0323,-0.087,0.3703,-0.6203,0.2656], +[1.2834,1.6318,-2.5106,12.1368,-4.9164,0.335,-0.0025,-0.0086,0.0415,-0.0924,0.386,-0.6467,0.2773], +[-0.4438,1.6936,-2.4801,11.7414,-4.8147,0.3463,-0.0031,-0.0075,0.0435,-0.0895,0.3834,-0.6422,0.2749], +[-0.2325,1.613,-2.4272,12.1673,-8.1046,0.3529,-0.0033,-0.0065,0.0434,-0.0851,0.3606,-0.6019,0.2545], +[-2.1989,1.6982,-2.4926,12.7697,-10.7769,0.3643,-0.0037,-0.0061,0.0459,-0.0859,0.3821,-0.6441,0.2821], +[-0.8411,1.6919,-2.4301,12.0592,-8.667,0.3572,-0.004,-0.0005,0.0305,-0.0865,0.3748,-0.6317,0.2776], +[0.1678,1.6387,-2.3829,11.423,-6.0839,0.3552,-0.0038,-0.0004,0.0275,-0.0933,0.3894,-0.6552,0.2867], +[0.8079,1.7778,-2.4652,11.0582,-4.0097,0.3404,-0.0029,-0.0096,0.0477,-0.0928,0.4036,-0.6792,0.2963], +[-1.1219,1.8103,-2.4361,10.7708,-4.1791,0.3561,-0.0036,-0.0078,0.0484,-0.0819,0.3736,-0.6278,0.2717], +[-4.8133,1.8058,-2.331,9.8828,-2.9487,0.3871,-0.0049,-0.0019,0.0409,-0.0736,0.3513,-0.5879,0.2503], +[-8.1979,2.0298,-2.494,10.6089,-5.3076,0.4011,-0.0058,0.0028,0.0321,-0.0692,0.3504,-0.5851,0.247], +[-6.752,2.0613,-2.4814,10.131,-3.6573,0.3884,-0.0055,0.0002,0.0371,-0.0753,0.3769,-0.6294,0.2655], +[-3.566,1.8329,-2.2802,9.0883,-0.4962,0.3807,-0.005,-0.0007,0.0371,-0.081,0.3819,-0.6401,0.2738], +[1.0387,1.7975,-2.2844,9.2486,-0.6268,0.3494,-0.0037,-0.0064,0.0437,-0.0821,0.3621,-0.6004,0.2472], +[1.6962,1.5592,-2.1909,9.9497,-4.5187,0.3625,-0.0033,-0.0098,0.0505,-0.0904,0.364,-0.5976,0.2383], +[1.7174,1.6924,-2.3499,11.1189,-8.075,0.3556,-0.0029,-0.0144,0.0602,-0.0871,0.3514,-0.5716,0.2195], +[-1.1808,1.896,-2.4788,11.4555,-8.5302,0.3668,-0.0036,-0.0124,0.0586,-0.0775,0.3326,-0.5377,0.2006], +[-1.9286,1.8974,-2.4107,10.6569,-6.2357,0.3747,-0.0042,-0.0079,0.0509,-0.0731,0.3224,-0.5217,0.1951], +[-0.6762,1.6316,-2.0498,8.2301,-0.4293,0.3859,-0.0052,0.0017,0.0314,-0.0748,0.3067,-0.4907,0.1753], +[0.0177,1.3931,-1.7224,6.2104,3.67,0.398,-0.006,0.0074,0.0231,-0.0781,0.3064,-0.4907,0.1763], +[1.8242,1.4415,-1.8531,7.4867,0.3209,0.381,-0.0045,-0.0055,0.0517,-0.0808,0.3148,-0.504,0.181], +[3.3864,1.5296,-1.8957,8.1805,-2.714,0.3667,-0.0046,-0.0044,0.0516,-0.0669,0.2582,-0.4028,0.1272], +[1.4518,1.5557,-2.0588,9.891,-7.5275,0.3836,-0.0047,-0.0045,0.0515,-0.0676,0.2556,-0.3964,0.1218], +[-0.2228,1.7851,-2.3148,11.3445,-10.9345,0.3835,-0.0048,-0.0063,0.0572,-0.0663,0.2738,-0.4312,0.1425], +[-1.2686,1.848,-2.3626,11.0795,-8.9995,0.3885,-0.0049,-0.0053,0.0531,-0.0765,0.3143,-0.5003,0.1745], +[-1.1771,1.9498,-2.33,9.7844,-3.6954,0.382,-0.0052,-0.0022,0.0473,-0.0778,0.3354,-0.5421,0.202], +[-1.5905,1.9246,-2.2012,8.7588,-1.7051,0.39,-0.0063,0.0071,0.0279,-0.0723,0.315,-0.5067,0.1847], +[1.3907,1.7403,-1.9434,6.9646,2.6064,0.3789,-0.006,0.0072,0.0262,-0.0787,0.3279,-0.5282,0.1939], +[5.7059,1.724,-1.9265,7.7741,-2.061,0.3493,-0.0054,0.0068,0.0244,-0.0694,0.282,-0.4467,0.1515], +[12.6597,1.3459,-1.7148,8.837,-8.9553,0.3265,-0.0048,0.0144,-0.0045,-0.065,0.1958,-0.2892,0.0669], +[14.3993,1.3957,-1.9442,11.1527,-15.7051,0.3118,-0.0037,0.0089,-0.0004,-0.0745,0.2201,-0.3286,0.0822], +[17.6818,1.388,-1.9866,11.7883,-17.7697,0.2899,-0.0031,0.0095,-0.0089,-0.0708,0.1938,-0.2807,0.056], +[11.917,1.6817,-2.3045,13.3873,-21.1645,0.3206,-0.0046,0.0186,-0.0278,-0.0691,0.2114,-0.3145,0.0776], +[9.2777,1.6967,-2.2055,11.4045,-13.2029,0.3418,-0.0056,0.0253,-0.0412,-0.0758,0.2487,-0.3832,0.1165], +[5.8584,1.6874,-2.0515,9.5688,-8.1664,0.3719,-0.0073,0.0382,-0.0675,-0.0715,0.2508,-0.3923,0.1289], +[9.3245,1.5374,-1.8954,9.7989,-11.7858,0.3581,-0.0073,0.0413,-0.0754,-0.063,0.2057,-0.3147,0.0928], +[16.2286,1.2597,-1.7964,11.1013,-18.2966,0.3267,-0.0058,0.0385,-0.0835,-0.0656,0.1577,-0.2201,0.0326], +[15.2268,1.0841,-1.7857,12.168,-22.5467,0.3504,-0.0059,0.0373,-0.0777,-0.0718,0.1751,-0.253,0.0528], +[10.4724,1.4733,-2.2295,13.8392,-23.1801,0.3634,-0.0056,0.0276,-0.0497,-0.0848,0.2636,-0.4153,0.1436], +[5.2365,1.5165,-2.1802,12.4214,-17.9441,0.4039,-0.0071,0.0317,-0.0486,-0.0919,0.3179,-0.5147,0.1988], +[10.1259,1.4465,-1.9666,11.6878,-19.1724,0.3722,-0.0063,0.0273,-0.0379,-0.0743,0.2451,-0.3873,0.1349], +[8.7996,1.6042,-2.2123,13.8638,-26.1613,0.3767,-0.006,0.0209,-0.0216,-0.0624,0.2044,-0.3117,0.0907], +[7.3808,1.9753,-2.5467,14.6551,-24.7762,0.366,-0.0058,0.0184,-0.0173,-0.0685,0.2633,-0.4213,0.1535], +[8.2409,1.8093,-1.8703,8.5537,-10.4574,0.3742,-0.008,0.033,-0.0361,-0.0481,0.1904,-0.2951,0.0924], +[16.3443,1.4613,-1.5844,8.5531,-13.7014,0.3376,-0.0067,0.028,-0.0305,-0.0421,0.1473,-0.2208,0.0564], +[13.6814,1.7899,-2.0949,11.8906,-20.3017,0.3408,-0.0062,0.0239,-0.0268,-0.0499,0.1898,-0.2958,0.0953], +[-2.2305,2.0458,-2.0636,8.7608,-9.0684,0.4491,-0.0095,0.0277,-0.0118,-0.0522,0.2641,-0.4295,0.1659], +[7.1024,1.4245,-1.2884,5.4006,-5.1633,0.4266,-0.0107,0.0507,-0.0701,-0.0223,0.0801,-0.0982,-0.0105], +[22.5224,1.2411,-1.1587,5.4827,-6.229,0.3231,-0.008,0.0497,-0.0852,-0.035,0.0837,-0.1047,-0.0066], +[7.1688,2.0574,-2.1429,8.7073,-6.973,0.3913,-0.0079,0.0285,-0.027,-0.0746,0.3209,-0.5246,0.2072], +[10.9219,1.7121,-1.5447,6.0756,-5.588,0.3914,-0.0095,0.0458,-0.0634,-0.034,0.1515,-0.2269,0.0567], +[0.0292,1.3826,-1.5163,7.1831,-10.5716,0.5124,-0.0137,0.0821,-0.1555,-0.0443,0.1613,-0.2416,0.0645], +[-7.4708,1.924,-1.6304,5.8484,-7.4136,0.5394,-0.0152,0.0752,-0.1166,-0.0193,0.205,-0.3492,0.1599], +[17.4158,1.6902,-1.3304,3.6898,3.0431,0.3737,-0.0096,0.0478,-0.0772,-0.0183,0.131,-0.2054,0.0662], +[-2.725,3.8134,-2.3052,3.5243,8.0191,0.4042,-0.0133,0.0238,0.0586,0.0627,0.0422,-0.052,-0.018] +]; + + function calcHeightPctile(age, sex, heightCm) { + var idx = Math.max(0, Math.min(217, Math.round(age * 12) - 24)); + var L, M, S; + if (sex === 'female') { L = _htLMS_F_L[idx]; M = _htLMS_F_M[idx]; S = _htLMS_F_S[idx]; } + else { L = _htLMS_M_L[idx]; M = _htLMS_M_M[idx]; S = _htLMS_M_S[idx]; } + var z = (Math.pow(heightCm / M, L) - 1) / (L * S); + return { z: z, percentile: normalCDF(z) * 100 }; + } + + function computeBPPercentile(age, sex, heightCm, bpType, bpValue) { + var t1, t2, t3, t4, t5, ta1, ta2, ta3, ta4, ta5, tb1, tb2, tb3, tb4, tb5, w; + if (sex === 'female') { + t1=106.7; t2=140.7; t3=154.0; t4=160.5; t5=168.9; + ta1=5.00; ta2=10.70; ta3=13.16; ta4=14.51; ta5=17.33; + tb1=6.701; tb2=16.438; tb3=46.80; tb4=84.46; tb5=203.608; + w = (age - 10) * (heightCm - 147); + } else { + t1=107.8; t2=140.0; t3=154.5; t4=166.4; t5=179.1; + ta1=5.06; ta2=10.79; ta3=13.22; ta4=14.51; ta5=17.30; + tb1=-15; tb2=8.9; tb3=50.375; tb4=112.684; tb5=250.04; + w = (age - 10) * (heightCm - 150); + } + + var x = heightCm, y = age; + + // Height restricted cubic splines + var x2a = Math.max(0, x - t1); var x2b = Math.max(0, x - t4); var x2c = Math.max(0, x - t5); + var x2 = Math.pow(x2a,3) - Math.pow(x2b,3)*(t5-t1)/(t5-t4) + Math.pow(x2c,3)*(t4-t1)/(t5-t4); + var x3a = Math.max(0, x - t2); + var x3 = Math.pow(x3a,3) - Math.pow(x2b,3)*(t5-t2)/(t5-t4) + Math.pow(x2c,3)*(t4-t2)/(t5-t4); + var x4a = Math.max(0, x - t3); + var x4 = Math.pow(x4a,3) - Math.pow(x2b,3)*(t5-t3)/(t5-t4) + Math.pow(x2c,3)*(t4-t3)/(t5-t4); + var x2s = x2/100, x3s = x3/100, x4s = x4/100; + + // Age restricted cubic splines + var y2a = Math.max(0, y - ta1); var y2b = Math.max(0, y - ta4); var y2c = Math.max(0, y - ta5); + var y2 = Math.pow(y2a,3) - Math.pow(y2b,3)*(ta5-ta1)/(ta5-ta4) + Math.pow(y2c,3)*(ta4-ta1)/(ta5-ta4); + var y3a = Math.max(0, y - ta2); + var y3 = Math.pow(y3a,3) - Math.pow(y2b,3)*(ta5-ta2)/(ta5-ta4) + Math.pow(y2c,3)*(ta4-ta2)/(ta5-ta4); + var y4a = Math.max(0, y - ta3); + var y4 = Math.pow(y4a,3) - Math.pow(y2b,3)*(ta5-ta3)/(ta5-ta4) + Math.pow(y2c,3)*(ta4-ta3)/(ta5-ta4); + var y2s = y2/100, y3s = y3/100, y4s = y4/100; + + // Interaction restricted cubic splines + var w2a = Math.max(0, w - tb1); var w2b = Math.max(0, w - tb4); var w2c = Math.max(0, w - tb5); + var w2 = Math.pow(w2a,3) - Math.pow(w2b,3)*(tb5-tb1)/(tb5-tb4) + Math.pow(w2c,3)*(tb4-tb1)/(tb5-tb4); + var w3a = Math.max(0, w - tb2); + var w3 = Math.pow(w3a,3) - Math.pow(w2b,3)*(tb5-tb2)/(tb5-tb4) + Math.pow(w2c,3)*(tb4-tb2)/(tb5-tb4); + var w4a = Math.max(0, w - tb3); + var w4 = Math.pow(w4a,3) - Math.pow(w2b,3)*(tb5-tb3)/(tb5-tb4) + Math.pow(w2c,3)*(tb4-tb3)/(tb5-tb4); + var w2s = w2/10000, w3s = w3/10000, w4s = w4/10000; + + // Select coefficient array + var coeff; + if (sex === 'female') coeff = (bpType === 'sys') ? _bpCoeff_F_SYS : _bpCoeff_F_DIA; + else coeff = (bpType === 'sys') ? _bpCoeff_M_SYS : _bpCoeff_M_DIA; + + // Compute predicted BP at each percentile and find closest match + var fxsys = new Array(99); + for (var i = 0; i < 99; i++) { + fxsys[i] = coeff[i][0] + coeff[i][5]*x + coeff[i][6]*x2s + coeff[i][7]*x3s + coeff[i][8]*x4s + + coeff[i][1]*y + coeff[i][2]*y2s + coeff[i][3]*y3s + coeff[i][4]*y4s + + coeff[i][9]*w + coeff[i][10]*w2s + coeff[i][11]*w3s + coeff[i][12]*w4s; + } + + var minDiff = Infinity, percentile = 50; + for (var i = 0; i < 99; i++) { + var diff = Math.abs(bpValue - fxsys[i]); + if (diff < minDiff) { minDiff = diff; percentile = i + 1; } + } + return { percentile: percentile, predicted: fxsys }; + } + + function classifyBPFromPercentiles(age, sysPctile, diaPctile, sys, dia) { var sysClass, diaClass; if (age >= 13) { @@ -88,37 +532,21 @@ else diaClass = 'normal'; } else { // Ages 1-<13: use percentile thresholds - if (sys >= r.sys95 + 12 || sys >= 140) sysClass = 'stage2'; - else if (sys >= r.sys95 || sys >= 130) sysClass = 'stage1'; - else if (sys >= r.sys90 || sys >= 120) sysClass = 'elevated'; - else sysClass = 'normal'; + if (sysPctile >= 95 + 12 || sys >= 140) sysClass = 'stage2'; + else if (sysPctile >= 95 || sys >= 130) sysClass = 'stage1'; + else if (sysPctile >= 90 || sys >= 120) sysClass = 'elevated'; + else sysClass = 'normal'; - if (dia >= r.dia95 + 12 || dia >= 90) diaClass = 'stage2'; - else if (dia >= r.dia95 || dia >= 80) diaClass = 'stage1'; - else if (dia >= r.dia90) diaClass = 'elevated'; - else diaClass = 'normal'; + if (diaPctile >= 95 + 12 || dia >= 90) diaClass = 'stage2'; + else if (diaPctile >= 95 || dia >= 80) diaClass = 'stage1'; + else if (diaPctile >= 90) diaClass = 'elevated'; + else diaClass = 'normal'; } - // Overall classification = highest of systolic or diastolic var levels = { normal: 0, elevated: 1, stage1: 2, stage2: 3 }; var overall = levels[sysClass] >= levels[diaClass] ? sysClass : diaClass; - // Estimate percentiles - function estimatePctile(val, p50, p90, p95) { - if (val <= p50) return Math.max(1, Math.round(50 * val / p50)); - if (val <= p90) return Math.round(50 + 40 * (val - p50) / (p90 - p50)); - if (val <= p95) return Math.round(90 + 5 * (val - p90) / (p95 - p90)); - return Math.min(99, Math.round(95 + 4 * (val - p95) / 12)); - } - - return { - sysPercentile: estimatePctile(sys, r.sys50, r.sys90, r.sys95), - diaPercentile: estimatePctile(dia, r.dia50, r.dia90, r.dia95), - sysClass: sysClass, - diaClass: diaClass, - classification: overall, - ref: r - }; + return { sysClass: sysClass, diaClass: diaClass, classification: overall }; } var classLabels = { @@ -133,75 +561,124 @@ var sex = document.getElementById('bp-sex').value; var sys = parseFloat(document.getElementById('bp-systolic').value); var dia = parseFloat(document.getElementById('bp-diastolic').value); + var heightCm = parseFloat(document.getElementById('bp-height').value); - if (!age || !sex || !sys || !dia) { showToast('Fill in all fields', 'error'); return; } + if (!age || !sex || !sys || !dia || !heightCm) { showToast('Fill in all fields including height', 'error'); return; } if (age < 1 || age > 17) { showToast('Age must be 1-17 years', 'error'); return; } - var ref = sex === 'male' ? bpBoys : bpGirls; - var result = classifyBP(age, sys, dia, ref); - if (!result) { showToast('Invalid age', 'error'); return; } + var htResult = calcHeightPctile(age, sex, heightCm); + var sysResult = computeBPPercentile(age, sex, heightCm, 'sys', sys); + var diaResult = computeBPPercentile(age, sex, heightCm, 'dia', dia); - var cl = classLabels[result.classification]; + var bpClass = classifyBPFromPercentiles(age, sysResult.percentile, diaResult.percentile, sys, dia); + + // Get 50th, 90th, 95th predicted values for display + var sys50 = sysResult.predicted[49].toFixed(0), sys90 = sysResult.predicted[89].toFixed(0), sys95 = sysResult.predicted[94].toFixed(0); + var dia50 = diaResult.predicted[49].toFixed(0), dia90 = diaResult.predicted[89].toFixed(0), dia95 = diaResult.predicted[94].toFixed(0); + + var cl = classLabels[bpClass.classification]; var resultDiv = document.getElementById('bp-result'); resultDiv.classList.remove('hidden'); resultDiv.innerHTML = 'Reference values at 50th height percentile. For precise percentiles adjusted to patient height, consult the full AAP 2017 tables.
'; + 'BCM/Rosner quantile regression percentiles adjusted to patient height. AAP 2017 classification.
'; + + // Generate BP curves across ages 1-17 for this sex/height + renderBPChart(age, sex, heightCm, sys, dia); }); + + function renderBPChart(patientAge, sex, heightCm, patientSys, patientDia) { + if (typeof Chart === 'undefined') return; + var container = document.getElementById('bp-chart-container'); + if (!container) return; + container.classList.remove('hidden'); + if (_chartInstances['bp-chart-canvas']) { _chartInstances['bp-chart-canvas'].destroy(); _chartInstances['bp-chart-canvas'] = null; } + + // Generate percentile curves across ages 1-17 + var sys50 = [], sys90 = [], sys95 = [], dia50 = [], dia90 = [], dia95 = []; + for (var a = 1; a <= 17; a++) { + var sr = computeBPPercentile(a, sex, heightCm, 'sys', 100); + var dr = computeBPPercentile(a, sex, heightCm, 'dia', 60); + sys50.push({x:a, y:Math.round(sr.predicted[49])}); sys90.push({x:a, y:Math.round(sr.predicted[89])}); sys95.push({x:a, y:Math.round(sr.predicted[94])}); + dia50.push({x:a, y:Math.round(dr.predicted[49])}); dia90.push({x:a, y:Math.round(dr.predicted[89])}); dia95.push({x:a, y:Math.round(dr.predicted[94])}); + } + + var datasets = [ + { label: 'SBP 95th', data: sys95, borderColor: 'rgba(239,68,68,0.7)', borderWidth: 2, borderDash: [4,4], pointRadius: 0, fill: false, tension: 0.3 }, + { label: 'SBP 90th', data: sys90, borderColor: 'rgba(249,115,22,0.6)', borderWidth: 1.5, borderDash: [3,3], pointRadius: 0, fill: false, tension: 0.3 }, + { label: 'SBP 50th', data: sys50, borderColor: 'rgba(16,185,129,0.8)', borderWidth: 2, pointRadius: 0, fill: false, tension: 0.3 }, + { label: 'DBP 95th', data: dia95, borderColor: 'rgba(239,68,68,0.4)', borderWidth: 1.5, borderDash: [4,4], pointRadius: 0, fill: false, tension: 0.3 }, + { label: 'DBP 90th', data: dia90, borderColor: 'rgba(249,115,22,0.3)', borderWidth: 1, borderDash: [3,3], pointRadius: 0, fill: false, tension: 0.3 }, + { label: 'DBP 50th', data: dia50, borderColor: 'rgba(16,185,129,0.4)', borderWidth: 1.5, pointRadius: 0, fill: false, tension: 0.3 }, + { label: 'Patient SBP', data: [{x:patientAge, y:patientSys}], backgroundColor: '#2563eb', borderColor: '#1d4ed8', pointRadius: 8, pointHoverRadius: 10, showLine: false, type: 'scatter', order: 0 }, + { label: 'Patient DBP', data: [{x:patientAge, y:patientDia}], backgroundColor: '#7c3aed', borderColor: '#6d28d9', pointRadius: 8, pointHoverRadius: 10, pointStyle: 'triangle', showLine: false, type: 'scatter', order: 0 } + ]; + + _chartInstances['bp-chart-canvas'] = new Chart(document.getElementById('bp-chart-canvas'), { + type: 'line', + data: { datasets: datasets }, + options: { + responsive: true, maintainAspectRatio: true, aspectRatio: 1.6, + animation: { duration: 300 }, + scales: { + x: { type: 'linear', title: { display: true, text: 'Age (years)', font: { size: 12, weight: 'bold' } }, min: 1, max: 17, ticks: { stepSize: 1 }, grid: { color: 'rgba(0,0,0,0.05)' } }, + y: { title: { display: true, text: 'Blood Pressure (mmHg)', font: { size: 12, weight: 'bold' } }, min: 30, grid: { color: 'rgba(0,0,0,0.05)' } } + }, + plugins: { + legend: { display: true, position: 'bottom', labels: { font: { size: 10 }, usePointStyle: true } }, + tooltip: { + callbacks: { + label: function(ctx) { + if (ctx.dataset.label.indexOf('Patient') !== -1) return ctx.dataset.label + ': ' + ctx.parsed.y + ' mmHg'; + return ctx.dataset.label + ': ' + ctx.parsed.y + ' mmHg at age ' + ctx.parsed.x; + } + } + } + } + } + }); + } + document.getElementById('btn-clear-bp').addEventListener('click', function() { ['bp-age', 'bp-sex', 'bp-height', 'bp-systolic', 'bp-diastolic'].forEach(function(id) { var el = document.getElementById(id); if (el) el.value = ''; }); document.getElementById('bp-result').classList.add('hidden'); + var bpc = document.getElementById('bp-chart-container'); if (bpc) bpc.classList.add('hidden'); }); // ═══════════════════════════════════════════════════════════ // BMI PERCENTILE — CDC 2000 // ═══════════════════════════════════════════════════════════ - // CDC LMS parameters for BMI-for-age (selected ages, interpolated) - // Source: CDC 2000 growth charts - var bmiLMS = { - male: { - 2:{L:-1.862,M:16.42,S:0.08671}, 3:{L:-1.517,M:16.01,S:0.08726}, 4:{L:-1.157,M:15.75,S:0.08854}, - 5:{L:-0.867,M:15.63,S:0.09087}, 6:{L:-0.676,M:15.62,S:0.09411}, 7:{L:-0.556,M:15.73,S:0.09808}, - 8:{L:-0.478,M:15.97,S:0.10261}, 9:{L:-0.412,M:16.32,S:0.10756}, 10:{L:-0.348,M:16.79,S:0.11278}, - 11:{L:-0.282,M:17.37,S:0.11813}, 12:{L:-0.213,M:18.05,S:0.12348}, 13:{L:-0.146,M:18.79,S:0.12860}, - 14:{L:-0.084,M:19.56,S:0.13321}, 15:{L:-0.029,M:20.31,S:0.13706}, 16:{L:0.017,M:21.01,S:0.14001}, - 17:{L:0.053,M:21.64,S:0.14202}, 18:{L:0.080,M:22.17,S:0.14317}, 19:{L:0.098,M:22.62,S:0.14361}, - 20:{L:0.109,M:22.99,S:0.14352} - }, - female: { - 2:{L:-0.948,M:16.13,S:0.09486}, 3:{L:-0.586,M:15.77,S:0.09543}, 4:{L:-0.307,M:15.56,S:0.09727}, - 5:{L:-0.119,M:15.47,S:0.10053}, 6:{L:-0.005,M:15.51,S:0.10497}, 7:{L:0.061,M:15.69,S:0.11022}, - 8:{L:0.097,M:16.01,S:0.11598}, 9:{L:0.117,M:16.47,S:0.12196}, 10:{L:0.130,M:17.05,S:0.12794}, - 11:{L:0.139,M:17.72,S:0.13369}, 12:{L:0.148,M:18.44,S:0.13897}, 13:{L:0.157,M:19.16,S:0.14361}, - 14:{L:0.165,M:19.83,S:0.14743}, 15:{L:0.172,M:20.41,S:0.15034}, 16:{L:0.177,M:20.88,S:0.15231}, - 17:{L:0.180,M:21.24,S:0.15339}, 18:{L:0.181,M:21.49,S:0.15371}, 19:{L:0.181,M:21.65,S:0.15345}, - 20:{L:0.179,M:21.75,S:0.15278} - } - }; + // CDC BMI-for-Age 24-240mo (every 3 months, from CDC bmiagerev.csv) + var bmiLMS = {male:{24:{L:-1.982374,M:16.5478,S:0.080127},30:{L:-1.642107,M:16.2497,S:0.075499},36:{L:-1.419991,M:16.0003,S:0.072634},42:{L:-1.438165,M:15.7941,S:0.071495},48:{L:-1.714869,M:15.6282,S:0.071889},54:{L:-2.155348,M:15.5026,S:0.073491},60:{L:-2.615166,M:15.4191,S:0.075992},66:{L:-2.981797,M:15.3795,S:0.079211},72:{L:-3.211705,M:15.3835,S:0.083048},78:{L:-3.314769,M:15.429,S:0.0874},84:{L:-3.323189,M:15.5129,S:0.092131},90:{L:-3.270455,M:15.6317,S:0.097082},96:{L:-3.183058,M:15.7823,S:0.102091},102:{L:-3.079383,M:15.9617,S:0.107013},108:{L:-2.971148,M:16.1671,S:0.111721},114:{L:-2.865311,M:16.3961,S:0.116113},120:{L:-2.765648,M:16.6461,S:0.120112},126:{L:-2.673903,M:16.9151,S:0.123664},132:{L:-2.59056,M:17.2009,S:0.126735},138:{L:-2.51532,M:17.5014,S:0.129309},144:{L:-2.447426,M:17.8146,S:0.131389},150:{L:-2.385858,M:18.1387,S:0.132991},156:{L:-2.329457,M:18.4718,S:0.134141},162:{L:-2.277017,M:18.812,S:0.13488},168:{L:-2.227362,M:19.1576,S:0.135251},174:{L:-2.179426,M:19.5067,S:0.135309},180:{L:-2.132345,M:19.8577,S:0.13511},186:{L:-2.085574,M:20.2086,S:0.134718},192:{L:-2.039015,M:20.5576,S:0.134198},198:{L:-1.99315,M:20.9029,S:0.13362},204:{L:-1.949135,M:21.2425,S:0.133057},210:{L:-1.908831,M:21.5742,S:0.132585},216:{L:-1.87467,M:21.8959,S:0.132286},222:{L:-1.849323,M:22.2054,S:0.132249},228:{L:-1.835138,M:22.5007,S:0.132566},234:{L:-1.833401,M:22.7799,S:0.133339},240:{L:-1.843581,M:23.0414,S:0.134675}},female:{24:{L:-1.024497,M:16.388,S:0.085026},30:{L:-1.534542,M:16.0059,S:0.080932},36:{L:-2.096829,M:15.6992,S:0.078605},42:{L:-2.618733,M:15.4647,S:0.077904},48:{L:-3.018522,M:15.2985,S:0.078713},54:{L:-3.2593,M:15.1961,S:0.080904},60:{L:-3.350078,M:15.1519,S:0.0843},66:{L:-3.325522,M:15.1606,S:0.08868},72:{L:-3.225607,M:15.2169,S:0.093803},78:{L:-3.084291,M:15.3161,S:0.099427},84:{L:-2.926187,M:15.4536,S:0.105325},90:{L:-2.76731,M:15.6252,S:0.111295},96:{L:-2.617192,M:15.827,S:0.117159},102:{L:-2.480952,M:16.0552,S:0.122771},108:{L:-2.360921,M:16.3061,S:0.128014},114:{L:-2.257782,M:16.5763,S:0.132797},120:{L:-2.171296,M:16.8623,S:0.137057},126:{L:-2.100749,M:17.161,S:0.140754},132:{L:-2.045235,M:17.4691,S:0.143868},138:{L:-2.003802,M:17.7836,S:0.146399},144:{L:-1.975521,M:18.1015,S:0.148361},150:{L:-1.95952,M:18.42,S:0.149783},156:{L:-1.954978,M:18.7364,S:0.150705},162:{L:-1.9611,M:19.0481,S:0.151176},168:{L:-1.977074,M:19.3526,S:0.151256},174:{L:-2.002014,M:19.6475,S:0.15101},180:{L:-2.034893,M:19.9306,S:0.150512},186:{L:-2.07446,M:20.1998,S:0.149843},192:{L:-2.119157,M:20.4533,S:0.14909},198:{L:-2.167045,M:20.6891,S:0.148349},204:{L:-2.215738,M:20.9058,S:0.147723},210:{L:-2.262382,M:21.1016,S:0.147323},216:{L:-2.303688,M:21.2753,S:0.147269},222:{L:-2.336038,M:21.4255,S:0.147689},228:{L:-2.355678,M:21.5508,S:0.148724},234:{L:-2.35898,M:21.6501,S:0.150521},240:{L:-2.342797,M:21.7219,S:0.153241}}}; function calcBMIPercentile(bmi, L, M, S) { // Z-score from LMS: Z = ((BMI/M)^L - 1) / (L * S) @@ -225,6 +702,137 @@ return 0.5 * (1 + sign * y); } + // ═══════════════════════════════════════════════════════════ + // CHART.JS GROWTH CURVE RENDERING + // ═══════════════════════════════════════════════════════════ + + // Inverse LMS: given Z-score, return measurement value + function valueFromLMS(L, M, S, z) { + if (Math.abs(L) < 0.001) return M * Math.exp(S * z); + return M * Math.pow(1 + L * S * z, 1 / L); + } + + var PERCENTILE_LINES = [ + { p: 3, z: -1.88079, color: 'rgba(239,68,68,0.4)', dash: [4,4], width: 1 }, + { p: 5, z: -1.64485, color: 'rgba(249,115,22,0.4)', dash: [3,3], width: 1 }, + { p: 10, z: -1.28155, color: 'rgba(234,179,8,0.5)', dash: [2,2], width: 1 }, + { p: 25, z: -0.67449, color: 'rgba(163,163,163,0.5)',dash: [2,2], width: 1 }, + { p: 50, z: 0, color: 'rgba(16,185,129,0.9)', dash: [], width: 2.5 }, + { p: 75, z: 0.67449, color: 'rgba(163,163,163,0.5)',dash: [2,2], width: 1 }, + { p: 90, z: 1.28155, color: 'rgba(234,179,8,0.5)', dash: [2,2], width: 1 }, + { p: 95, z: 1.64485, color: 'rgba(249,115,22,0.4)', dash: [3,3], width: 1 }, + { p: 97, z: 1.88079, color: 'rgba(239,68,68,0.4)', dash: [4,4], width: 1 } + ]; + + function generatePercentileCurves(lmsTable, percentileLines) { + var ages = Object.keys(lmsTable).map(Number).sort(function(a,b){return a-b;}); + var datasets = []; + percentileLines.forEach(function(pl, idx) { + var points = []; + ages.forEach(function(age) { + var lms = lmsTable[age]; + var val = valueFromLMS(lms.L, lms.M, lms.S, pl.z); + if (isFinite(val) && val > 0) points.push({ x: age, y: Math.round(val * 100) / 100 }); + }); + datasets.push({ + label: pl.p + 'th', + data: points, + borderColor: pl.color, + borderWidth: pl.width, + borderDash: pl.dash, + pointRadius: 0, + pointHoverRadius: 0, + fill: false, + tension: 0.4, + order: 10 + }); + }); + // Add fill bands between symmetric percentiles (3-97, 5-95, 10-90, 25-75) + // Use the 50th as center reference + var fills = [ + { outer: 0, inner: 8, color: 'rgba(239,68,68,0.06)' }, // 3rd-97th + { outer: 1, inner: 7, color: 'rgba(249,115,22,0.06)' }, // 5th-95th + { outer: 2, inner: 6, color: 'rgba(234,179,8,0.06)' }, // 10th-90th + { outer: 3, inner: 5, color: 'rgba(163,163,163,0.06)' } // 25th-75th + ]; + fills.forEach(function(f) { + if (datasets[f.outer] && datasets[f.inner]) { + datasets[f.outer].fill = { target: f.inner, above: f.color, below: f.color }; + } + }); + return datasets; + } + + var _chartInstances = {}; + + function renderGrowthChart(canvasId, containerId, lmsTable, patientX, patientY, xLabel, yLabel, extraDatasets) { + if (typeof Chart === 'undefined') return; // Chart.js not loaded yet + + var container = document.getElementById(containerId); + if (!container) return; + container.classList.remove('hidden'); + + if (_chartInstances[canvasId]) { _chartInstances[canvasId].destroy(); _chartInstances[canvasId] = null; } + + var datasets = generatePercentileCurves(lmsTable, PERCENTILE_LINES); + + // Patient data point + datasets.push({ + label: 'Patient', + data: [{ x: patientX, y: patientY }], + backgroundColor: '#2563eb', + borderColor: '#1d4ed8', + pointRadius: 8, + pointHoverRadius: 10, + pointStyle: 'circle', + showLine: false, + type: 'scatter', + order: 0 + }); + + if (extraDatasets) extraDatasets.forEach(function(d) { datasets.push(d); }); + + _chartInstances[canvasId] = new Chart(document.getElementById(canvasId), { + type: 'line', + data: { datasets: datasets }, + options: { + responsive: true, + maintainAspectRatio: true, + aspectRatio: 1.6, + animation: { duration: 300 }, + scales: { + x: { + type: 'linear', + title: { display: true, text: xLabel, font: { size: 12, weight: 'bold' } }, + grid: { color: 'rgba(0,0,0,0.05)' } + }, + y: { + title: { display: true, text: yLabel, font: { size: 12, weight: 'bold' } }, + grid: { color: 'rgba(0,0,0,0.05)' } + } + }, + plugins: { + legend: { display: false }, + tooltip: { + callbacks: { + label: function(ctx) { + if (ctx.dataset.label === 'Patient') return 'Patient: ' + ctx.parsed.y.toFixed(1) + ' ' + yLabel.split('(').pop().replace(')', ''); + return ctx.dataset.label + ': ' + ctx.parsed.y.toFixed(1); + } + } + } + } + } + }); + } + + // Mid-parental height calculation + function calcMidParentalHeight(motherHt, fatherHt, sex) { + if (!motherHt || !fatherHt) return null; + var mph = sex === 'male' ? (motherHt + fatherHt + 13) / 2 : (motherHt + fatherHt - 13) / 2; + return { target: mph, low: mph - 8.5, high: mph + 8.5 }; + } + // Extended BMI classification per CDC 2022 // Uses % of 95th percentile for severe obesity staging function classifyBMI(percentile, bmi, lms) { @@ -247,7 +855,9 @@ } document.getElementById('btn-calc-bmi').addEventListener('click', function() { - var age = parseFloat(document.getElementById('bmi-age').value); + var ageYr = parseFloat(document.getElementById('bmi-age-yr').value) || 0; + var ageMo = parseInt(document.getElementById('bmi-age-mo').value) || 0; + var age = ageYr + ageMo / 12; var sex = document.getElementById('bmi-sex').value; var weight = parseFloat(document.getElementById('bmi-weight').value); var height = parseFloat(document.getElementById('bmi-height').value); @@ -256,10 +866,10 @@ if (age < 2 || age > 20) { showToast('Age must be 2-20 years', 'error'); return; } var bmi = weight / Math.pow(height / 100, 2); - var ageRound = Math.round(age); - if (ageRound < 2) ageRound = 2; - if (ageRound > 20) ageRound = 20; - var lms = bmiLMS[sex][ageRound]; + var ageMonths = Math.round(age * 12); + if (ageMonths < 24) ageMonths = 24; + if (ageMonths > 240) ageMonths = 240; + var lms = interpolateLMS(bmiLMS[sex], ageMonths); if (!lms) { showToast('Invalid age/sex', 'error'); return; } var result = calcBMIPercentile(bmi, lms.L, lms.M, lms.S); @@ -283,10 +893,12 @@ 'GA ' + ga + ' weeks, ' + (risk === 'medium' ? 'with' : 'without') + ' neurotoxicity risk factors. AAP 2022 CPG. Always use clinical judgment.
'; + + // Chart: phototherapy threshold line vs patient + renderBiliChart(hours, tsb, [ + { label: 'Phototherapy Threshold', data: generateThresholdCurve(table), borderColor: '#ef4444', borderWidth: 2, borderDash: [], fill: { target: 'origin', above: 'rgba(239,68,68,0.08)' } } + ]); }); document.getElementById('btn-clear-bili-aap').addEventListener('click', function() { @@ -675,6 +1369,7 @@ var el = document.getElementById(id); if (el) el.value = ''; }); document.getElementById('bili-result').classList.add('hidden'); + var bc = document.getElementById('bili-chart-container'); if (bc) bc.classList.add('hidden'); }); // Bhutani nomogram zones (approximate hour-specific TSB boundaries) @@ -716,6 +1411,13 @@ 'Bhutani hour-specific nomogram for infants >= 35 weeks GA. Bhutani et al., Pediatrics 1999.
'; + + // Chart: Bhutani zone curves with patient + renderBiliChart(hours, tsb, [ + { label: '95th (High-Risk)', data: generateThresholdCurve(bhutaniZones.p95), borderColor: '#ef4444', borderWidth: 2, fill: false, borderDash: [] }, + { label: '75th (High-Intermed)', data: generateThresholdCurve(bhutaniZones.p75), borderColor: '#f97316', borderWidth: 1.5, fill: { target: '-1', above: 'rgba(239,68,68,0.08)' }, borderDash: [3,3] }, + { label: '40th (Low-Intermed)', data: generateThresholdCurve(bhutaniZones.p40), borderColor: '#f59e0b', borderWidth: 1.5, fill: { target: '-1', above: 'rgba(249,115,22,0.08)' }, borderDash: [3,3] } + ]); }); document.getElementById('btn-clear-bhutani').addEventListener('click', function() { @@ -723,6 +1425,7 @@ var el = document.getElementById(id); if (el) el.value = ''; }); document.getElementById('bili-result').classList.add('hidden'); + var bc = document.getElementById('bili-chart-container'); if (bc) bc.classList.add('hidden'); }); } })(); diff --git a/public/js/chartReview.js b/public/js/chartReview.js index fd65efe..5a18ee0 100644 --- a/public/js/chartReview.js +++ b/public/js/chartReview.js @@ -168,6 +168,7 @@ outputCard.classList.remove('hidden'); outputCard.scrollIntoView({ behavior: 'smooth' }); showToast('Chart review generated!', 'success'); + if (typeof suggestBillingCodes === 'function') suggestBillingCodes('cr-review-text', data.review, 'chart', document.getElementById('cr-age').value); } else showToast(data.error || 'Failed', 'error'); }) .catch(function(err) { hideBusy(); showToast(err.message, 'error'); }); diff --git a/public/js/hospitalCourse.js b/public/js/hospitalCourse.js index 343788e..a6ae360 100644 --- a/public/js/hospitalCourse.js +++ b/public/js/hospitalCourse.js @@ -175,6 +175,7 @@ clarifyOutput.classList.add('hidden'); outputCard.scrollIntoView({ behavior: 'smooth' }); showToast('Hospital course generated!', 'success'); + if (typeof suggestBillingCodes === 'function') suggestBillingCodes('hc-course-text', data.hospitalCourse, 'hospital', document.getElementById('hc-age').value, document.getElementById('hc-setting').value); } else showToast(data.error || 'Failed', 'error'); }) .catch(function(err) { hideBusy(); showToast(err.message, 'error'); }); diff --git a/public/js/liveEncounter.js b/public/js/liveEncounter.js index 3676a5d..ea7e77c 100644 --- a/public/js/liveEncounter.js +++ b/public/js/liveEncounter.js @@ -124,27 +124,45 @@ pauseBtn.addEventListener('click', function() { if (!isRecording) return; if (!isPaused) { - if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'recording') { - recorder.mediaRecorder.pause(); - timer.stop(); - isPaused = true; - pauseBtn.innerHTML = ' Resume'; - pauseBtn.classList.add('btn-primary'); - pauseBtn.classList.remove('btn-ghost'); - if (recognition) try { recognition.stop(); } catch(e) {} - showToast('Recording paused', 'info'); + // Pause: try MediaRecorder.pause(), fall back to stop+accumulate + if (recorder.mediaRecorder) { + try { + if (typeof recorder.mediaRecorder.pause === 'function' && recorder.mediaRecorder.state === 'recording') { + recorder.mediaRecorder.pause(); + } + } catch(e) { console.warn('[Rec] Pause not supported:', e.message); } } + timer.stop(); + isPaused = true; + pauseBtn.innerHTML = ' Resume'; + pauseBtn.classList.add('btn-primary'); + pauseBtn.classList.remove('btn-ghost'); + if (recognition) try { recognition.stop(); } catch(e) {} + showToast('Recording paused', 'info'); } else { - if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'paused') { - recorder.mediaRecorder.resume(); - timer.start(); - isPaused = false; - pauseBtn.innerHTML = ' Pause'; - pauseBtn.classList.remove('btn-primary'); - pauseBtn.classList.add('btn-ghost'); - if (recognition) try { recognition.start(); } catch(e) {} - showToast('Recording resumed', 'info'); + // Resume: try MediaRecorder.resume(), fall back to just restarting recognition + if (recorder.mediaRecorder) { + try { + if (typeof recorder.mediaRecorder.resume === 'function' && recorder.mediaRecorder.state === 'paused') { + recorder.mediaRecorder.resume(); + } else if (recorder.mediaRecorder.state === 'inactive') { + // MediaRecorder was stopped (browser killed it) — restart it on the same stream + if (recorder.stream && recorder.stream.active) { + var mime = MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm'; + recorder.mediaRecorder = new MediaRecorder(recorder.stream, { mimeType: mime, audioBitsPerSecond: 32000 }); + recorder.mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) recorder.chunks.push(e.data); }; + recorder.mediaRecorder.start(1000); + } + } + } catch(e) { console.warn('[Rec] Resume error:', e.message); } } + timer.resume(); + isPaused = false; + pauseBtn.innerHTML = ' Pause'; + pauseBtn.classList.remove('btn-primary'); + pauseBtn.classList.add('btn-ghost'); + if (recognition) try { recognition.start(); } catch(e) {} + showToast('Recording resumed', 'info'); } }); } @@ -190,6 +208,7 @@ outputCard.classList.remove('hidden'); outputCard.scrollIntoView({ behavior: 'smooth' }); showToast('HPI generated!', 'success'); + if (typeof suggestBillingCodes === 'function') suggestBillingCodes('enc-hpi-text', data.hpi, 'hpi', document.getElementById('enc-age').value, document.getElementById('enc-setting').value); } else showToast(data.error || 'Failed', 'error'); }) .catch(function(err) { hideBusy(); showToast(err.message, 'error'); }); diff --git a/public/js/shadess.js b/public/js/shadess.js index 47a1225..f48ae6c 100644 --- a/public/js/shadess.js +++ b/public/js/shadess.js @@ -298,14 +298,22 @@ pauseBtn.addEventListener('click', function() { if (!_shadessRecording || !_shadessRecorder || !_shadessRecorder.mediaRecorder) return; if (!_shadessIsPaused) { - _shadessRecorder.mediaRecorder.pause(); + try { if (_shadessRecorder.mediaRecorder.state === 'recording') _shadessRecorder.mediaRecorder.pause(); } catch(e) {} _shadessTimer.stop(); _shadessIsPaused = true; pauseBtn.innerHTML = ' Resume'; if (_shhadessRecognition) try { _shhadessRecognition.stop(); } catch(e) {} } else { - _shadessRecorder.mediaRecorder.resume(); - _shadessTimer.start(); + try { + if (_shadessRecorder.mediaRecorder.state === 'paused') { _shadessRecorder.mediaRecorder.resume(); } + else if (_shadessRecorder.mediaRecorder.state === 'inactive' && _shadessRecorder.stream && _shadessRecorder.stream.active) { + var mime = MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm'; + _shadessRecorder.mediaRecorder = new MediaRecorder(_shadessRecorder.stream, { mimeType: mime, audioBitsPerSecond: 32000 }); + _shadessRecorder.mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) _shadessRecorder.chunks.push(e.data); }; + _shadessRecorder.mediaRecorder.start(1000); + } + } catch(e) {} + _shadessTimer.resume(); _shadessIsPaused = false; pauseBtn.innerHTML = ' Pause'; if (_shhadessRecognition) try { _shhadessRecognition.start(); } catch(e) {} @@ -761,11 +769,21 @@ pauseBtn.addEventListener('click', function() { if (!_wvRecording || !_wvRecorder || !_wvRecorder.mediaRecorder) return; if (!_wvPaused) { - _wvRecorder.mediaRecorder.pause(); _wvTimer.stop(); _wvPaused = true; + try { if (_wvRecorder.mediaRecorder.state === 'recording') _wvRecorder.mediaRecorder.pause(); } catch(e) {} + _wvTimer.stop(); _wvPaused = true; pauseBtn.innerHTML = ' Resume'; if (_wvRecognition) try { _wvRecognition.stop(); } catch(e) {} } else { - _wvRecorder.mediaRecorder.resume(); _wvTimer.start(); _wvPaused = false; + try { + if (_wvRecorder.mediaRecorder.state === 'paused') { _wvRecorder.mediaRecorder.resume(); } + else if (_wvRecorder.mediaRecorder.state === 'inactive' && _wvRecorder.stream && _wvRecorder.stream.active) { + var mime = MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm'; + _wvRecorder.mediaRecorder = new MediaRecorder(_wvRecorder.stream, { mimeType: mime, audioBitsPerSecond: 32000 }); + _wvRecorder.mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) _wvRecorder.chunks.push(e.data); }; + _wvRecorder.mediaRecorder.start(1000); + } + } catch(e) {} + _wvTimer.resume(); _wvPaused = false; pauseBtn.innerHTML = ' Pause'; if (_wvRecognition) try { _wvRecognition.start(); } catch(e) {} } @@ -904,6 +922,7 @@ if (tag) tag.textContent = (data.model || '').split('/').pop(); if (outCard) { outCard.classList.remove('hidden'); outCard.scrollIntoView({ behavior: 'smooth' }); } showToast('Well visit note generated!', 'success'); + if (typeof suggestBillingCodes === 'function') suggestBillingCodes('wv-note-text', data.note, 'wellvisit', document.getElementById('wv-note-age').value); } else { showToast(data.error || 'Generation failed', 'error'); } diff --git a/public/js/sickVisit.js b/public/js/sickVisit.js index 027f87d..00c2aa5 100644 --- a/public/js/sickVisit.js +++ b/public/js/sickVisit.js @@ -193,11 +193,21 @@ pauseBtn.addEventListener('click', function() { if (!_sickRecording || !_sickRecorder || !_sickRecorder.mediaRecorder) return; if (!_sickPaused) { - _sickRecorder.mediaRecorder.pause(); _sickTimer.stop(); _sickPaused = true; + try { if (_sickRecorder.mediaRecorder.state === 'recording') _sickRecorder.mediaRecorder.pause(); } catch(e) {} + _sickTimer.stop(); _sickPaused = true; pauseBtn.innerHTML = ' Resume'; if (_sickRecognition) try { _sickRecognition.stop(); } catch(e) {} } else { - _sickRecorder.mediaRecorder.resume(); _sickTimer.start(); _sickPaused = false; + try { + if (_sickRecorder.mediaRecorder.state === 'paused') { _sickRecorder.mediaRecorder.resume(); } + else if (_sickRecorder.mediaRecorder.state === 'inactive' && _sickRecorder.stream && _sickRecorder.stream.active) { + var mime = MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm'; + _sickRecorder.mediaRecorder = new MediaRecorder(_sickRecorder.stream, { mimeType: mime, audioBitsPerSecond: 32000 }); + _sickRecorder.mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) _sickRecorder.chunks.push(e.data); }; + _sickRecorder.mediaRecorder.start(1000); + } + } catch(e) {} + _sickTimer.resume(); _sickPaused = false; pauseBtn.innerHTML = ' Pause'; if (_sickRecognition) try { _sickRecognition.start(); } catch(e) {} } @@ -329,6 +339,7 @@ if (tag) tag.textContent = (data.model || '').split('/').pop(); if (outCard) { outCard.classList.remove('hidden'); outCard.scrollIntoView({ behavior: 'smooth' }); } showToast('Sick visit note generated!', 'success'); + if (typeof suggestBillingCodes === 'function') suggestBillingCodes('sick-note-text', data.note, 'sickvisit', document.getElementById('sick-age').value); } else { showToast(data.error || 'Generation failed', 'error'); } diff --git a/public/js/soap.js b/public/js/soap.js index 193c60a..355bc71 100644 --- a/public/js/soap.js +++ b/public/js/soap.js @@ -134,6 +134,7 @@ outputCard.classList.remove('hidden'); outputCard.scrollIntoView({ behavior: 'smooth' }); showToast('SOAP note generated!', 'success'); + if (typeof suggestBillingCodes === 'function') suggestBillingCodes('soap-text', data.soap, 'soap', document.getElementById('soap-age').value); } else showToast(data.error || 'Failed', 'error'); }) .catch(function(err) { hideBusy(); showToast(err.message, 'error'); }); diff --git a/public/js/voiceDictation.js b/public/js/voiceDictation.js index 5d7203d..faa1b53 100644 --- a/public/js/voiceDictation.js +++ b/public/js/voiceDictation.js @@ -104,27 +104,31 @@ pauseBtn.addEventListener('click', function() { if (!isRecording) return; if (!isPaused) { - if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'recording') { - recorder.mediaRecorder.pause(); - timer.stop(); - isPaused = true; - pauseBtn.innerHTML = ' Resume'; - pauseBtn.classList.add('btn-primary'); - pauseBtn.classList.remove('btn-ghost'); - if (recognition) try { recognition.stop(); } catch(e) {} - showToast('Paused', 'info'); - } + try { if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'recording') recorder.mediaRecorder.pause(); } catch(e) {} + timer.stop(); + isPaused = true; + pauseBtn.innerHTML = ' Resume'; + pauseBtn.classList.add('btn-primary'); + pauseBtn.classList.remove('btn-ghost'); + if (recognition) try { recognition.stop(); } catch(e) {} + showToast('Paused', 'info'); } else { - if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'paused') { - recorder.mediaRecorder.resume(); - timer.start(); - isPaused = false; - pauseBtn.innerHTML = ' Pause'; - pauseBtn.classList.remove('btn-primary'); - pauseBtn.classList.add('btn-ghost'); - if (recognition) try { recognition.start(); } catch(e) {} - showToast('Resumed', 'info'); - } + try { + if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'paused') { recorder.mediaRecorder.resume(); } + else if (recorder.mediaRecorder && recorder.mediaRecorder.state === 'inactive' && recorder.stream && recorder.stream.active) { + var mime = MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm'; + recorder.mediaRecorder = new MediaRecorder(recorder.stream, { mimeType: mime, audioBitsPerSecond: 32000 }); + recorder.mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) recorder.chunks.push(e.data); }; + recorder.mediaRecorder.start(1000); + } + } catch(e) {} + timer.resume(); + isPaused = false; + pauseBtn.innerHTML = ' Pause'; + pauseBtn.classList.remove('btn-primary'); + pauseBtn.classList.add('btn-ghost'); + if (recognition) try { recognition.start(); } catch(e) {} + showToast('Resumed', 'info'); } }); } diff --git a/server.js b/server.js index adbfff8..68c8580 100644 --- a/server.js +++ b/server.js @@ -190,6 +190,7 @@ app.use('/api', require('./src/routes/encounters')); app.use('/api', require('./src/routes/memories')); app.use('/api', require('./src/routes/documents')); app.use('/api', require('./src/routes/audioBackups')); +app.use('/api', require('./src/routes/billing')); app.use('/api/sessions', require('./src/routes/sessions')); app.use('/api', require('./src/routes/wellVisit')); app.use('/api', require('./src/routes/sickVisit')); diff --git a/src/routes/billing.js b/src/routes/billing.js new file mode 100644 index 0000000..2f0471d --- /dev/null +++ b/src/routes/billing.js @@ -0,0 +1,365 @@ +// ============================================================ +// BILLING CODE SUGGESTIONS — ICD-10 + CPT from note analysis +// Uses NLM Clinical Tables API for ICD-10 lookup (free, no auth) +// ============================================================ + +var express = require('express'); +var router = express.Router(); +var { authMiddleware } = require('../middleware/auth'); +var logger = require('../utils/logger'); + +// ── CPT E/M Reference Tables ────────────────────────────────────── + +var CPT_EM = { + outpatient_new: [ + { code: '99202', level: 2, desc: 'New patient, straightforward MDM', time: '15-29 min' }, + { code: '99203', level: 3, desc: 'New patient, low complexity MDM', time: '30-44 min' }, + { code: '99204', level: 4, desc: 'New patient, moderate complexity MDM', time: '45-59 min' }, + { code: '99205', level: 5, desc: 'New patient, high complexity MDM', time: '60-74 min' } + ], + outpatient_established: [ + { code: '99211', level: 1, desc: 'Established patient, may not require physician', time: '—' }, + { code: '99212', level: 2, desc: 'Established patient, straightforward MDM', time: '10-19 min' }, + { code: '99213', level: 3, desc: 'Established patient, low complexity MDM', time: '20-29 min' }, + { code: '99214', level: 4, desc: 'Established patient, moderate complexity MDM', time: '30-39 min' }, + { code: '99215', level: 5, desc: 'Established patient, high complexity MDM', time: '40-54 min' } + ], + wellvisit_new: [ + { code: '99381', desc: 'Preventive visit, new patient, infant (< 1 year)' }, + { code: '99382', desc: 'Preventive visit, new patient, early childhood (1-4 years)' }, + { code: '99383', desc: 'Preventive visit, new patient, late childhood (5-11 years)' }, + { code: '99384', desc: 'Preventive visit, new patient, adolescent (12-17 years)' }, + { code: '99385', desc: 'Preventive visit, new patient, 18-39 years' } + ], + wellvisit_established: [ + { code: '99391', desc: 'Preventive visit, established patient, infant (< 1 year)' }, + { code: '99392', desc: 'Preventive visit, established patient, early childhood (1-4 years)' }, + { code: '99393', desc: 'Preventive visit, established patient, late childhood (5-11 years)' }, + { code: '99394', desc: 'Preventive visit, established patient, adolescent (12-17 years)' }, + { code: '99395', desc: 'Preventive visit, established patient, 18-39 years' } + ], + ed: [ + { code: '99281', level: 1, desc: 'ED visit, straightforward MDM' }, + { code: '99282', level: 2, desc: 'ED visit, low complexity MDM' }, + { code: '99283', level: 3, desc: 'ED visit, moderate complexity MDM' }, + { code: '99284', level: 4, desc: 'ED visit, moderate-high complexity MDM' }, + { code: '99285', level: 5, desc: 'ED visit, high complexity MDM' } + ], + inpatient_admit: [ + { code: '99221', level: 1, desc: 'Initial hospital care, straightforward/low MDM' }, + { code: '99222', level: 2, desc: 'Initial hospital care, moderate MDM' }, + { code: '99223', level: 3, desc: 'Initial hospital care, high MDM' } + ], + inpatient_subsequent: [ + { code: '99231', level: 1, desc: 'Subsequent hospital care, straightforward/low MDM' }, + { code: '99232', level: 2, desc: 'Subsequent hospital care, moderate MDM' }, + { code: '99233', level: 3, desc: 'Subsequent hospital care, high MDM' } + ], + inpatient_discharge: [ + { code: '99238', desc: 'Hospital discharge, 30 min or less' }, + { code: '99239', desc: 'Hospital discharge, more than 30 min' } + ] +}; + +// ── ROS Systems for counting ────────────────────────────────────── +var ROS_SYSTEMS = [ + 'constitutional', 'eyes', 'ent', 'cardiovascular', 'respiratory', + 'gastrointestinal', 'genitourinary', 'musculoskeletal', 'integumentary', + 'neurological', 'psychiatric', 'endocrine', 'hematologic', 'allergic' +]; + +var PE_SYSTEMS = [ + 'general', 'heent', 'eyes', 'ears', 'nose', 'throat', 'neck', + 'cardiovascular', 'respiratory', 'chest', 'lungs', 'abdomen', 'abdominal', + 'genitourinary', 'musculoskeletal', 'skin', 'integumentary', + 'neurologic', 'neurological', 'psychiatric', 'lymphatic' +]; + +// ── Extract diagnoses from note text ───────────────────────────── + +// Common pediatric diagnoses — avoids NLM lookup for known terms +var COMMON_ICD10 = { + 'fever': { code: 'R50.9', name: 'Fever, unspecified' }, + 'cough': { code: 'R05.9', name: 'Cough, unspecified' }, + 'vomiting': { code: 'R11.10', name: 'Vomiting, unspecified' }, + 'diarrhea': { code: 'R19.7', name: 'Diarrhea, unspecified' }, + 'constipation': { code: 'K59.00', name: 'Constipation, unspecified' }, + 'headache': { code: 'R51.9', name: 'Headache, unspecified' }, + 'abdominal pain': { code: 'R10.9', name: 'Unspecified abdominal pain' }, + 'rash': { code: 'R21', name: 'Rash and other nonspecific skin eruption' }, + 'sore throat': { code: 'J02.9', name: 'Acute pharyngitis, unspecified' }, + 'pharyngitis': { code: 'J02.9', name: 'Acute pharyngitis, unspecified' }, + 'strep pharyngitis': { code: 'J02.0', name: 'Streptococcal pharyngitis' }, + 'otitis media': { code: 'H66.90', name: 'Otitis media, unspecified' }, + 'acute otitis media': { code: 'H66.90', name: 'Otitis media, unspecified' }, + 'uri': { code: 'J06.9', name: 'Acute upper respiratory infection, unspecified' }, + 'upper respiratory infection': { code: 'J06.9', name: 'Acute upper respiratory infection, unspecified' }, + 'bronchiolitis': { code: 'J21.9', name: 'Acute bronchiolitis, unspecified' }, + 'asthma': { code: 'J45.20', name: 'Mild intermittent asthma, uncomplicated' }, + 'asthma exacerbation': { code: 'J45.21', name: 'Mild intermittent asthma with acute exacerbation' }, + 'pneumonia': { code: 'J18.9', name: 'Pneumonia, unspecified organism' }, + 'croup': { code: 'J05.0', name: 'Acute obstructive laryngitis' }, + 'bronchitis': { code: 'J20.9', name: 'Acute bronchitis, unspecified' }, + 'eczema': { code: 'L30.9', name: 'Dermatitis, unspecified' }, + 'atopic dermatitis': { code: 'L20.9', name: 'Atopic dermatitis, unspecified' }, + 'urticaria': { code: 'L50.9', name: 'Urticaria, unspecified' }, + 'conjunctivitis': { code: 'H10.9', name: 'Unspecified conjunctivitis' }, + 'urinary tract infection': { code: 'N39.0', name: 'Urinary tract infection, site not specified' }, + 'uti': { code: 'N39.0', name: 'Urinary tract infection, site not specified' }, + 'gastroenteritis': { code: 'K52.9', name: 'Noninfective gastroenteritis and colitis, unspecified' }, + 'dehydration': { code: 'E86.0', name: 'Dehydration' }, + 'seizure': { code: 'R56.9', name: 'Unspecified convulsions' }, + 'febrile seizure': { code: 'R56.00', name: 'Simple febrile convulsions' }, + 'anemia': { code: 'D64.9', name: 'Anemia, unspecified' }, + 'iron deficiency anemia': { code: 'D50.9', name: 'Iron deficiency anemia, unspecified' }, + 'obesity': { code: 'E66.01', name: 'Morbid (severe) obesity due to excess calories' }, + 'failure to thrive': { code: 'R62.51', name: 'Failure to thrive (child)' }, + 'adhd': { code: 'F90.9', name: 'Attention-deficit hyperactivity disorder, unspecified type' }, + 'anxiety': { code: 'F41.9', name: 'Anxiety disorder, unspecified' }, + 'depression': { code: 'F32.9', name: 'Major depressive disorder, single episode, unspecified' }, + 'well child': { code: 'Z00.129', name: 'Encounter for routine child health examination without abnormal findings' }, + 'well child visit': { code: 'Z00.129', name: 'Encounter for routine child health examination without abnormal findings' }, + 'newborn': { code: 'Z00.110', name: 'Health examination for newborn under 8 days old' }, + 'jaundice': { code: 'P59.9', name: 'Neonatal jaundice, unspecified' }, + 'neonatal jaundice': { code: 'P59.9', name: 'Neonatal jaundice, unspecified' }, + 'hyperbilirubinemia': { code: 'P59.9', name: 'Neonatal jaundice, unspecified' } +}; + +function extractDiagnoses(noteText) { + var diagnoses = []; + + // Look for Assessment section + var assessmentMatch = noteText.match(/(?:assessment|diagnos[ie]s|impression|a\/p|assessment\s*(?:and|&)\s*plan)[:\s]*\n?([\s\S]*?)(?:\n\s*(?:plan|disposition|follow.up|return|recommendations)[:\s]|\n\s*\n\s*\n|$)/i); + var assessmentText = assessmentMatch ? assessmentMatch[1] : noteText; + + // Extract ICD-10 codes already in the text (e.g., "J06.9" or "(J06.9)") + var icdPattern = /\b([A-TV-Z]\d{2}(?:\.\d{1,4})?)\b/g; + var icdMatch; + while ((icdMatch = icdPattern.exec(noteText)) !== null) { + diagnoses.push({ term: icdMatch[1], type: 'icd_extracted' }); + } + + // Extract numbered diagnoses from assessment + var numberedLines = assessmentText.match(/^\s*\d+[\.\)]\s*(.+)$/gm); + if (numberedLines) { + numberedLines.forEach(function(line) { + var term = line.replace(/^\s*\d+[\.\)]\s*/, '').replace(/\s*[\(\[].*$/, '').trim(); + if (term.length > 3 && term.length < 100) { + diagnoses.push({ term: term, type: 'numbered' }); + } + }); + } + + // Extract dash/bullet diagnoses + var bulletLines = assessmentText.match(/^\s*[-•]\s*(.+)$/gm); + if (bulletLines) { + bulletLines.forEach(function(line) { + var term = line.replace(/^\s*[-•]\s*/, '').replace(/\s*[\(\[].*$/, '').trim(); + if (term.length > 3 && term.length < 100) { + diagnoses.push({ term: term, type: 'bullet' }); + } + }); + } + + // If no structured diagnoses found, try to extract from inline text + if (diagnoses.length === 0) { + var commonPatterns = [ + /(?:diagnosed? with|assessment of|consistent with|suggestive of|likely|probable)\s+([^,\.\n]{3,60})/gi + ]; + commonPatterns.forEach(function(pattern) { + var m; + while ((m = pattern.exec(assessmentText)) !== null) { + diagnoses.push({ term: m[1].trim(), type: 'inline' }); + } + }); + } + + // Deduplicate + var seen = {}; + return diagnoses.filter(function(d) { + var key = d.term.toLowerCase(); + if (seen[key]) return false; + seen[key] = true; + return true; + }); +} + +// ── Count ROS and PE systems documented ────────────────────────── + +function countDocumentedSystems(noteText) { + var lower = noteText.toLowerCase(); + var rosCount = 0; + var peCount = 0; + + ROS_SYSTEMS.forEach(function(sys) { + if (lower.indexOf(sys) !== -1) rosCount++; + }); + // Also check common abbreviations + if (/\bENT\b/.test(noteText)) rosCount++; + if (/\bGI\b/.test(noteText)) rosCount++; + if (/\bGU\b/.test(noteText)) rosCount++; + if (/\bMSK\b/.test(noteText)) rosCount++; + + PE_SYSTEMS.forEach(function(sys) { + if (lower.indexOf(sys) !== -1) peCount++; + }); + + return { rosCount: Math.min(rosCount, 14), peCount: Math.min(peCount, 12) }; +} + +// ── Estimate E/M complexity level ──────────────────────────────── + +function estimateEMLevel(noteText, diagnosisCount) { + var systems = countDocumentedSystems(noteText); + var noteLength = noteText.length; + + // MDM complexity estimation (simplified 2021 E/M guidelines) + // Based on: number of diagnoses, data reviewed, risk + var mdmLevel = 2; // default straightforward + + if (diagnosisCount >= 4 || noteLength > 3000) mdmLevel = 4; + else if (diagnosisCount >= 2 || noteLength > 1500) mdmLevel = 3; + + // Check for high-risk indicators + var highRisk = /(?:admit|hospitali[sz]|intubat|seizure|sepsis|meningitis|fracture|surgery|ICU|PICU|NICU|emergent|critical|unstable)/i.test(noteText); + if (highRisk) mdmLevel = Math.max(mdmLevel, 4); + + var moderateRisk = /(?:dehydrat|IV fluid|antibiotic|x-ray|CT scan|MRI|ultrasound|lab|CBC|CMP|urinalysis|blood culture|lumbar puncture)/i.test(noteText); + if (moderateRisk) mdmLevel = Math.max(mdmLevel, 3); + + return { + level: Math.min(mdmLevel, 5), + rosCount: systems.rosCount, + peCount: systems.peCount, + diagnosisCount: diagnosisCount, + complexity: mdmLevel >= 4 ? 'high' : mdmLevel >= 3 ? 'moderate' : 'low' + }; +} + +// ── Get age category for well visit CPT ────────────────────────── + +function getWellVisitCPT(patientAge) { + var ageStr = (patientAge || '').toLowerCase(); + var ageYears = 0; + var monthMatch = ageStr.match(/(\d+)\s*(?:month|mo)/); + var yearMatch = ageStr.match(/(\d+)\s*(?:year|yr|y\b)/); + var dayMatch = ageStr.match(/(\d+)\s*(?:day|d\b)/); + var weekMatch = ageStr.match(/(\d+)\s*(?:week|wk)/); + + if (yearMatch) ageYears = parseInt(yearMatch[1]); + else if (monthMatch) ageYears = parseInt(monthMatch[1]) / 12; + else if (weekMatch) ageYears = parseInt(weekMatch[1]) / 52; + else if (dayMatch) ageYears = parseInt(dayMatch[1]) / 365; + + // Established patient codes (most common) + if (ageYears < 1) return CPT_EM.wellvisit_established[0]; + if (ageYears < 5) return CPT_EM.wellvisit_established[1]; + if (ageYears < 12) return CPT_EM.wellvisit_established[2]; + if (ageYears < 18) return CPT_EM.wellvisit_established[3]; + return CPT_EM.wellvisit_established[4]; +} + +// ── NLM ICD-10 lookup ──────────────────────────────────────────── + +async function lookupICD10(term) { + try { + // Use maxList=1 for short/generic terms, 2 for longer specific terms + var maxList = term.split(/\s+/).length >= 3 ? 2 : 1; + var url = 'https://clinicaltables.nlm.nih.gov/api/icd10cm/v3/search?sf=code,name&terms=' + encodeURIComponent(term) + '&maxList=' + maxList; + var resp = await fetch(url, { signal: AbortSignal.timeout(5000) }); + if (!resp.ok) return []; + var data = await resp.json(); + // NLM response format: [totalCount, codeArray, extraDataArray, displayArray] + if (!data || !data[1] || !data[3]) return []; + return data[3].map(function(item) { + return { code: item[0], name: item[1] }; + }); + } catch (e) { + return []; + } +} + +// ── Main endpoint ──────────────────────────────────────────────── + +router.post('/suggest-codes', authMiddleware, async function(req, res) { + try { + var { noteText, noteType, patientAge, visitType } = req.body; + if (!noteText) return res.status(400).json({ error: 'No note text provided' }); + + // 1. Extract diagnoses from note text + var diagnoses = extractDiagnoses(noteText); + + // 2. Look up ICD-10 codes via NLM for each diagnosis + var icd10Results = []; + var seen = {}; + + // First add any ICD-10 codes already extracted from the text + diagnoses.filter(function(d) { return d.type === 'icd_extracted'; }).forEach(function(d) { + if (!seen[d.term]) { icd10Results.push({ code: d.term, name: '', source: 'extracted' }); seen[d.term] = true; } + }); + + // Then look up non-ICD terms — check local common map first, then NLM + var lookupTerms = diagnoses.filter(function(d) { return d.type !== 'icd_extracted'; }).slice(0, 8); + for (var i = 0; i < lookupTerms.length; i++) { + var termLower = lookupTerms[i].term.toLowerCase().trim(); + var localMatch = COMMON_ICD10[termLower]; + if (localMatch && !seen[localMatch.code]) { + icd10Results.push({ code: localMatch.code, name: localMatch.name, source: 'local' }); + seen[localMatch.code] = true; + } else if (!localMatch) { + var results = await lookupICD10(lookupTerms[i].term); + results.forEach(function(r) { + if (!seen[r.code]) { icd10Results.push({ code: r.code, name: r.name, source: 'nlm' }); seen[r.code] = true; } + }); + } + } + + // 3. Suggest CPT codes based on note type and complexity + var cptResults = []; + var emLevel = estimateEMLevel(noteText, diagnoses.length); + + if (noteType === 'wellvisit') { + var wvCode = getWellVisitCPT(patientAge); + if (wvCode) cptResults.push(wvCode); + // Well visits may also have a problem-oriented code if issues found + if (diagnoses.length > 1) { + cptResults.push({ code: '99213', desc: 'May also bill problem-oriented visit if significant issue addressed', note: 'modifier -25' }); + } + } else if (noteType === 'hospital' || visitType === 'inpatient') { + var isAdmission = /(?:admit|admission|initial hospital|H&P)/i.test(noteText); + var isDischarge = /(?:discharge|d\/c summary)/i.test(noteText); + if (isDischarge) { + cptResults.push(CPT_EM.inpatient_discharge[noteText.length > 2000 ? 1 : 0]); + } else if (isAdmission) { + var admitIdx = Math.min(emLevel.level - 2, 2); + if (admitIdx >= 0) cptResults.push(CPT_EM.inpatient_admit[admitIdx]); + } else { + var subIdx = Math.min(emLevel.level - 2, 2); + if (subIdx >= 0) cptResults.push(CPT_EM.inpatient_subsequent[subIdx]); + } + } else if (visitType === 'ed') { + var edIdx = Math.min(emLevel.level - 1, 4); + cptResults.push(CPT_EM.ed[edIdx]); + } else { + // Outpatient — determine new vs established + var isNew = /\bnew patient\b/i.test(noteText); + var table = isNew ? CPT_EM.outpatient_new : CPT_EM.outpatient_established; + var idx = Math.min(emLevel.level - 1, table.length - 1); + cptResults.push(table[idx]); + } + + logger.audit(req.user.id, 'suggest_billing_codes', 'Suggested ' + icd10Results.length + ' ICD-10 + ' + cptResults.length + ' CPT codes', req, { category: 'clinical' }); + + res.json({ + success: true, + icd10: icd10Results.slice(0, 10), + cpt: cptResults, + emLevel: emLevel + }); + } catch (err) { + console.error('[Billing] Error:', err.message); + res.status(500).json({ error: 'Code suggestion failed' }); + } +}); + +module.exports = router;