'use strict'; /* ─────────────────────────────────────────────────────────────────────────── seed_ctmath_rt2324_e3v1.js Чистый вариант-пробник для трека exam-prep `ctmath`. Источник: РТ–2023/2024, Этап III, Вариант 1 (РИКЗ, «Тематическое консультирование по математике»). 30 заданий: А1–А10 + В1–В20. Перенабрано вручную в KaTeX по PDF (визуальное чтение, НЕ OCR): F:\!Рабочие\ЦТ\Математика\Математика\РТ\2023-2024\МАТ РТ-3 23_24 В1.pdf variant=106 — Этап III РТ-2023/24 (этап I — 104, этап II — 105). Геометрия закодирована текстом (стандартная разметка фигур / углы словами). Исключение — В1 (чтение графика): кусочно-линейная нечётная функция воспроизведена inline-SVG в figure_html (как у math9-заданий); все 6 утверждений и ответ (145) согласованы с реконструкцией. Идемпотентность: upsert по UNIQUE(exam_key, variant, task_idx). Запуск: node backend/scripts/seed_ctmath_rt2324_e3v1.js # DRY-RUN (по умолчанию) node backend/scripts/seed_ctmath_rt2324_e3v1.js --apply # запись в БД ⚠️ Массовую запись в БД запускает ПОЛЬЗОВАТЕЛЬ вручную (авто-режим Claude Code блокирует продакшн-записи). Без --apply ничего не пишется. ─────────────────────────────────────────────────────────────────────────── */ const { DatabaseSync } = require('node:sqlite'); const path = require('path'); const APPLY = process.argv.includes('--apply'); const EXAM = 'ctmath'; const VARIANT = 106; const PROV = 'РТ–2023/2024, Этап III, Вариант 1'; const R = String.raw; /* opts: метки кириллица а–д (как в существующих строках ctmath; checkAnswerServer имеет ветку /^[а-д]$/). РТ-варианты 1..5 → а..д. */ const L = ['а', 'б', 'в', 'г', 'д']; const mc = (...html) => html.map((h, i) => [L[i], h]); /* ── SVG-график для В1: нечётная кусочно-линейная функция на [-6;6] через точки (-6,-3),(-4,1),(4,-1),(6,3). f(0)=0; возрастает на [-6;-4] и [4;6], убывает на [-4;4]. Цвета — только в SVG-стоки (как у math9-фигур). */ const FIG_B1 = ` x y O 1 1 y=f(x) `; /* ── 30 заданий ─────────────────────────────────────────────────────────── */ const TASKS = [ // ── Часть A: А1–А10 ────────────────────────────────────────────────────── { idx: 1, type: 'mc', topic: 'functions', subtopic: 'fn-graphs', diff: 1, text: R`На координатной плоскости отмечены точки $A(2;-1)$, $B(1;2)$, $C(-2;-2)$, $D(-1;1)$, $E(0;-2)$. Выберите ту из них, сумма координат которой равна $-4$.`, opts: mc('$A$', '$B$', '$C$', '$D$', '$E$'), answer: 'в', sol: R`Сумма координат: для $A$ это $2+(-1)=1$, для $B$ это $1+2=3$, для $C$ это $-2+(-2)=-4$, для $D$ это $-1+1=0$, для $E$ это $0+(-2)=-2$. Сумме $-4$ соответствует точка $C$.`, ref: 'Математика, 6 класс, гл. 5, § 1' }, { idx: 2, type: 'mc', topic: 'stereometry', subtopic: 'ster-basics', diff: 3, text: R`Дан куб $ABCDA_1B_1C_1D_1$. Точка $K$ — середина диагонали $A_1D$. Среди отрезков $A_1B_1$, $B_1D_1$, $C_1K$, $BB_1$, $A_1C_1$ укажите отрезок, по которому плоскость, заданная прямой $DC_1$ и точкой $K$, пересекает плоскость грани $A_1B_1C_1D_1$.`, opts: mc('$A_1B_1$', '$B_1D_1$', '$C_1K$', '$BB_1$', '$A_1C_1$'), answer: 'д', sol: R`Секущая плоскость, заданная прямой $DC_1$ и точкой $K$, содержит точку $C_1$ (она на $DC_1$) и точку $A_1$ (так как $K$ — середина $A_1D$, прямая $DC_1$ и точка $K$ задают плоскость диагонального сечения, проходящую через $A_1$). Точки $A_1$ и $C_1$ принадлежат и грани $A_1B_1C_1D_1$, поэтому пересечение плоскостей — отрезок $A_1C_1$.`, ref: 'Геометрия, 10 класс, разд. 1, § 2–3' }, { idx: 3, type: 'mc', topic: 'numbers', subtopic: 'num-real', diff: 2, text: R`Расположите числа $\log_3 27$, $\ 3^{-1}$, $\ \sqrt{64}$ в порядке возрастания.`, opts: mc('$\sqrt{64};\ \log_3 27;\ 3^{-1}$', '$3^{-1};\ \sqrt{64};\ \log_3 27$', '$\sqrt{64};\ 3^{-1};\ \log_3 27$', '$3^{-1};\ \log_3 27;\ \sqrt{64}$', '$\log_3 27;\ \sqrt{64};\ 3^{-1}$'), answer: 'г', sol: R`$\log_3 27=\log_3 3^{3}=3$; $\ 3^{-1}=\dfrac13$; $\ \sqrt{64}=8$. Так как $\dfrac13<3<8$, числа в порядке возрастания: $3^{-1};\ \log_3 27;\ \sqrt{64}$.`, ref: 'Алгебра, 8 класс, гл. 1, § 1–4; гл. 11 кл., § 3' }, { idx: 4, type: 'mc', topic: 'expressions', subtopic: 'expr-polynomials', diff: 1, text: R`Укажите номер выражения, тождественно равного выражению $a^{3}$.`, opts: mc('$a:a^{3}$', '$a\cdot a^{2}$', '$\left(a^{2}\right)^{2}$', '$3a$', '$a^{-3}$'), answer: 'б', sol: R`По свойству степеней $a\cdot a^{2}=a^{1+2}=a^{3}$. (Остальные: $a:a^{3}=a^{-2}$; $\left(a^{2}\right)^{2}=a^{4}$; $3a$ и $a^{-3}$ не равны $a^{3}$.)`, ref: 'Алгебра, 7 класс, гл. 2, § 5' }, { idx: 5, type: 'mc', topic: 'expressions', subtopic: 'expr-polynomials', diff: 1, text: R`Результат разложения многочлена $4b^{2}+4bc-4b$ на множители имеет вид:`, opts: mc('$4b(b+c)$', '$4b(bc-1)$', '$4b(1+c)$', '$(4b-1)(b+c)$', '$4b(b+c-1)$'), answer: 'д', sol: R`Общий множитель членов многочлена $4b^{2}+4bc-4b$ — одночлен $4b$. Тогда $4b^{2}+4bc-4b=4b(b+c-1)$.`, ref: 'Алгебра, 7 класс, гл. 2, § 14' }, { idx: 6, type: 'open', topic: 'expressions', subtopic: 'expr-powers-roots', diff: 2, text: R`Среди чисел $10$, $99$, $0$, $-10$, $100$ укажите номера тех, которые не входят в область определения выражения $\dfrac{1}{10-\sqrt{x}}$.
1) $10$; 2) $99$; 3) $0$; 4) $-10$; 5) $100$.
Ответ запишите цифрами в порядке возрастания, без пробелов.`, answer: '45', ansShow: '4, 5', sol: R`Выражение $\dfrac{1}{10-\sqrt{x}}$ имеет смысл при $x\ge0$ и $10-\sqrt{x}\ne0$, то есть $x\ge0$, $x\ne100$. Область определения $[0;100)\cup(100;+\infty)$. Из данных чисел ей не принадлежат $-10$ (так как $-10<0$) и $100$ (исключено). Это числа под номерами 4 и 5.`, ref: 'Алгебра, 8 класс, гл. 1, § 1' }, { idx: 7, type: 'mc', topic: 'word-sequences', subtopic: 'word-problems', diff: 2, text: R`За три четверти учебного года Петя использовал $\dfrac25$ купленных в начале учебного года тетрадей, после чего у него осталось $48$ тетрадей. Сколько тетрадей купил Петя в начале учебного года?`, opts: mc('$80$', '$96$', '$120$', '$74$', '$116$'), answer: 'а', sol: R`Числу $48$ соответствует дробь $1-\dfrac25=\dfrac35$ всех тетрадей. Тогда куплено $48:\dfrac35=\dfrac{48\cdot5}{3}=80$ тетрадей.`, ref: 'Математика, 5 класс, ч. 2, гл. 3, § 10' }, { idx: 8, type: 'mc', topic: 'trigonometry', subtopic: 'trig-identities', diff: 2, text: R`Найдите значение выражения $\operatorname{tg}(-120^\circ)+\left|-\sqrt3\right|$.`, opts: mc('$0$', '$\dfrac{4\sqrt3}{3}$', '$1-\sqrt3$', '$2\sqrt3$', '$-\dfrac{2\sqrt3}{3}$'), answer: 'г', sol: R`$\operatorname{tg}(-120^\circ)=-\operatorname{tg}120^\circ=-\operatorname{tg}(180^\circ-60^\circ)=\operatorname{tg}60^\circ=\sqrt3$. Тогда $\operatorname{tg}(-120^\circ)+\left|-\sqrt3\right|=\sqrt3+\sqrt3=2\sqrt3.$`, ref: 'Алгебра, 10 класс, гл. 1, § 3; § 9' }, { idx: 9, type: 'mc', topic: 'stereometry', subtopic: 'ster-rotation', diff: 2, text: R`Сечение сферы плоскостью, отстоящей от её центра на расстоянии $3$, имеет радиус $3\sqrt2$. Найдите радиус сферы.`, opts: mc('$9\sqrt2$', '$3\sqrt3$', '$6$', '$12$', '$4\sqrt3$'), answer: 'б', sol: R`Радиус сферы $R$ — гипотенуза прямоугольного треугольника с катетами $3$ (расстояние до плоскости) и $3\sqrt2$ (радиус сечения). По теореме Пифагора $R^{2}=3^{2}+\left(3\sqrt2\right)^{2}=9+18=27$, поэтому $R=3\sqrt3$.`, ref: 'Геометрия, 11 класс, разд. 3, § 5' }, { idx: 10, type: 'open', topic: 'functions', subtopic: 'fn-properties', diff: 2, text: R`Укажите номера функций, которые принимают только положительные значения на промежутке $(4;+\infty)$.
1) $f(x)=-4x$;
2) $f(x)=\sqrt{x-4}$;
3) $f(x)=x^{3}-4$;
4) $f(x)=\log_{\frac14}x$;
5) $f(x)=-x^{2}-4$.
Ответ запишите цифрами в порядке возрастания, без пробелов.`, answer: '23', ansShow: '2, 3', sol: R`$1)$ $-4x$ при $x>4$ отрицательна. $\ 2)$ $\sqrt{x-4}$ при $x>4$ положительна. $\ 3)$ $x^{3}-4$ положительна при $x>\sqrt[3]{4}$, а $(4;+\infty)\subset(\sqrt[3]{4};+\infty)$ — положительна. $\ 4)$ $\log_{\frac14}x$ положительна только на $(0;1)$. $\ 5)$ $-x^{2}-4$ отрицательна при всех $x$. Подходят функции 2 и 3.`, ref: 'Алгебра, 8 класс, гл. 3, § 13–14' }, // ── Часть B: В1–В20 ────────────────────────────────────────────────────── { idx: 11, type: 'open', topic: 'functions', subtopic: 'fn-properties', diff: 3, fig: FIG_B1, text: R`На рисунке изображён график функции $y=f(x)$, определённой на промежутке $[-6;6]$. Выберите верные утверждения.
1) функция является нечётной;
2) $f(3)>0$;
3) график функции симметричен относительно оси ординат;
4) $f(-5)>f(-6)$;
5) функция убывает на промежутке $[-4;4]$;
6) график функции $y=f(x)+3$ проходит через точку $(0;2)$.
Ответ запишите цифрами в порядке возрастания, без пробелов.`, answer: '145', ansShow: '1, 4, 5', sol: R`$1)$ верно: график симметричен относительно начала координат, поэтому функция нечётная. $\ 2)$ неверно: по графику $f(3)<0$. $\ 3)$ неверно: график нечётной функции симметричен относительно начала координат, а не оси ординат. $\ 4)$ верно: на промежутке $[-6;-4]$ функция возрастает, поэтому $f(-5)>f(-6)$. $\ 5)$ верно: на отрезке $[-4;4]$ при увеличении $x$ значения функции уменьшаются. $\ 6)$ неверно: $f(0)=0$, поэтому график $y=f(x)+3$ проходит через точку $(0;3)$, а не $(0;2)$.`, ref: 'Алгебра, 9 класс, гл. 2, § 6–9' }, { idx: 12, type: 'long', topic: 'stereometry', subtopic: 'ster-angles-distances', diff: 3, text: R`$ABCDA_1B_1C_1D_1$ — куб. Точки $M$ и $K$ — середины рёбер $A_1D_1$ и $AA_1$ соответственно. Для начала каждого из предложений А–В подберите его окончание 1–6 так, чтобы получилось верное утверждение.
Начало:
А) Величина угла между прямыми $A_1B_1$ и $KM$ равна …
Б) Величина угла между прямыми $B_1C_1$ и $KM$ равна …
В) Величина угла между прямыми $BD$ и $KM$ равна …
Окончание:
1) $30^\circ$; 2) $0^\circ$; 3) $60^\circ$; 4) $90^\circ$; 5) $120^\circ$; 6) $45^\circ$.
Ответ запишите сочетанием букв и цифр, например: А1Б1В4.`, answer: 'А4Б6В3', ansShow: 'А4Б6В3', sol: R`А) Прямая $A_1B_1$ перпендикулярна плоскости грани $AA_1D_1D$, а $KM$ лежит в этой плоскости, поэтому $A_1B_1\perp KM$ — угол $90^\circ$ (окончание 4). Б) $B_1C_1\parallel A_1D_1$, поэтому угол между $B_1C_1$ и $KM$ равен углу $A_1MK$; в равнобедренном прямоугольном треугольнике $KA_1M$ ($A_1K=A_1M$) он равен $45^\circ$ (окончание 6). В) Через середину $P$ ребра проведём $MP\parallel B_1D_1$; треугольник $PMK$ равносторонний, поэтому угол между $BD$ и $KM$ равен $60^\circ$ (окончание 3).`, ref: 'Геометрия, 10 класс, разд. 2, § 4' }, { idx: 13, type: 'open', topic: 'numbers', subtopic: 'num-divisibility', diff: 2, text: R`Найдите сумму всех натуральных делителей числа $95$.`, answer: '120', sol: R`Число $95=5\cdot19$ имеет четыре натуральных делителя: $1$, $5$, $19$ и $95$. Их сумма равна $1+5+19+95=120$.`, ref: 'Математика, 5 класс, ч. 1, гл. 1, § 12' }, { idx: 14, type: 'open', topic: 'equations', subtopic: 'eq-linear', diff: 2, text: R`Найдите произведение наименьшего и наибольшего целых решений двойного неравенства $-51\dfrac13<-3x<4\sqrt2$.`, answer: '-17', sol: R`Разделим все части на $-3$ (знаки неравенства меняются на противоположные): $-\dfrac{4\sqrt2}{3}1$ решений не имеет. Из $\sin3x=0$: $3x=180^\circ n$, $x=60^\circ n$. Промежутку $[-270^\circ;-135^\circ]$ принадлежат $-180^\circ$ ($n=-3$) и $-240^\circ$ ($n=-4$); их сумма равна $-420^\circ$.`, ref: 'Алгебра, 10 класс, гл. 1, § 8; § 12' }, { idx: 29, type: 'open', topic: 'equations', subtopic: 'eq-logarithmic', diff: 4, text: R`Найдите сумму всех целых решений неравенства $\log_{0{,}7}\left(x^{2}-7x+18\right)-\log_{0{,}7}(x-1)<\log_{0{,}7}2$ на промежутке $(-10;10)$.`, answer: '35', sol: R`Неравенство приводится к виду $\log_{0{,}7}\left(x^{2}-7x+18\right)<\log_{0{,}7}\bigl(2(x-1)\bigr)$. Основание $0{,}7<1$ (функция убывает), поэтому равносильна система $\begin{cases}x^{2}-7x+18>2x-2,\\2x-2>0.\end{cases}$ Первое: $x^{2}-9x+20>0\Rightarrow x<4$ или $x>5$; второе: $x>1$. Решение $(1;4)\cup(5;+\infty)$. Пересечение с $(-10;10)$: $(1;4)\cup(5;10)$; целые $2,3,6,7,8,9$, их сумма $35$.`, ref: 'Алгебра, 11 класс, гл. 3, § 10' }, { idx: 30, type: 'open', topic: 'stereometry', subtopic: 'ster-angles-distances', diff: 5, text: R`Сторона $AB$ треугольника $ABC$, у которого $AB=BC=12$, $AC=8$, лежит в плоскости $\alpha$, а длины проекций двух других сторон треугольника $ABC$ на эту плоскость относятся как $1:3$. Найдите значение выражения $\dfrac{13}{\cos^{2}\beta}$, где $\beta$ — угол между плоскостью треугольника $ABC$ и плоскостью $\alpha$.`, answer: '256', sol: R`Пусть $CO$ — перпендикуляр к $\alpha$, $AO:BO=1:3$, $AO=x$, $BO=3x$. Из $CO^{2}=BC^{2}-BO^{2}=AC^{2}-AO^{2}$: $144-9x^{2}=64-x^{2}$, $8x^{2}=80$, $x=\sqrt{10}$, $CO=3\sqrt6$. Высота $CK$ треугольника $ABC$ к $AB$: по формуле Герона $S=32\sqrt2$, откуда $CK=\dfrac{2S}{AB}=\dfrac{64\sqrt2}{12}=\dfrac{16\sqrt2}{3}$. Тогда $OK=\sqrt{CK^{2}-CO^{2}}=\sqrt{\dfrac{512}{9}-54}=\dfrac{\sqrt{26}}{3}$, а $\cos\beta=\dfrac{OK}{CK}=\dfrac{\sqrt{13}}{16}$. Значит, $\dfrac{13}{\cos^{2}\beta}=\dfrac{13\cdot256}{13}=256$.`, ref: 'Геометрия, 10 класс, разд. 3, § 10' }, ]; /* ── Сборка solution_html ────────────────────────────────────────────────── */ function ansShowOf(t) { if (t.ansShow != null) return t.ansShow; if (t.type === 'mc') return `${t.answer})`; return `$${t.answer}$`; } function buildSolution(t) { const ans = ansShowOf(t); let html = `${t.sol}
Ответ: ${ans}
`; if (t.ref) html += `
Учебник: ${t.ref}
`; return html; } /* ── Самопроверка (повтор логики checkAnswerServer из exam-prep.js) ────────── */ const EPS = 1e-6; function srvToNumber(s) { if (s == null) return NaN; let t = String(s).trim().replace(/\$/g, '').replace(/\s+/g, '').replace(',', '.'); const f = t.match(/^(-?\d+(?:\.\d+)?)\s*\/\s*(-?\d+(?:\.\d+)?)$/); if (f) { const n = Number(f[1]), d = Number(f[2]); return d === 0 ? NaN : n / d; } const n = Number(t); return Number.isFinite(n) ? n : NaN; } function checkAnswerServer(userInput, canonical) { if (userInput == null || canonical == null) return false; const c = String(canonical).trim(); if (/^[а-д]$/.test(c)) return String(userInput).trim().toLowerCase() === c.toLowerCase(); if (/^[^;]+;[^;]+$/.test(c)) return false; const cn = srvToNumber(c), un = srvToNumber(userInput); if (Number.isNaN(cn) || Number.isNaN(un)) return false; return Math.abs(cn - un) < EPS; } /* ── Валидация набора ──────────────────────────────────────────────────────── */ const problems = []; if (TASKS.length !== 30) problems.push(`Ожидалось 30 заданий, получено ${TASKS.length}`); const seen = new Set(); for (const t of TASKS) { if (seen.has(t.idx)) problems.push(`Дубль task_idx=${t.idx}`); seen.add(t.idx); if (t.idx < 1 || t.idx > 30) problems.push(`task_idx вне 1..30: ${t.idx}`); if (!['mc', 'open', 'long'].includes(t.type)) problems.push(`#${t.idx}: тип ${t.type}`); if (t.type === 'mc') { if (!Array.isArray(t.opts) || t.opts.length !== 5) problems.push(`#${t.idx}: mc должен иметь 5 вариантов`); if (!t.opts.some(o => o[0] === t.answer)) problems.push(`#${t.idx}: answer "${t.answer}" не среди меток`); } if (!t.text || !t.sol) problems.push(`#${t.idx}: пустой text/sol`); if (t.type !== 'long' && !checkAnswerServer(t.answer, t.answer)) problems.push(`#${t.idx}: answer "${t.answer}" не проходит self-check (Unicode-минус? пробел?)`); if (/−/.test(String(t.answer))) problems.push(`#${t.idx}: Unicode-минус в answer`); } /* ── Экспорт для тестов/тиража (без запуска main при require) ──────────────── */ module.exports = { TASKS, buildSolution, ansShowOf, checkAnswerServer, EXAM, VARIANT, PROV }; if (require.main !== module) return; /* ── Открытие БД ───────────────────────────────────────────────────────────── */ const DB = path.join(__dirname, '..', 'data', 'learnspace.db'); const db = new DatabaseSync(DB); const track = db.prepare(`SELECT exam_key, variants_count FROM exam_tracks WHERE exam_key=?`).get(EXAM); if (!track) { console.error(`✗ Трек '${EXAM}' не найден в exam_tracks. Прерывание.`); process.exit(1); } /* ── DRY-RUN сводка ────────────────────────────────────────────────────────── */ console.log(`\n=== seed_ctmath_rt2324_e3v1 (${PROV}) variant=${VARIANT} ===`); console.log(`Режим: ${APPLY ? 'APPLY (запись)' : 'DRY-RUN (только проверка)'}\n`); const byType = TASKS.reduce((a, t) => (a[t.type] = (a[t.type] || 0) + 1, a), {}); console.log('Типы:', JSON.stringify(byType), ' | с фигурой:', TASKS.filter(t => t.fig).length, '\n'); console.log('idx | type | subtopic | d | answer'); console.log('----+------+-----------------------+---+----------'); for (const t of TASKS) { console.log(`${String(t.idx).padStart(3)} | ${t.type.padEnd(4)} | ${String(t.subtopic).padEnd(21)} | ${t.diff} | ${String(t.answer)}`); } if (problems.length) { console.error(`\n✗ ПРОБЛЕМЫ (${problems.length}):`); problems.forEach(p => console.error(' - ' + p)); console.error('\nЗапись отменена из-за ошибок валидации.'); db.close(); process.exit(1); } console.log('\n✓ Валидация и self-check ответов пройдены (30/30).'); /* ── APPLY: upsert ─────────────────────────────────────────────────────────── */ if (!APPLY) { console.log('\nDRY-RUN: ничего не записано. Для записи: node backend/scripts/seed_ctmath_rt2324_e3v1.js --apply\n'); db.close(); process.exit(0); } const upsert = db.prepare(` INSERT INTO exam_tasks (exam_key, variant, task_idx, task_type, text_html, figure_html, opts_json, answer, solution_html, topic, subtopic, difficulty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(exam_key, variant, task_idx) DO UPDATE SET task_type = excluded.task_type, text_html = excluded.text_html, figure_html = excluded.figure_html, opts_json = excluded.opts_json, answer = excluded.answer, solution_html = excluded.solution_html, topic = excluded.topic, subtopic = excluded.subtopic, difficulty = excluded.difficulty `); let n = 0; db.exec('BEGIN'); try { for (const t of TASKS) { upsert.run( EXAM, VARIANT, t.idx, t.type, t.text, t.fig || null, t.type === 'mc' ? JSON.stringify(t.opts) : null, t.answer, buildSolution(t), t.topic, t.subtopic, t.diff ); n++; } const distinct = db.prepare(`SELECT COUNT(DISTINCT variant) c FROM exam_tasks WHERE exam_key=? AND variant BETWEEN 101 AND 1999`).get(EXAM).c; db.prepare(`UPDATE exam_tracks SET variants_count=? WHERE exam_key=?`).run(distinct, EXAM); db.exec('COMMIT'); console.log(`\n✓ Записано/обновлено ${n} заданий (variant=${VARIANT}).`); console.log(`✓ exam_tracks.variants_count = ${distinct} (различных вариантов).`); console.log(`\nПробник доступен: /exam-prep/ctmath → «Варианты» → «РТ-2023/24 · этап III».\n`); } catch (e) { db.exec('ROLLBACK'); console.error('\n✗ Ошибка записи, откат транзакции:', e.message); process.exitCode = 1; } db.close();