From 36f34b161e853c6dddcc18e02eb6414adfa051cf Mon Sep 17 00:00:00 2001 From: Gerrit Cloete Date: Thu, 2 Jan 2025 09:50:36 +0200 Subject: [PATCH] Add: initialize project with package.json, .gitignore, and deployment workflow; implement scripts for indexing and converting questions --- .github/workflows/deploy.yml | 53 + .gitignore | 1 + package-lock.json | 1172 +++++++++++++++++ package.json | 18 + public/index.html | 94 ++ public/questionIndex.json | 74 ++ .../cardiology/arrhythmias/afib.html | 68 + .../cardiology/emergencies/tamponade.html | 78 ++ .../critical-care/mods/fulminant-case.html | 145 ++ .../sepsis/vasopressor-choice.html | 110 ++ .../endocrinology/adrenal/crisis.html | 120 ++ .../endocrinology/thyroid/thyroid-storm.html | 115 ++ .../hematology/ttp/acute-management.html | 137 ++ .../acid-base/complex-disorders.html | 120 ++ .../acid-base/metabolic-alkalosis.html | 104 ++ scripts/convertMarkdown.js | 69 + scripts/indexQuestions.js | 45 + 17 files changed, 2523 insertions(+) create mode 100644 .github/workflows/deploy.yml create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/index.html create mode 100644 public/questionIndex.json create mode 100644 public/questions/cardiology/arrhythmias/afib.html create mode 100644 public/questions/cardiology/emergencies/tamponade.html create mode 100644 public/questions/critical-care/mods/fulminant-case.html create mode 100644 public/questions/critical-care/sepsis/vasopressor-choice.html create mode 100644 public/questions/endocrinology/adrenal/crisis.html create mode 100644 public/questions/endocrinology/thyroid/thyroid-storm.html create mode 100644 public/questions/hematology/ttp/acute-management.html create mode 100644 public/questions/nephrology/acid-base/complex-disorders.html create mode 100644 public/questions/nephrology/acid-base/metabolic-alkalosis.html create mode 100644 scripts/convertMarkdown.js create mode 100644 scripts/indexQuestions.js diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..1c4d3f6 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,53 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: ["master"] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Build + run: npm run build + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: ./public + + deploy: + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: production + url: ${{ github.server_url }}/${{ github.repository }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v3 + env: + GITHUB_TOKEN: ${{ github.token }} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..077d185 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1172 @@ +{ + "name": "internal-med-questions", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "internal-med-questions", + "version": "1.0.0", + "dependencies": { + "gray-matter": "^4.0.3", + "http-server": "^14.1.1", + "marked": "^15.0.4", + "rimraf": "^6.0.1" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "license": "MIT", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/marked": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.4.tgz", + "integrity": "sha512-TCHvDqmb3ZJ4PWG7VEGVgtefA5/euFmsIhxtD0XsBxI39gUSKL81mIRFdt0AiNQozUahd4ke98ZdirExd/vSEw==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "license": "MIT", + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/qs": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..39b6b16 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "internal-med-questions", + "version": "1.0.0", + "description": "Internal Medicine Question Bank", + "scripts": { + "clean": "rimraf \"./public/questions\"", + "index": "node scripts/indexQuestions.js", + "convert": "node -e \"require('./scripts/convertMarkdown')('./questions', './public/questions')\"", + "build": "npm run clean && npm run convert && npm run index", + "serve": "npm run build && http-server public" + }, + "dependencies": { + "gray-matter": "^4.0.3", + "http-server": "^14.1.1", + "marked": "^4.0.12", + "rimraf": "^3.0.2" + } +} diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..178ead2 --- /dev/null +++ b/public/index.html @@ -0,0 +1,94 @@ + + + + + + Internal Medicine Questions + + + +
+
+ + + + + +
+
+
+ + + + diff --git a/public/questionIndex.json b/public/questionIndex.json new file mode 100644 index 0000000..2fb0634 --- /dev/null +++ b/public/questionIndex.json @@ -0,0 +1,74 @@ +[ + { + "filepath": "questions/cardiology/arrhythmias/afib.html", + "specialty": "cardiology", + "topic": "arrhythmias", + "difficulty": "medium", + "id": "CARD001", + "title": "---\r" + }, + { + "filepath": "questions/cardiology/emergencies/tamponade.html", + "specialty": "cardiology", + "topic": "emergencies", + "difficulty": "hard", + "id": "CARD002", + "title": "---\r" + }, + { + "filepath": "questions/critical-care/mods/fulminant-case.html", + "specialty": "critical-care", + "topic": "MODS", + "difficulty": "ultra-hard", + "id": "CRIT002", + "title": "---\r" + }, + { + "filepath": "questions/critical-care/sepsis/vasopressor-choice.html", + "specialty": "critical-care", + "topic": "sepsis", + "difficulty": "hard", + "id": "CRIT001", + "title": "---\r" + }, + { + "filepath": "questions/endocrinology/adrenal/crisis.html", + "specialty": "endocrinology", + "topic": "adrenal", + "difficulty": "hard", + "id": "ENDO002", + "title": "---\r" + }, + { + "filepath": "questions/endocrinology/thyroid/thyroid-storm.html", + "specialty": "endocrinology", + "topic": "thyroid", + "difficulty": "hard", + "id": "ENDO001", + "title": "---\r" + }, + { + "filepath": "questions/hematology/ttp/acute-management.html", + "specialty": "hematology", + "topic": "TTP", + "difficulty": "ultra-hard", + "id": "HEME001", + "title": "---\r" + }, + { + "filepath": "questions/nephrology/acid-base/complex-disorders.html", + "specialty": "nephrology", + "topic": "acid-base", + "difficulty": "hard", + "id": "NEPH001", + "title": "---\r" + }, + { + "filepath": "questions/nephrology/acid-base/metabolic-alkalosis.html", + "specialty": "nephrology", + "topic": "acid-base", + "difficulty": "hard", + "id": "NEPH002", + "title": "---\r" + } +] \ No newline at end of file diff --git a/public/questions/cardiology/arrhythmias/afib.html b/public/questions/cardiology/arrhythmias/afib.html new file mode 100644 index 0000000..ce67c79 --- /dev/null +++ b/public/questions/cardiology/arrhythmias/afib.html @@ -0,0 +1,68 @@ + + + + + + + arrhythmias + + + +

Atrial Fibrillation Management

+

Question

+

A 72-year-old woman with newly diagnosed atrial fibrillation has a CHA₂DS₂-VASc score of 4. She has normal renal function and no history of bleeding. Which is the most appropriate anticoagulation strategy?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)No anticoagulation needed
B)Aspirin 81mg daily
C)Warfarin with target INR 2-3
D)Direct oral anticoagulant (DOAC)
+
+View Answer + +

Correct Answer

+

D

+

Explanation

+ +

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/cardiology/emergencies/tamponade.html b/public/questions/cardiology/emergencies/tamponade.html new file mode 100644 index 0000000..719333d --- /dev/null +++ b/public/questions/cardiology/emergencies/tamponade.html @@ -0,0 +1,78 @@ + + + + + + + emergencies + + + +

Cardiac Tamponade Management

+

Question

+

A 45-year-old man with metastatic lung cancer presents with acute dyspnea, hypotension (BP 82/60), and tachycardia (HR 125). Bedside echo shows a large pericardial effusion with right ventricular diastolic collapse. Despite 2L of IV fluids, his condition worsens with:

+ +

Which combination of immediate management steps is most appropriate?

+

Options

+

A) Immediate pericardiocentesis + supplemental O2 + call cardiology +B) Start dobutamine + IV fluids + prepare for OR +C) Pericardial window in OR + mechanical ventilation +D) Supplemental O2 + empiric antibiotics + CT chest +E) Start norepinephrine + mechanical ventilation + cardiology consult

+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This is a case of life-threatening cardiac tamponade requiring immediate intervention:

+
    +
  1. Key diagnostic findings:

    +
      +
    • Beck's triad: hypotension, JVD, muffled heart sounds
    • +
    • Pulsus paradoxus >10 mmHg (here 25 mmHg)
    • +
    • Echo showing RV diastolic collapse
    • +
    • Known malignancy (common cause)
    • +
    +
  2. +
  3. Critical management principles:

    +
      +
    • Emergent pericardiocentesis is indicated due to:
        +
      • Hemodynamic compromise
      • +
      • Altered mental status
      • +
      • Failed fluid challenge
      • +
      +
    • +
    • Delay for OR or imaging could be fatal
    • +
    • Inotropes/pressors won't address underlying problem
    • +
    • Mechanical ventilation could worsen cardiac output
    • +
    +
  4. +
  5. Common pitfalls:

    +
      +
    • Waiting for CT imaging
    • +
    • Prioritizing mechanical ventilation
    • +
    • Over-reliance on medical management
    • +
    +
  6. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/critical-care/mods/fulminant-case.html b/public/questions/critical-care/mods/fulminant-case.html new file mode 100644 index 0000000..b35a3e6 --- /dev/null +++ b/public/questions/critical-care/mods/fulminant-case.html @@ -0,0 +1,145 @@ + + + + + + + MODS + + + +

Complex Multi-Organ Dysfunction Management

+

Question

+

A 38-year-old previously healthy woman presents with toxic shock syndrome. Current status:

+

Respiratory:

+ +

Cardiovascular:

+ +

Renal/Metabolic:

+ +

Hematologic:

+ +

Hepatic:

+ +

Which combination of immediate interventions will most likely improve survival?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)Prone positioning + vasopressin + CRRT + plasma exchange + stress-dose steroids
B)VV-ECMO + inotropes + hemodialysis + FFP/platelets + NAC infusion
C)Recruitment maneuver + epinephrine + CVVH + activated protein C + IVIG
D)High-frequency oscillation + dobutamine + peritoneal dialysis + antithrombin III
E)Airway pressure release + terlipressin + diuretics + factor VIIa + albumin
+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This ultra-complex case requires careful consideration of multiple organ systems:

+
    +
  1. Respiratory Management:

    +
      +
    • Severe ARDS (P/F < 100) requires prone positioning
    • +
    • High plateau pressure contraindicates recruitment
    • +
    • ECMO criteria met but higher mortality with shock
    • +
    +
  2. +
  3. Circulatory Support:

    +
      +
    • Vasopressin indicated for norepinephrine >0.5 µg/kg/min
    • +
    • Inotropes may worsen shock-induced cardiomyopathy
    • +
    • Low ScvO2 reflects poor oxygen delivery
    • +
    +
  4. +
  5. Renal/Metabolic:

    +
      +
    • CRRT preferred due to:
        +
      • Hemodynamic instability
      • +
      • Hyperkalemia
      • +
      • Severe acidosis
      • +
      • Volume management needs
      • +
      +
    • +
    +
  6. +
  7. Hematologic/Inflammatory:

    +
      +
    • DIC requires supportive care
    • +
    • Plasma exchange beneficial in toxic shock
    • +
    • Factor VIIa contraindicated in DIC
    • +
    • Activated protein C withdrawn from market
    • +
    +
  8. +
  9. Evidence-Based Rationale:

    +
      +
    • Prone positioning: 16% absolute mortality reduction in severe ARDS
    • +
    • Vasopressin: Reduces norepinephrine requirements
    • +
    • CRRT: Better hemodynamic tolerance than intermittent
    • +
    • Plasma exchange: Removes inflammatory mediators
    • +
    • Steroids: Indicated in refractory shock
    • +
    +
  10. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/critical-care/sepsis/vasopressor-choice.html b/public/questions/critical-care/sepsis/vasopressor-choice.html new file mode 100644 index 0000000..7491773 --- /dev/null +++ b/public/questions/critical-care/sepsis/vasopressor-choice.html @@ -0,0 +1,110 @@ + + + + + + + sepsis + + + +

Vasopressor Selection in Septic Shock

+

Question

+

A 68-year-old man with pneumonia presents with septic shock. After receiving 30 mL/kg IV crystalloids:

+

Vitals/Labs:

+ +

Which combination of interventions is most appropriate at this time?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)Start norepinephrine + continue fluid resuscitation
B)Start vasopressin as first-line + inotrope
C)Start epinephrine alone + hold fluids
D)Start phenylephrine + stress-dose steroids
E)Start dopamine + diuretics
+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This is a classic warm septic shock case requiring specific interventions:

+
    +
  1. Hemodynamic Analysis:

    +
      +
    • Hyperdynamic state (high CI)
    • +
    • Vasodilatory shock (low SVR)
    • +
    • Tissue hypoperfusion (high lactate, low ScvO2)
    • +
    • Adequate preload (CVP 12)
    • +
    +
  2. +
  3. Management Rationale:

    +
      +
    • Norepinephrine is first-line because:
        +
      • Increases SVR with minimal chronotropy
      • +
      • Maintains splanchnic perfusion
      • +
      • Better survival vs dopamine
      • +
      +
    • +
    • Continued fluids needed for:
        +
      • Ongoing losses
      • +
      • Persistent hypoperfusion
      • +
      +
    • +
    +
  4. +
  5. Why other options are wrong:

    +
      +
    • Vasopressin: Second-line agent
    • +
    • Epinephrine: May worsen tachycardia/lactate
    • +
    • Phenylephrine: Poor splanchnic flow
    • +
    • Dopamine: Higher arrhythmia risk
    • +
    +
  6. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/endocrinology/adrenal/crisis.html b/public/questions/endocrinology/adrenal/crisis.html new file mode 100644 index 0000000..5e9d79a --- /dev/null +++ b/public/questions/endocrinology/adrenal/crisis.html @@ -0,0 +1,120 @@ + + + + + + + adrenal + + + +

Adrenal Crisis Management

+

Question

+

A 45-year-old woman with known Addison's disease presents to ED with:

+ +

Labs show:

+ +

She hasn't taken her usual hydrocortisone for 2 days due to vomiting. What is the most appropriate immediate management?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)IV hydrocortisone 100mg + NS bolus + D5W + broad-spectrum antibiotics
B)IM hydrocortisone 50mg + oral rehydration + antiemetics
C)IV dexamethasone 4mg + albumin + vasopressors
D)Oral prednisone 60mg + potassium-sparing diuretics
E)IV methylprednisolone 125mg + NS maintenance + insulin
+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This is an acute adrenal crisis requiring immediate intervention:

+
    +
  1. Key diagnostic features:

    +
      +
    • Known Addison's disease
    • +
    • Precipitating illness (likely gastroenteritis)
    • +
    • Classic presentation:
        +
      • Hypotension
      • +
      • Hyponatremia
      • +
      • Hyperkalemia
      • +
      • Hypoglycemia
      • +
      • Fever
      • +
      +
    • +
    +
  2. +
  3. Management priorities:

    +
      +
    • Immediate glucocorticoid replacement
        +
      • Hydrocortisone preferred (mineralocorticoid activity)
      • +
      • High dose needed (100mg IV)
      • +
      +
    • +
    • Aggressive fluid resuscitation
        +
      • Normal saline corrects volume/sodium
      • +
      +
    • +
    • Glucose replacement
    • +
    • Empiric antibiotics (rule out sepsis)
    • +
    +
  4. +
  5. Why other options are wrong:

    +
      +
    • IM route insufficient in shock
    • +
    • Dexamethasone lacks mineralocorticoid effect
    • +
    • Oral therapy inappropriate (vomiting)
    • +
    • Methylprednisolone not first-line
    • +
    +
  6. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/endocrinology/thyroid/thyroid-storm.html b/public/questions/endocrinology/thyroid/thyroid-storm.html new file mode 100644 index 0000000..5543a08 --- /dev/null +++ b/public/questions/endocrinology/thyroid/thyroid-storm.html @@ -0,0 +1,115 @@ + + + + + + + thyroid + + + +

Thyroid Storm Management

+

Question

+

A 32-year-old woman with known Graves' disease presents to the ED with:

+ +

Labs:

+ +

Which combination of immediate treatments is most appropriate?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)PTU + propranolol + hydrocortisone + cooling measures
B)Methimazole + metoprolol + radioactive iodine
C)Lugol's solution + aspirin + propranolol
D)PTU + diltiazem + prednisone
E)Total thyroidectomy + beta blockade
+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This is a case of thyroid storm requiring prompt intervention:

+
    +
  1. Diagnostic Criteria (Burch-Wartofsky Score >45):

    +
      +
    • High fever: 39.8°C (15 points)
    • +
    • Severe tachycardia >140 (25 points)
    • +
    • Agitation/delirium (20 points)
    • +
    • GI-hepatic dysfunction absent (0 points)
    • +
    • Total score ~60 points
    • +
    +
  2. +
  3. Management principles:

    +
      +
    • Block hormone synthesis (PTU preferred over methimazole)
        +
      • PTU also blocks T4→T3 conversion
      • +
      +
    • +
    • Block sympathetic effects (propranolol)
        +
      • Non-selective β-blockade needed
      • +
      +
    • +
    • Block hormone release (iodine solution after PTU)
    • +
    • Support adrenals (hydrocortisone)
    • +
    • Treat precipitant
    • +
    • Supportive care/cooling
    • +
    +
  4. +
  5. Why other options are wrong:

    +
      +
    • RAI contraindicated in thyroid storm
    • +
    • Calcium channel blockers less effective
    • +
    • Surgery too risky in acute phase
    • +
    • Aspirin may increase free T4
    • +
    +
  6. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/hematology/ttp/acute-management.html b/public/questions/hematology/ttp/acute-management.html new file mode 100644 index 0000000..85c7348 --- /dev/null +++ b/public/questions/hematology/ttp/acute-management.html @@ -0,0 +1,137 @@ + + + + + + + TTP + + + +

Complex TTP Management with Neurological Deterioration

+

Question

+

A 35-year-old woman presents with:

+ +

After starting plasma exchange, she develops:

+ +

Which management strategy offers the best survival benefit?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)Double-volume plasmapheresis + rituximab + steroids + ECMO + continue anticoagulation
B)Single-volume plasmapheresis + caplacizumab + hold anticoagulation
C)Switch to hemodialysis + IVIG + platelet transfusion
D)Fresh frozen plasma infusion + cyclophosphamide + IVC filter
E)Therapeutic plasma exchange + splenectomy + antiepileptics
+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This is a catastrophic TTP case with multiple life-threatening complications:

+
    +
  1. Disease Severity Assessment:

    +
      +
    • Severe thrombocytopenia with end-organ damage
    • +
    • Neurological deterioration
    • +
    • Cardiac involvement
    • +
    • Respiratory failure
    • +
    • DIC complication
    • +
    • Thrombotic complications
    • +
    +
  2. +
  3. Management Rationale:

    +
      +
    • Double-volume plasmapheresis:
        +
      • More rapid ADAMTS13 replacement
      • +
      • Better clearance of autoantibodies
      • +
      • Indicated in neurological deterioration
      • +
      +
    • +
    • Rituximab:
        +
      • Early administration improves outcomes
      • +
      • Reduces relapse risk
      • +
      • Addresses autoimmune component
      • +
      +
    • +
    • ECMO support:
        +
      • Manages cardiogenic shock
      • +
      • Provides respiratory support
      • +
      • Allows time for treatment response
      • +
      +
    • +
    +
  4. +
  5. Critical Considerations:

    +
      +
    • Anticoagulation must continue despite bleeding risk:
        +
      • Catastrophic microthrombi formation
      • +
      • Central line maintenance
      • +
      • DVT presence
      • +
      +
    • +
    • Platelet transfusion contraindicated unless life-threatening bleeding
    • +
    • IVC filter contraindicated (increases thrombosis risk)
    • +
    • Splenectomy outdated, high mortality risk
    • +
    +
  6. +
  7. Expected Outcomes:

    +
      +
    • Mortality >90% without aggressive intervention
    • +
    • ~70% survival with optimal management
    • +
    • Neurological recovery possible with prompt treatment
    • +
    +
  8. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/nephrology/acid-base/complex-disorders.html b/public/questions/nephrology/acid-base/complex-disorders.html new file mode 100644 index 0000000..dfea72d --- /dev/null +++ b/public/questions/nephrology/acid-base/complex-disorders.html @@ -0,0 +1,120 @@ + + + + + + + acid-base + + + +

Complex Acid-Base Disorder Analysis

+

Question

+

A 62-year-old diabetic presents with severe diarrhea, DKA, and acute kidney injury. Labs show:

+ +

Which combination of acid-base disorders best explains these findings?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)Metabolic acidosis (high AG) + Respiratory acidosis
B)Metabolic acidosis (high AG) + Metabolic acidosis (normal AG)
C)Metabolic acidosis (high AG) + Respiratory alkalosis
D)Triple disorder: Metabolic acidosis (high AG) + Metabolic acidosis (normal AG) + Respiratory alkalosis
E)Metabolic acidosis (high AG) + Metabolic alkalosis
+
+View Answer + +

Correct Answer

+

D

+

Explanation

+

This is a complex triple disorder:

+
    +
  1. Primary disorders identification:

    +
      +
    • High anion gap metabolic acidosis (DKA)
        +
      • Elevated AG = 20
      • +
      • Ketoacidosis from DKA
      • +
      +
    • +
    • Normal anion gap metabolic acidosis
        +
      • GI bicarbonate loss from diarrhea
      • +
      • Delta ratio 0.8 suggests mixed metabolic acidosis
      • +
      +
    • +
    • Respiratory alkalosis
        +
      • Expected pCO2 = (1.5 × HCO3) + 8 ± 2
      • +
      • Expected = 21.5 mmHg
      • +
      • Actual = 24 mmHg
      • +
      • Relative respiratory alkalosis present
      • +
      +
    • +
    +
  2. +
  3. Supporting evidence:

    +
      +
    • Delta gap = 2.0 confirms additional non-AG acidosis
    • +
    • Multiple appropriate clinical triggers:
        +
      • DKA causing high AG acidosis
      • +
      • Diarrhea causing normal AG acidosis
      • +
      • Respiratory compensation plus sepsis/DKA driving respiratory alkalosis
      • +
      +
    • +
    +
  4. +
  5. Clinical pearls:

    +
      +
    • Multiple disorders often coexist in critically ill patients
    • +
    • Delta ratio helps identify mixed metabolic disorders
    • +
    • Clinical context crucial for interpretation
    • +
    +
  6. +
+

References

+
+ + + + \ No newline at end of file diff --git a/public/questions/nephrology/acid-base/metabolic-alkalosis.html b/public/questions/nephrology/acid-base/metabolic-alkalosis.html new file mode 100644 index 0000000..952f2cc --- /dev/null +++ b/public/questions/nephrology/acid-base/metabolic-alkalosis.html @@ -0,0 +1,104 @@ + + + + + + + acid-base + + + +

Metabolic Alkalosis Evaluation

+

Question

+

A 54-year-old woman with history of CHF presents with 2 weeks of nausea and weakness. She's been taking high doses of furosemide. Labs show:

+ +

Which statement best explains her acid-base disorder and appropriate management?

+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescription
A)Contraction alkalosis; treat with isotonic saline and potassium replacement
B)Diuretic-induced alkalosis; treat with KCl and continue diuretics
C)Primary metabolic alkalosis; treat with acetazolamide
D)Respiratory acidosis with metabolic compensation; no treatment needed
E)Mixed alkalosis; treat with fluid restriction and hydrogen chloride
+
+View Answer + +

Correct Answer

+

A

+

Explanation

+

This case represents chloride-responsive (saline-responsive) metabolic alkalosis:

+
    +
  1. Key diagnostic findings:

    +
      +
    • Elevated pH and HCO3 confirm metabolic alkalosis
    • +
    • Low urine Cl (<20 mEq/L) suggests chloride-responsive state
    • +
    • Hypokalemia and hypovolemia from diuretic use
    • +
    • Appropriate respiratory compensation (expected pCO2 = 0.7 × HCO3 + 20 ± 5)
    • +
    +
  2. +
  3. Pathophysiology:

    +
      +
    • Volume contraction from furosemide leads to:
        +
      • Increased bicarbonate reabsorption
      • +
      • Enhanced K+ and H+ exchange
      • +
      • Chloride depletion maintaining alkalosis
      • +
      +
    • +
    +
  4. +
  5. Management principles:

    +
      +
    • Volume repletion with NaCl restores chloride
    • +
    • K+ replacement essential for recovery
    • +
    • Underlying CHF needs careful monitoring
    • +
    • Diuretic adjustment may be needed
    • +
    +
  6. +
+

References

+
+ + + + \ No newline at end of file diff --git a/scripts/convertMarkdown.js b/scripts/convertMarkdown.js new file mode 100644 index 0000000..c0f3f41 --- /dev/null +++ b/scripts/convertMarkdown.js @@ -0,0 +1,69 @@ +const fs = require('fs'); +const path = require('path'); +const marked = require('marked'); +const matter = require('gray-matter'); + +function convertMarkdownFiles(questionsDir, outputDir) { + console.log(`Converting markdown files from ${questionsDir} to ${outputDir}`); + + const walkSync = (dir) => { + const files = fs.readdirSync(dir); + files.forEach(file => { + const filepath = path.join(dir, file); + const stat = fs.statSync(filepath); + + // Calculate relative path maintaining directory structure + const relativeToQuestions = path.relative(questionsDir, dir); + const currentOutputDir = path.join(outputDir, relativeToQuestions); + + if (stat.isDirectory()) { + console.log(`Creating directory: ${currentOutputDir}`); + fs.mkdirSync(currentOutputDir, { recursive: true }); + walkSync(filepath); + } else if (path.extname(file) === '.md') { + // Create output directory if it doesn't exist + if (!fs.existsSync(currentOutputDir)) { + console.log(`Creating directory: ${currentOutputDir}`); + fs.mkdirSync(currentOutputDir, { recursive: true }); + } + + const content = fs.readFileSync(filepath, 'utf8'); + const { data, content: markdownContent } = matter(content); + + const html = ` + + + + + + ${data.topic || 'Medical Question'} + + + + ${marked.parse(markdownContent)} + +`; + + const outputPath = path.join(currentOutputDir, file.replace('.md', '.html')); + console.log(`Writing file: ${outputPath}`); + fs.writeFileSync(outputPath, html); + } + }); + }; + + // Ensure base output directory exists + if (!fs.existsSync(outputDir)) { + console.log(`Creating base output directory: ${outputDir}`); + fs.mkdirSync(outputDir, { recursive: true }); + } + + walkSync(questionsDir); +} + +module.exports = convertMarkdownFiles; diff --git a/scripts/indexQuestions.js b/scripts/indexQuestions.js new file mode 100644 index 0000000..dde9848 --- /dev/null +++ b/scripts/indexQuestions.js @@ -0,0 +1,45 @@ +const fs = require('fs'); +const path = require('path'); +const matter = require('gray-matter'); + +function indexQuestions(questionsDir) { + const questions = []; + const walkSync = (dir) => { + const files = fs.readdirSync(dir); + files.forEach(file => { + const filepath = path.join(dir, file); + if (fs.statSync(filepath).isDirectory()) { + walkSync(filepath); + } else if (path.extname(file) === '.md') { + const content = fs.readFileSync(filepath, 'utf8'); + const { data } = matter(content); + if (data.specialty) { + // Extract just the path after 'questions' directory + const relativePath = filepath + .split(/[\/\\]questions[\/\\]/)[1] // Split on questions directory + .replace(/\\/g, '/') // Convert backslashes to forward slashes + .replace('.md', '.html'); + + questions.push({ + filepath: `questions/${relativePath}`, // Add questions prefix + specialty: data.specialty, + topic: data.topic, + difficulty: data.difficulty, + id: data.id, + title: content.split('\n')[0].replace('# ', '') + }); + } + } + }); + }; + + walkSync(questionsDir); + return questions.sort((a, b) => a.specialty.localeCompare(b.specialty)); +} + +const questionsDir = path.join(__dirname, '../questions'); +const index = indexQuestions(questionsDir); +fs.writeFileSync( + path.join(__dirname, '../public/questionIndex.json'), + JSON.stringify(index, null, 2) +);