diff --git a/assets/generated/01-title-food-chain.png b/assets/generated/01-title-food-chain.png deleted file mode 100644 index 92c5a4c..0000000 Binary files a/assets/generated/01-title-food-chain.png and /dev/null differ diff --git a/assets/generated/01-title-food-chain.signed.svg b/assets/generated/01-title-food-chain.signed.svg deleted file mode 100644 index a7199dd..0000000 --- a/assets/generated/01-title-food-chain.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Титульная картинка - Вампирическая пищевая цепочка: элита, отбор и человечество как ресурс - diff --git a/assets/generated/02-medieval-origin.png b/assets/generated/02-medieval-origin.png deleted file mode 100644 index 8c95f08..0000000 Binary files a/assets/generated/02-medieval-origin.png and /dev/null differ diff --git a/assets/generated/02-medieval-origin.signed.svg b/assets/generated/02-medieval-origin.signed.svg deleted file mode 100644 index 837e40f..0000000 --- a/assets/generated/02-medieval-origin.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Происхождение вируса - XII-XIV века: войны, эпидемии и скрытое распространение SNV-12 - diff --git a/assets/generated/03-vampire-classes.png b/assets/generated/03-vampire-classes.png deleted file mode 100644 index 03f06a7..0000000 Binary files a/assets/generated/03-vampire-classes.png and /dev/null differ diff --git a/assets/generated/03-vampire-classes.signed.svg b/assets/generated/03-vampire-classes.signed.svg deleted file mode 100644 index 04e264d..0000000 --- a/assets/generated/03-vampire-classes.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Классы вампиров - Молодой носитель, старший адаптант и гемарх в одной иерархии - diff --git a/assets/generated/04-failed-infection.png b/assets/generated/04-failed-infection.png deleted file mode 100644 index fc2cea8..0000000 Binary files a/assets/generated/04-failed-infection.png and /dev/null differ diff --git a/assets/generated/04-failed-infection.signed.svg b/assets/generated/04-failed-infection.signed.svg deleted file mode 100644 index ceaf68c..0000000 --- a/assets/generated/04-failed-infection.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Неудачное заражение - Феррогемный каскад и термогемолитический коллапс - diff --git a/assets/generated/05-recognize-vampire.png b/assets/generated/05-recognize-vampire.png deleted file mode 100644 index 5d07fb5..0000000 Binary files a/assets/generated/05-recognize-vampire.png and /dev/null differ diff --git a/assets/generated/05-recognize-vampire.signed.svg b/assets/generated/05-recognize-vampire.signed.svg deleted file mode 100644 index a42f934..0000000 --- a/assets/generated/05-recognize-vampire.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Как распознать вампира - Судебно-медицинский плакат с внешними и поведенческими маркерами - diff --git a/assets/generated/06-blood-economy.png b/assets/generated/06-blood-economy.png deleted file mode 100644 index 6276d77..0000000 Binary files a/assets/generated/06-blood-economy.png and /dev/null differ diff --git a/assets/generated/06-blood-economy.signed.svg b/assets/generated/06-blood-economy.signed.svg deleted file mode 100644 index d5612ba..0000000 --- a/assets/generated/06-blood-economy.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Экономика качественной крови - Массовая, стабильная, пиковая и династическая кровь как ресурс - diff --git a/assets/generated/07-artificial-blood.png b/assets/generated/07-artificial-blood.png deleted file mode 100644 index c86be55..0000000 Binary files a/assets/generated/07-artificial-blood.png and /dev/null differ diff --git a/assets/generated/07-artificial-blood.signed.svg b/assets/generated/07-artificial-blood.signed.svg deleted file mode 100644 index 7b77eb9..0000000 --- a/assets/generated/07-artificial-blood.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Почему искусственная кровь не подходит - Сравнение живой сигнатуры крови и стерильного суррогата - diff --git a/assets/generated/08-hidden-donor-market.png b/assets/generated/08-hidden-donor-market.png deleted file mode 100644 index f279def..0000000 Binary files a/assets/generated/08-hidden-donor-market.png and /dev/null differ diff --git a/assets/generated/08-hidden-donor-market.signed.svg b/assets/generated/08-hidden-donor-market.signed.svg deleted file mode 100644 index 5245757..0000000 --- a/assets/generated/08-hidden-donor-market.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Тайный рынок доноров - Клиники, биобанки, школы, клубы и логистика к верхушке - diff --git a/assets/generated/09-donor-house.png b/assets/generated/09-donor-house.png deleted file mode 100644 index 15b7d94..0000000 Binary files a/assets/generated/09-donor-house.png and /dev/null differ diff --git a/assets/generated/09-donor-house.signed.svg b/assets/generated/09-donor-house.signed.svg deleted file mode 100644 index a5318d0..0000000 --- a/assets/generated/09-donor-house.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Донорский дом - Элитный пансион как скрытая инфраструктура премиальных доноров - diff --git a/assets/generated/10-blood-etiquette.png b/assets/generated/10-blood-etiquette.png deleted file mode 100644 index aedfc8a..0000000 Binary files a/assets/generated/10-blood-etiquette.png and /dev/null differ diff --git a/assets/generated/10-blood-etiquette.signed.svg b/assets/generated/10-blood-etiquette.signed.svg deleted file mode 100644 index 9418bf1..0000000 --- a/assets/generated/10-blood-etiquette.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Кровяной этикет элиты - Аристократический ритуал оценки донора как дегустация вина - diff --git a/assets/generated/11-feeding-zones-map.png b/assets/generated/11-feeding-zones-map.png deleted file mode 100644 index 3b867c8..0000000 Binary files a/assets/generated/11-feeding-zones-map.png and /dev/null differ diff --git a/assets/generated/11-feeding-zones-map.signed.svg b/assets/generated/11-feeding-zones-map.signed.svg deleted file mode 100644 index f0e81da..0000000 --- a/assets/generated/11-feeding-zones-map.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Геополитика кормовых зон - Резервуары населения, коридоры, убежища и экспериментальные территории - diff --git a/assets/generated/12-food-chain-chart.png b/assets/generated/12-food-chain-chart.png deleted file mode 100644 index 9815901..0000000 Binary files a/assets/generated/12-food-chain-chart.png and /dev/null differ diff --git a/assets/generated/12-food-chain-chart.signed.svg b/assets/generated/12-food-chain-chart.signed.svg deleted file mode 100644 index 786c393..0000000 --- a/assets/generated/12-food-chain-chart.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Пищевая цепочка - От человека через сортировку и рынок качества к гемархам - diff --git a/assets/generated/13-medieval-europe-map.png b/assets/generated/13-medieval-europe-map.png deleted file mode 100644 index ac0054f..0000000 Binary files a/assets/generated/13-medieval-europe-map.png and /dev/null differ diff --git a/assets/generated/13-medieval-europe-map.signed.svg b/assets/generated/13-medieval-europe-map.signed.svg deleted file mode 100644 index bd955ea..0000000 --- a/assets/generated/13-medieval-europe-map.signed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - Средневековье создаёт идеальную среду - XII-XIV века: войны, миграции, антисанитария, эпидемии - diff --git a/assets/generated/README.md b/assets/generated/README.md deleted file mode 100644 index 374f31c..0000000 --- a/assets/generated/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Generated vampire visuals - -Подписанные версии лежат в SVG-файлах: плашка с текстом редактируется прямо в SVG. Чистые PNG лежат рядом с теми же номерами. - -- 01-title-food-chain - - PNG: `01-title-food-chain.png` - - Подписанная версия: `01-title-food-chain.signed.svg` - - Подпись: Титульная картинка — Вампирическая пищевая цепочка: элита, отбор и человечество как ресурс -- 02-medieval-origin - - PNG: `02-medieval-origin.png` - - Подписанная версия: `02-medieval-origin.signed.svg` - - Подпись: Происхождение вируса — XII-XIV века: войны, эпидемии и скрытое распространение SNV-12 -- 03-vampire-classes - - PNG: `03-vampire-classes.png` - - Подписанная версия: `03-vampire-classes.signed.svg` - - Подпись: Классы вампиров — Молодой носитель, старший адаптант и гемарх в одной иерархии -- 04-failed-infection - - PNG: `04-failed-infection.png` - - Подписанная версия: `04-failed-infection.signed.svg` - - Подпись: Неудачное заражение — Феррогемный каскад и термогемолитический коллапс -- 05-recognize-vampire - - PNG: `05-recognize-vampire.png` - - Подписанная версия: `05-recognize-vampire.signed.svg` - - Подпись: Как распознать вампира — Судебно-медицинский плакат с внешними и поведенческими маркерами -- 06-blood-economy - - PNG: `06-blood-economy.png` - - Подписанная версия: `06-blood-economy.signed.svg` - - Подпись: Экономика качественной крови — Массовая, стабильная, пиковая и династическая кровь как ресурс -- 07-artificial-blood - - PNG: `07-artificial-blood.png` - - Подписанная версия: `07-artificial-blood.signed.svg` - - Подпись: Почему искусственная кровь не подходит — Сравнение живой сигнатуры крови и стерильного суррогата -- 08-hidden-donor-market - - PNG: `08-hidden-donor-market.png` - - Подписанная версия: `08-hidden-donor-market.signed.svg` - - Подпись: Тайный рынок доноров — Клиники, биобанки, школы, клубы и логистика к верхушке -- 09-donor-house - - PNG: `09-donor-house.png` - - Подписанная версия: `09-donor-house.signed.svg` - - Подпись: Донорский дом — Элитный пансион как скрытая инфраструктура премиальных доноров -- 10-blood-etiquette - - PNG: `10-blood-etiquette.png` - - Подписанная версия: `10-blood-etiquette.signed.svg` - - Подпись: Кровяной этикет элиты — Аристократический ритуал оценки донора как дегустация вина -- 11-feeding-zones-map - - PNG: `11-feeding-zones-map.png` - - Подписанная версия: `11-feeding-zones-map.signed.svg` - - Подпись: Геополитика кормовых зон — Резервуары населения, коридоры, убежища и экспериментальные территории -- 12-food-chain-chart - - PNG: `12-food-chain-chart.png` - - Подписанная версия: `12-food-chain-chart.signed.svg` - - Подпись: Пищевая цепочка — От человека через сортировку и рынок качества к гемархам -- 13-medieval-europe-map - - PNG: `13-medieval-europe-map.png` - - Подписанная версия: `13-medieval-europe-map.signed.svg` - - Подпись: Средневековье создаёт идеальную среду — XII-XIV века: войны, миграции, антисанитария, эпидемии diff --git a/assets/generated/ai-01-snv12-agent.png b/assets/generated/ai-01-snv12-agent.png new file mode 100644 index 0000000..46d1184 Binary files /dev/null and b/assets/generated/ai-01-snv12-agent.png differ diff --git a/assets/generated/ai-02-medieval-spread-map.png b/assets/generated/ai-02-medieval-spread-map.png new file mode 100644 index 0000000..a2bee03 Binary files /dev/null and b/assets/generated/ai-02-medieval-spread-map.png differ diff --git a/assets/generated/ai-03-vampire-classes.png b/assets/generated/ai-03-vampire-classes.png new file mode 100644 index 0000000..8f7fca2 Binary files /dev/null and b/assets/generated/ai-03-vampire-classes.png differ diff --git a/assets/generated/ai-04-failed-infection.png b/assets/generated/ai-04-failed-infection.png new file mode 100644 index 0000000..b6c425e Binary files /dev/null and b/assets/generated/ai-04-failed-infection.png differ diff --git a/assets/generated/ai-05-blood-economy.png b/assets/generated/ai-05-blood-economy.png new file mode 100644 index 0000000..da35ad4 Binary files /dev/null and b/assets/generated/ai-05-blood-economy.png differ diff --git a/assets/generated/ai-06-live-vs-artificial-blood.png b/assets/generated/ai-06-live-vs-artificial-blood.png new file mode 100644 index 0000000..3a44fe7 Binary files /dev/null and b/assets/generated/ai-06-live-vs-artificial-blood.png differ diff --git a/assets/generated/ai-07-hidden-donor-market.png b/assets/generated/ai-07-hidden-donor-market.png new file mode 100644 index 0000000..61853e6 Binary files /dev/null and b/assets/generated/ai-07-hidden-donor-market.png differ diff --git a/assets/generated/ai-08-feeding-zones-map.png b/assets/generated/ai-08-feeding-zones-map.png new file mode 100644 index 0000000..d4e0197 Binary files /dev/null and b/assets/generated/ai-08-feeding-zones-map.png differ diff --git a/generate_presentation.js b/generate_presentation.js index de5d1e5..e1af12d 100644 --- a/generate_presentation.js +++ b/generate_presentation.js @@ -4,364 +4,394 @@ const pptxgen = require('pptxgenjs'); const base = __dirname; const outPath = path.join(base, 'prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx'); const assets = { - title: path.join(base, 'assets', 'generated', '01-title-food-chain.png'), - medieval: path.join(base, 'assets', 'generated', '02-medieval-origin.png'), - classes: path.join(base, 'assets', 'generated', '03-vampire-classes.png'), - failed: path.join(base, 'assets', 'generated', '04-failed-infection.png'), - recognize: path.join(base, 'assets', 'generated', '05-recognize-vampire.png'), - blood: path.join(base, 'assets', 'generated', '06-blood-economy.png'), - artificial: path.join(base, 'assets', 'generated', '07-artificial-blood.png'), - market: path.join(base, 'assets', 'generated', '08-hidden-donor-market.png'), - donorHouse: path.join(base, 'assets', 'generated', '09-donor-house.png'), - etiquette: path.join(base, 'assets', 'generated', '10-blood-etiquette.png'), - zones: path.join(base, 'assets', 'generated', '11-feeding-zones-map.png'), - chain: path.join(base, 'assets', 'generated', '12-food-chain-chart.png') + agent: path.join(base, 'assets', 'generated', 'ai-01-snv12-agent.png'), + medieval: path.join(base, 'assets', 'generated', 'ai-02-medieval-spread-map.png'), + classes: path.join(base, 'assets', 'generated', 'ai-03-vampire-classes.png'), + failed: path.join(base, 'assets', 'generated', 'ai-04-failed-infection.png'), + economy: path.join(base, 'assets', 'generated', 'ai-05-blood-economy.png'), + artificial: path.join(base, 'assets', 'generated', 'ai-06-live-vs-artificial-blood.png'), + market: path.join(base, 'assets', 'generated', 'ai-07-hidden-donor-market.png'), + zones: path.join(base, 'assets', 'generated', 'ai-08-feeding-zones-map.png') }; const pptx = new pptxgen(); pptx.layout = 'LAYOUT_WIDE'; pptx.author = 'Hermes Agent'; pptx.company = 'Nous Research'; -pptx.subject = 'Псевдонаучная теория о гемозависимой элите'; +pptx.subject = 'Строгая псевдонаучная модель гемозависимой элиты'; pptx.title = 'Пищевая цепочка: от тебя до теневого правительства'; pptx.lang = 'ru-RU'; pptx.theme = { - headFontFace: 'Georgia', + headFontFace: 'Aptos Display', bodyFontFace: 'Aptos', lang: 'ru-RU' }; const C = { - bgDark: '130B0D', - bgLight: 'F3EADF', - card: 'FFF7EE', - red: '7A1623', - red2: 'A42A37', - text: '24181A', - cream: 'F5E6D3', - gold: 'C7A56A', - muted: '705A5D', + bg: 'F7F9FC', white: 'FFFFFF', - ink: '2A1A1D', - brown: '4A3327' + ink: '1F2937', + muted: '667085', + line: 'CAD5E2', + blue: '245B8F', + blueSoft: 'EAF2FB', + red: 'B42318', + redSoft: 'FDECEC', + graySoft: 'EEF2F6', + dark: '102A43' }; function footer(slide, n, dark = false) { slide.addText(String(n).padStart(2, '0'), { - x: 12.42, y: 7.02, w: 0.4, h: 0.18, - fontSize: 10, color: dark ? 'B89B82' : C.muted, - align: 'right', margin: 0 + x: 12.48, + y: 7.02, + w: 0.36, + h: 0.18, + fontSize: 10, + color: dark ? 'D0DAE6' : C.muted, + align: 'right', + margin: 0 }); } -function baseTextSlide(slide, title, tag = 'Псевдонаучная реконструкция') { - slide.background = { color: C.bgLight }; - slide.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: 13.333, h: 0.42, fill: { color: C.red }, line: { color: C.red } }); - slide.addText(title, { x: 0.62, y: 0.58, w: 8.8, h: 0.38, fontFace: 'Georgia', fontSize: 26, bold: true, color: C.ink, margin: 0 }); - slide.addText(tag, { x: 10.0, y: 0.62, w: 2.65, h: 0.18, fontSize: 10, color: C.red2, italic: true, align: 'right', margin: 0 }); -} - -function addBullets(slide, items, opts = {}) { - const text = []; - items.forEach((item) => text.push({ text: item, options: { bullet: { indent: 14 }, breakLine: true } })); +function put(slide, text, x, y, w, h, opts = {}) { slide.addText(text, { - x: opts.x ?? 0.9, - y: opts.y ?? 1.6, - w: opts.w ?? 5.2, - h: opts.h ?? 4.4, - fontSize: opts.fontSize ?? 18, - color: opts.color ?? C.text, - paraSpaceAfterPt: opts.paraSpaceAfterPt ?? 8, - margin: 0.04, - valign: 'top' + x, y, w, h, + fontFace: opts.fontFace ?? 'Aptos', + fontSize: opts.fontSize ?? 14, + color: opts.color ?? C.ink, + bold: opts.bold ?? false, + italic: opts.italic ?? false, + align: opts.align ?? 'left', + valign: opts.valign ?? 'mid', + margin: opts.margin ?? 0.02, + breakLine: opts.breakLine ?? true }); } -function addCard(slide, x, y, w, h, title, body, accent = C.red2) { - slide.addShape(pptx.ShapeType.roundRect, { x, y, w, h, rectRadius: 0.06, fill: { color: C.card }, line: { color: accent, pt: 1.2 } }); - slide.addText(title, { x: x + 0.18, y: y + 0.16, w: w - 0.36, h: 0.24, fontSize: 17, bold: true, color: C.red, margin: 0 }); - slide.addText(body, { x: x + 0.18, y: y + 0.52, w: w - 0.36, h: h - 0.7, fontSize: 14.6, color: C.text, margin: 0.02, valign: 'mid' }); -} - -function addCallout(slide, text, opts = {}) { +function card(slide, x, y, w, h, title, body, opts = {}) { slide.addShape(pptx.ShapeType.roundRect, { - x: opts.x ?? 0.9, - y: opts.y ?? 5.82, - w: opts.w ?? 11.5, - h: opts.h ?? 0.58, + x, y, w, h, rectRadius: 0.05, - fill: { color: opts.fill ?? C.red }, - line: { color: opts.fill ?? C.red } + fill: { color: opts.fill ?? C.white }, + line: { color: opts.line ?? C.line, pt: opts.pt ?? 1.1 } }); - slide.addText(text, { - x: (opts.x ?? 0.9) + 0.14, - y: (opts.y ?? 5.82) + 0.13, - w: (opts.w ?? 11.5) - 0.28, - h: 0.23, - align: 'center', color: C.white, - fontSize: opts.fontSize ?? 20, - bold: true, italic: opts.italic ?? true, margin: 0 + if (title) { + put(slide, title, x + 0.18, y + 0.16, w - 0.36, 0.28, { + fontSize: opts.titleSize ?? 16, + bold: true, + color: opts.titleColor ?? C.ink + }); + } + if (body) { + put(slide, body, x + 0.18, y + (title ? 0.52 : 0.18), w - 0.36, h - (title ? 0.68 : 0.28), { + fontSize: opts.bodySize ?? 13.5, + color: opts.bodyColor ?? C.ink, + valign: opts.bodyValign ?? 'top', + margin: 0.04 + }); + } +} + +function pill(slide, x, y, w, h, text, opts = {}) { + slide.addShape(pptx.ShapeType.roundRect, { + x, y, w, h, + rectRadius: 0.08, + fill: { color: opts.fill ?? C.graySoft }, + line: { color: opts.line ?? C.graySoft, pt: 1 } }); + put(slide, text, x + 0.08, y + 0.05, w - 0.16, h - 0.1, { + fontSize: opts.fontSize ?? 12.5, + color: opts.color ?? C.ink, + bold: opts.bold ?? false, + align: opts.align ?? 'center' + }); +} + +function titleSlideBase(slide, title, subtitle) { + slide.background = { color: C.bg }; + put(slide, title, 0.9, 0.78, 6.1, 1.25, { fontSize: 28, bold: true, color: C.dark, margin: 0 }); + put(slide, subtitle, 0.92, 2.18, 6.3, 0.55, { fontSize: 16, color: C.muted, margin: 0 }); +} + +function textSlideBase(slide, title, kicker = 'Псевдонаучная реконструкция') { + slide.background = { color: C.bg }; + put(slide, title, 0.7, 0.52, 8.4, 0.42, { fontSize: 26, bold: true, color: C.dark, margin: 0 }); + put(slide, kicker, 10.05, 0.58, 2.55, 0.2, { fontSize: 10.5, color: C.blue, italic: true, align: 'right', margin: 0 }); } function fullImage(slide, imagePath) { - slide.background = { color: C.bgDark }; + slide.background = { color: C.white }; slide.addImage({ path: imagePath, x: 0, y: 0, w: 13.333, h: 7.5 }); } -function lightPlaque(slide, text, x, y, w, h, fontSize = 12, opts = {}) { - slide.addText(text, { - x, y, w, h, - fontFace: opts.fontFace ?? 'Georgia', - fontSize, - bold: opts.bold ?? false, - italic: opts.italic ?? false, - color: opts.color ?? C.brown, - align: opts.align ?? 'center', - valign: opts.valign ?? 'mid', - margin: opts.margin ?? 0.02, - breakLine: true - }); -} - -function darkPlaque(slide, text, x, y, w, h, fontSize = 12, opts = {}) { - slide.addText(text, { - x, y, w, h, - fontFace: opts.fontFace ?? 'Georgia', - fontSize, - bold: opts.bold ?? false, - italic: opts.italic ?? false, - color: opts.color ?? C.cream, - align: opts.align ?? 'center', - valign: opts.valign ?? 'mid', - margin: opts.margin ?? 0.02, - breakLine: true - }); -} - -// 1 title +// 1. title { const s = pptx.addSlide(); - fullImage(s, assets.title); - s.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: 13.333, h: 7.5, fill: { color: '120A0D', transparency: 34 }, line: { color: '120A0D', transparency: 100 } }); - s.addShape(pptx.ShapeType.roundRect, { x: 0.72, y: 0.82, w: 6.95, h: 5.25, rectRadius: 0.06, fill: { color: '1B1114', transparency: 15 }, line: { color: C.red2, pt: 1.1, transparency: 20 } }); - s.addText('Пищевая цепочка:\nот тебя до теневого правительства', { x: 1.0, y: 1.15, w: 6.3, h: 1.5, color: C.white, fontFace: 'Georgia', fontSize: 24, bold: true, margin: 0 }); - s.addText('Расширенная версия: типы вампиров,\nкачественная кровь и скрытый рынок доноров', { x: 1.04, y: 2.95, w: 6.0, h: 0.75, color: C.cream, fontSize: 17.5, italic: true, margin: 0 }); - s.addText('Клуб шапочек из фольги\nПсевдонаучный доклад в академическом стиле', { x: 1.04, y: 4.0, w: 4.9, h: 0.8, color: 'E0D0C4', fontSize: 16, margin: 0 }); - footer(s, 1, true); + titleSlideBase(s, + 'Пищевая цепочка:\nот тебя до теневого правительства', + 'Псевдонаучная модель гемозависимой элиты и скрытой инфраструктуры питания' + ); + + card(s, 0.92, 3.0, 5.25, 2.25, 'Исходная гипотеза', + 'Теневое правительство — это не только политическая сеть. В этой модели оно выступает как долгоживущая гемозависимая каста, которая превратила институты контроля в устойчивую систему отбора, хранения и распределения качественной человеческой крови.', + { fill: C.white, line: C.line, bodySize: 15, bodyValign: 'mid' } + ); + + card(s, 7.1, 1.2, 5.2, 4.95, 'Минимальная схема', '', { fill: C.white, line: C.line }); + pill(s, 7.6, 2.0, 1.1, 0.5, 'человек', { fill: C.blueSoft, line: C.blue, color: C.blue, bold: true }); + put(s, '→', 8.85, 2.08, 0.3, 0.2, { fontSize: 24, color: C.muted, align: 'center' }); + pill(s, 9.25, 2.0, 1.2, 0.5, 'отбор', { fill: C.graySoft, line: C.line, color: C.ink, bold: true }); + put(s, '→', 10.55, 2.08, 0.3, 0.2, { fontSize: 24, color: C.muted, align: 'center' }); + pill(s, 10.95, 2.0, 1.1, 0.5, 'кровь', { fill: C.redSoft, line: C.red, color: C.red, bold: true }); + put(s, '→', 8.85, 3.48, 0.3, 0.2, { fontSize: 24, color: C.muted, align: 'center' }); + pill(s, 9.25, 3.4, 2.05, 0.56, 'верхушка элиты', { fill: C.dark, line: C.dark, color: C.white, bold: true }); + put(s, 'долгожительство\nселекция\nскрытая логистика', 7.58, 4.28, 4.1, 0.95, { + fontSize: 16, + color: C.muted, + align: 'center' + }); + + put(s, 'Жанр: строгая псевдонаучная подача для клуба шапочек из фольги', 0.95, 6.55, 6.8, 0.22, { + fontSize: 12.5, + color: C.muted, + italic: true, + margin: 0 + }); + footer(s, 1); } -// 2 hypothesis +// 2. hypothesis { const s = pptx.addSlide(); - baseTextSlide(s, 'Гипотеза исследования'); - addCard(s, 0.88, 1.55, 5.35, 2.15, 'Базовая идея', 'Теневое правительство — это не просто политическая сеть, а долгоживущая гемозависимая каста, превратившая власть в механизм стабильного питания.'); - addBullets(s, [ - 'вирусное происхождение касты;', - 'долголетие как источник стратегического преимущества;', - 'кровь как ресурс, валюта и предмет селекции;', - 'власть как надстройка над пищевой цепочкой.' - ], { x: 7.05, y: 1.72, w: 5.0, h: 3.6, fontSize: 18 }); - addCallout(s, 'Ключевая формула: власть = контроль кормовой инфраструктуры'); + textSlideBase(s, 'Исходная гипотеза'); + card(s, 0.88, 1.45, 12.0, 1.2, + 'Тезис', + 'Элита не просто управляет обществом — она питается им, а долгожительство превращает биологическую зависимость в устойчивое политическое преимущество.', + { fill: C.white, line: C.blue, titleColor: C.blue, bodySize: 17, bodyValign: 'mid' } + ); + card(s, 0.88, 3.0, 2.75, 2.05, '1. Биология', 'Вампиризм интерпретируется как вирусная адаптация, а не мистическое проклятие.', { fill: C.redSoft, line: C.red }); + card(s, 3.85, 3.0, 2.75, 2.05, '2. Долголетие', 'Большой горизонт планирования даёт накопление власти, знаний и скрытых сетей.', { fill: C.blueSoft, line: C.blue }); + card(s, 6.82, 3.0, 2.75, 2.05, '3. Кровь как ресурс', 'Кровь одновременно еда, валюта, индикатор качества и объект селекции.', { fill: C.white, line: C.line }); + card(s, 9.79, 3.0, 3.09, 2.05, '4. Институты', 'Государства, клиники и элитные клубы работают как фасад для кормовой инфраструктуры.', { fill: C.white, line: C.line }); + pill(s, 1.7, 5.72, 9.9, 0.62, 'Ключевая формула: власть = контроль кормовой инфраструктуры', { fill: C.dark, line: C.dark, color: C.white, fontSize: 20, bold: true }); footer(s, 2); } -// 3 virus +// 3. biological agent { const s = pptx.addSlide(); - baseTextSlide(s, 'Sanguis Noctis Virus (SNV-12)'); - addBullets(s, [ - 'латентная вирус-индуцированная вампиризация;', - 'хроническая антропогематофагия;', - 'гемозависимый постчеловеческий синдром;', - 'обратимая фототолерантность после кормления.' - ], { x: 0.88, y: 1.7, w: 5.0, h: 3.8, fontSize: 18 }); - addCard(s, 6.8, 1.55, 5.3, 3.9, 'Ключевые эффекты', 'SNV-12 не делает человека мистическим существом мгновенно. Он перестраивает обменные пути, усиливает регенерацию, замедляет старение и формирует зависимость от человеческой крови как от носителя редких сигнальных молекул.'); - addCallout(s, 'Вампиризм здесь — не проклятие, а вирусная адаптация', { fill: C.red2 }); + fullImage(s, assets.agent); + put(s, 'Биологический агент: вирус, молекула и механизм действия', 0.62, 0.23, 11.98, 0.42, { + fontSize: 24, bold: true, color: C.dark, align: 'center' + }); + put(s, '1. Вирион SNV-12', 1.28, 1.3, 2.45, 0.26, { fontSize: 14, bold: true, color: C.red, align: 'center' }); + put(s, '2. Гемофильный регуляторный комплекс', 5.0, 1.3, 2.75, 0.26, { fontSize: 13.6, bold: true, color: C.red, align: 'center' }); + put(s, 'комплекс HEP + MitoX + Reg\nкоординирует метаболическую перестройку', 7.7, 2.46, 1.68, 0.78, { fontSize: 11, color: C.ink, align: 'center' }); + put(s, 'Связывание → эндоцитоз → выход РНК → внутриклеточный транспорт', 4.58, 5.9, 3.24, 0.34, { fontSize: 11.2, color: C.blue, align: 'center', bold: true }); + put(s, '3. Клеточные мишени и системные эффекты', 9.08, 1.3, 3.9, 0.26, { fontSize: 13.2, bold: true, color: C.red, align: 'center' }); + put(s, 'ROS↑,\nпотенциал↓', 8.42, 3.18, 1.35, 0.38, { fontSize: 10.5, color: C.red, align: 'center' }); + put(s, 'сдвиг\nметаболизма гема', 9.88, 3.18, 1.62, 0.38, { fontSize: 10.5, color: C.red, align: 'center' }); + put(s, 'ускорение\nрепарации тканей', 11.52, 3.18, 1.2, 0.38, { fontSize: 10.1, color: C.red, align: 'center' }); + put(s, 'сумеречное зрение\nи фоточувствительность', 8.42, 5.15, 1.34, 0.42, { fontSize: 9.8, color: C.blue, align: 'center' }); + put(s, 'лактатный сдвиг\nи экономия энергии', 11.52, 5.15, 1.16, 0.42, { fontSize: 9.8, color: C.blue, align: 'center' }); + put(s, 'Зависимость от донорской крови: сигналы донора → цитокины и факторы → гем и железо → гормоны и липиды → адаптация хозяина', 8.18, 6.05, 4.1, 0.28, { + fontSize: 10.2, color: C.blue, align: 'center', bold: true + }); + put(s, 'Рабочая гипотеза: вампиризм — результат вирусной перенастройки обмена, регенерации и светочувствительности.', 10.63, 6.75, 2.2, 0.48, { + fontSize: 10.2, color: C.muted, align: 'center' + }); footer(s, 3); } -// 4 medieval origin +// 4. medieval spread map { const s = pptx.addSlide(); fullImage(s, assets.medieval); - darkPlaque(s, 'XII–XIV века', 5.05, 0.38, 3.2, 0.34, 18, { bold: true }); - lightPlaque(s, 'войны и миграции', 1.18, 6.24, 2.25, 0.34, 12); - lightPlaque(s, 'антисанитария', 3.63, 6.24, 2.15, 0.34, 12); - lightPlaque(s, 'эпидемии и массовая смертность', 6.05, 6.24, 3.0, 0.34, 12); - lightPlaque(s, 'аристократические линии', 9.35, 6.24, 2.8, 0.34, 12); - darkPlaque(s, 'Средневековье создаёт идеальную среду для скрытого патогена', 2.55, 6.83, 8.2, 0.26, 16, { italic: true, bold: true }); - footer(s, 4, true); + put(s, 'Средневековье создаёт идеальную среду', 0.22, 0.28, 4.12, 0.34, { fontSize: 21, bold: true, color: C.dark, align: 'center' }); + put(s, 'XII–XIV века: торговля, миграции, войны и эпидемии', 0.22, 0.62, 4.12, 0.22, { fontSize: 11.2, color: C.muted, align: 'center' }); + put(s, 'Карта показывает не романтизированное Средневековье, а эпидемиологическую логику: плотные торговые сети и конфликтные зоны создают коридоры для скрытого распространения SNV-12.', 11.28, 5.55, 1.82, 1.34, { + fontSize: 10.4, color: C.ink, align: 'center', valign: 'mid' + }); + footer(s, 4); } -// 5 classes +// 5. physiological changes +{ + const s = pptx.addSlide(); + textSlideBase(s, 'Как вирус меняет организм'); + card(s, 0.88, 1.4, 3.88, 1.4, 'Кровяная среда', 'Норма: обычный транспорт кислорода.\nЗаражение: рост потребности в гем-сигналах.\nАдаптация: кровь становится носителем регуляторных факторов.', { fill: C.white, line: C.red }); + card(s, 4.95, 1.4, 3.88, 1.4, 'Обмен веществ', 'Норма: стандартный энергетический цикл.\nЗаражение: гиперметаболический стресс.\nАдаптация: экономичный режим и сдвиг к лактатной утилизации.', { fill: C.white, line: C.blue }); + card(s, 9.02, 1.4, 3.43, 1.4, 'Нервная система', 'Норма: стабильный базовый тонус.\nЗаражение: сенсорная перегрузка.\nАдаптация: фокус на сигналы риска и добычи.', { fill: C.white, line: C.line }); + card(s, 0.88, 3.15, 3.88, 1.4, 'Зрение и свет', 'Норма: дневная фототрансдукция.\nЗаражение: фоточувствительность и стресс.\nАдаптация: усиление сумеречного зрения ценой непереносимости яркого света.', { fill: C.white, line: C.blue }); + card(s, 4.95, 3.15, 3.88, 1.4, 'Регенерация', 'Норма: обычное заживление.\nЗаражение: воспалительный всплеск.\nАдаптация: ускоренная репарация тканей и выживание после травм.', { fill: C.white, line: C.red }); + card(s, 9.02, 3.15, 3.43, 1.4, 'Старение', 'Норма: обычный клеточный цикл.\nЗаражение: сильная нагрузка на ткани.\nАдаптация: замедленное старение и накопление опыта.', { fill: C.white, line: C.line }); + card(s, 0.88, 5.08, 11.98, 1.08, 'Переход к симптомам', 'Именно эта системная перестройка далее объясняет четыре наблюдаемых свойства: питание кровью, чувствительность к солнечному свету, быстрое восстановление и долговременное биологическое долголетие.', { fill: C.dark, line: C.dark, titleColor: C.white, bodyColor: 'EAF2FB', bodySize: 15, bodyValign: 'mid' }); + footer(s, 5); +} + +// 6. dependency on blood +{ + const s = pptx.addSlide(); + textSlideBase(s, 'Почему возникает зависимость от крови'); + pill(s, 0.92, 2.1, 2.25, 0.9, '1. Вирус требует\nживые сигнальные молекулы', { fill: C.redSoft, line: C.red, color: C.red, bold: true, fontSize: 15 }); + put(s, '→', 3.3, 2.34, 0.4, 0.2, { fontSize: 28, color: C.muted, align: 'center' }); + pill(s, 3.82, 2.1, 2.25, 0.9, '2. Донорская кровь несёт\nцитокины, гормоны и стресс-маркеры', { fill: C.blueSoft, line: C.blue, color: C.blue, bold: true, fontSize: 14.2 }); + put(s, '→', 6.22, 2.34, 0.4, 0.2, { fontSize: 28, color: C.muted, align: 'center' }); + pill(s, 6.72, 2.1, 2.25, 0.9, '3. Искусственный суррогат\nсохраняет транспорт, но не сигналы', { fill: C.graySoft, line: C.line, color: C.ink, bold: true, fontSize: 14.2 }); + put(s, '→', 9.12, 2.34, 0.4, 0.2, { fontSize: 28, color: C.muted, align: 'center' }); + pill(s, 9.62, 2.1, 2.75, 0.9, '4. Голод = дефицит регуляторных\nкомпонентов, а не просто калорий', { fill: C.dark, line: C.dark, color: C.white, bold: true, fontSize: 14.2 }); + card(s, 1.15, 4.0, 3.45, 1.25, 'Живая кровь', 'Биохимический пакет с вариативностью, метаболической активностью и поведенческим следом донора.', { fill: C.white, line: C.red }); + card(s, 5.0, 4.0, 3.45, 1.25, 'Искусственная кровь', 'Полезна как транспортная среда, но слишком стерильна и бедна на активные сигналы.', { fill: C.white, line: C.blue }); + card(s, 8.85, 4.0, 3.45, 1.25, 'Следствие', 'Отсюда возникает селекция по качеству, ритуалы допуска и рынок дефицитных доноров.', { fill: C.white, line: C.line }); + footer(s, 6); +} + +// 7. classes { const s = pptx.addSlide(); fullImage(s, assets.classes); - lightPlaque(s, 'нестабилен, часто голоден', 0.45, 5.93, 3.42, 0.4, 12); - lightPlaque(s, 'контроль только формируется', 0.45, 6.36, 3.42, 0.38, 11.5); - lightPlaque(s, 'устойчив, скрытен, дисциплинирован', 4.62, 5.93, 3.42, 0.4, 11.6); - lightPlaque(s, 'столетнее накопление опыта', 4.62, 6.36, 3.42, 0.38, 11.3); - lightPlaque(s, 'редкое питание, максимальная селекция', 8.95, 5.93, 3.45, 0.4, 11.3); - lightPlaque(s, 'биологическая верхушка касты', 8.95, 6.36, 3.45, 0.38, 11.5); - footer(s, 5, true); + put(s, 'Классы вампирической адаптации', 0.88, 0.3, 11.6, 0.36, { fontSize: 22, bold: true, color: C.dark, align: 'center' }); + put(s, 'Чем выше класс, тем больше контроль голода, доступ к качественной крови и политическое влияние.', 0.3, 6.9, 12.7, 0.24, { fontSize: 11.5, color: C.muted, align: 'center' }); + footer(s, 7); } -// 6 failed infection +// 8. failed infection { const s = pptx.addSlide(); fullImage(s, assets.failed); - lightPlaque(s, 'объект: носитель SNV-12\nс несовместимым фенотипом', 0.52, 0.8, 3.47, 1.16, 12.5, { bold: true }); - lightPlaque(s, 'сосудистый\nперегрев', 4.48, 1.74, 0.78, 0.28, 10.8); - lightPlaque(s, 'гемолиз', 4.47, 2.7, 0.78, 0.28, 10.8); - lightPlaque(s, 'системный\nколлапс', 4.47, 3.54, 0.78, 0.3, 10.5); - lightPlaque(s, 'рост температуры\nдо критического порога', 1.2, 4.0, 2.8, 0.28, 10.8); - lightPlaque(s, 'утрата стабильности\nкровяной среды', 0.9, 6.05, 3.1, 0.38, 12); - lightPlaque(s, 'Неудачное обращение объясняется\nтермогемолитическим коллапсом.', 4.35, 5.45, 3.8, 1.1, 13, { bold: true }); - footer(s, 6, true); + put(s, 'Неудачное заражение: каскад несовместимости', 1.1, 0.28, 11.1, 0.36, { fontSize: 22, bold: true, color: C.dark, align: 'center' }); + put(s, 'нейровегетативный\nсбой', 3.6, 1.78, 1.44, 0.44, { fontSize: 11.2, color: C.blue, align: 'center' }); + put(s, 'кардиореспираторный\nстресс', 3.57, 2.92, 1.5, 0.44, { fontSize: 11.2, color: C.blue, align: 'center' }); + put(s, 'абдоминальный\nсосудистый криз', 3.58, 4.12, 1.48, 0.44, { fontSize: 11.0, color: C.blue, align: 'center' }); + put(s, 'периферический\nспазм', 3.58, 5.33, 1.48, 0.4, { fontSize: 11.0, color: C.blue, align: 'center' }); + put(s, 'терминальное\nистощение', 3.58, 6.42, 1.48, 0.4, { fontSize: 11.0, color: C.blue, align: 'center' }); + put(s, 'генетическая и иммунная\nнесовместимость', 7.62, 1.7, 4.66, 0.42, { fontSize: 12.2, color: C.red, align: 'center', bold: true }); + put(s, 'сосудистый перегрев\nи гиперметаболизм', 7.62, 3.0, 4.66, 0.42, { fontSize: 12.2, color: C.red, align: 'center', bold: true }); + put(s, 'массовый гемолиз\nи высвобождение гема', 7.62, 4.25, 4.66, 0.42, { fontSize: 12.2, color: C.red, align: 'center', bold: true }); + put(s, 'воспалительный каскад\nи токсическая перегрузка', 7.62, 5.46, 4.66, 0.42, { fontSize: 12.2, color: C.red, align: 'center', bold: true }); + put(s, 'системный коллапс\nбез устойчивой адаптации', 7.62, 6.65, 4.66, 0.42, { fontSize: 12.2, color: C.red, align: 'center', bold: true }); + footer(s, 8); } -// 7 recognize vampire +// 9. recognition slide built in ppt { const s = pptx.addSlide(); - fullImage(s, assets.recognize); - lightPlaque(s, 'слегка увеличенные\nклыки', 0.42, 2.06, 2.38, 0.46, 12.4); - lightPlaque(s, 'медленное\nстарение', 0.42, 3.58, 2.38, 0.46, 12.4); - lightPlaque(s, 'слишком ровная\nкожа', 0.42, 5.14, 2.38, 0.46, 12.2); - lightPlaque(s, 'тёмный расширенный\nзрачок', 10.53, 2.06, 2.38, 0.46, 12.2); - lightPlaque(s, 'интерес к крови\nи травмам', 10.53, 3.58, 2.38, 0.46, 12.2); - lightPlaque(s, 'закрытые клубы\nи тайные круги', 10.53, 5.14, 2.38, 0.46, 12.0); - footer(s, 7, true); + textSlideBase(s, 'Как распознать вампира'); + card(s, 4.45, 1.55, 4.45, 4.4, 'Гемозависимый фенотип', 'Наблюдаемая форма — это не «монстр из мифа», а человек с устойчивыми физиологическими и поведенческими отклонениями, которые становятся заметны в фазах голода, отбора и социальной маскировки.', { fill: C.white, line: C.blue, bodySize: 16, bodyValign: 'mid' }); + card(s, 0.86, 1.55, 3.1, 1.06, 'Внешний маркер 1', 'слегка увеличенные клыки', { fill: C.redSoft, line: C.red, bodySize: 14.5 }); + card(s, 0.86, 2.82, 3.1, 1.06, 'Внешний маркер 2', 'медленное старение и слишком ровная кожа', { fill: C.redSoft, line: C.red, bodySize: 14.2 }); + card(s, 0.86, 4.09, 3.1, 1.06, 'Внешний маркер 3', 'расширенный тёмный зрачок в фазе голода', { fill: C.redSoft, line: C.red, bodySize: 14.2 }); + card(s, 9.33, 1.55, 3.14, 1.06, 'Поведение 1', 'фиксация на крови, травмах и медицинских темах', { fill: C.blueSoft, line: C.blue, bodySize: 14.2 }); + card(s, 9.33, 2.82, 3.14, 1.06, 'Поведение 2', 'тяга к закрытым элитным кругам и ритуалам допуска', { fill: C.blueSoft, line: C.blue, bodySize: 14.2 }); + card(s, 9.33, 4.09, 3.14, 1.06, 'Поведение 3', 'необычная дисциплина питания и контроля среды', { fill: C.blueSoft, line: C.blue, bodySize: 14.2 }); + pill(s, 1.62, 6.15, 10.0, 0.56, 'Один признак ничего не доказывает; показательна именно устойчивая комбинация физиологии, голода и социального поведения.', { fill: C.dark, line: C.dark, color: C.white, fontSize: 16, bold: true }); + footer(s, 9); } -// 8 blood economy +// 10. blood economy { const s = pptx.addSlide(); - fullImage(s, assets.blood); - lightPlaque(s, 'базовое\nподдержание', 1.26, 1.84, 2.05, 0.36, 12.2); - lightPlaque(s, 'норма для\nпериферии', 1.26, 3.33, 2.05, 0.36, 12.2); - lightPlaque(s, 'усиление\nспособностей', 1.26, 4.82, 2.05, 0.36, 12.0); - lightPlaque(s, 'ресурс для элиты\nи ритуалов', 1.26, 6.3, 2.05, 0.36, 11.6); - lightPlaque(s, 'минимальные\nтребования', 10.16, 2.0, 1.62, 0.28, 10.4); - lightPlaque(s, 'устойчивый\nрацион', 10.16, 3.48, 1.62, 0.28, 10.4); - lightPlaque(s, 'для старших\nадаптантов', 10.16, 4.98, 1.62, 0.28, 10.2); - lightPlaque(s, 'только для\nдревних', 10.16, 6.47, 1.62, 0.28, 10.2); - lightPlaque(s, 'дефицит создаёт власть', 0.78, 6.72, 2.2, 0.24, 11.2, { bold: true }); - lightPlaque(s, 'чем старше древний,\nтем выше требования', 10.38, 6.72, 2.2, 0.34, 10.5, { bold: true }); - footer(s, 8, true); + fullImage(s, assets.economy); + put(s, 'Экономика качественной крови', 0.42, 0.32, 12.48, 0.34, { fontSize: 22, bold: true, color: C.dark, align: 'center' }); + put(s, 'Массовая кровь поддерживает периферию; пиковая и династическая питают верхушку и ритуалы.', 0.45, 6.3, 4.3, 0.8, { fontSize: 11.3, color: C.muted, align: 'center' }); + put(s, 'Чем древнее адаптант, тем выше требования к сигнальному профилю донора и тем уже доступ.', 5.05, 6.3, 4.3, 0.8, { fontSize: 11.3, color: C.muted, align: 'center' }); + footer(s, 10); } -// 9 artificial blood +// 11. live vs artificial blood { const s = pptx.addSlide(); fullImage(s, assets.artificial); - lightPlaque(s, 'высокая\nвариативность', 4.78, 1.58, 1.55, 0.28, 10.2); - lightPlaque(s, 'выражены', 4.78, 2.54, 1.55, 0.28, 10.2); - lightPlaque(s, 'уникален', 4.78, 3.48, 1.55, 0.28, 10.2); - lightPlaque(s, 'активна', 4.78, 4.42, 1.55, 0.28, 10.2); - lightPlaque(s, 'есть', 4.78, 5.47, 1.55, 0.28, 10.2); - lightPlaque(s, 'полное', 4.78, 6.33, 1.55, 0.28, 10.2); - lightPlaque(s, 'сглажен', 10.2, 1.58, 1.55, 0.28, 10.2); - lightPlaque(s, 'почти нет', 10.2, 2.54, 1.55, 0.28, 10.2); - lightPlaque(s, 'стёрт', 10.2, 3.48, 1.55, 0.28, 10.2); - lightPlaque(s, 'низкая', 10.2, 4.42, 1.55, 0.28, 10.2); - lightPlaque(s, 'нет', 10.2, 5.47, 1.55, 0.28, 10.2); - lightPlaque(s, 'минимальное', 10.2, 6.33, 1.55, 0.28, 10.2); - footer(s, 9, true); + put(s, 'Почему искусственная кровь не подходит', 1.78, 0.2, 9.8, 0.34, { fontSize: 22, bold: true, color: C.dark, align: 'center' }); + put(s, 'вариативность\nсигналов', 0.24, 3.15, 2.05, 0.38, { fontSize: 10.8, color: C.red, align: 'center' }); + put(s, 'активная\nнейрохимия', 0.24, 4.16, 2.05, 0.38, { fontSize: 10.8, color: C.red, align: 'center' }); + put(s, 'иммунный\nотклик', 0.24, 5.18, 2.05, 0.38, { fontSize: 10.8, color: C.red, align: 'center' }); + put(s, 'эффект\nнасыщения', 0.24, 6.2, 2.05, 0.38, { fontSize: 10.8, color: C.red, align: 'center' }); + put(s, 'сигналы\nсглажены', 11.0, 3.15, 2.05, 0.38, { fontSize: 10.8, color: C.blue, align: 'center' }); + put(s, 'подпись\nстёрта', 11.0, 4.16, 2.05, 0.38, { fontSize: 10.8, color: C.blue, align: 'center' }); + put(s, 'ответ\nнизкий', 11.0, 5.18, 2.05, 0.38, { fontSize: 10.8, color: C.blue, align: 'center' }); + put(s, 'сытости\nнет', 11.0, 6.2, 2.05, 0.38, { fontSize: 10.8, color: C.blue, align: 'center' }); + put(s, 'Живая кровь даёт вариативный биохимический пакет: гормоны, стресс-маркеры, активный метаболизм и индивидуальный нейрохимический след.', 0.2, 6.7, 5.7, 0.48, { + fontSize: 11.4, color: C.red, align: 'center', bold: true + }); + put(s, 'Искусственный суррогат сохраняет транспортную функцию, но слишком стерилен и не вызывает полноценного насыщения.', 7.48, 6.7, 5.7, 0.48, { + fontSize: 11.4, color: C.blue, align: 'center', bold: true + }); + footer(s, 11); } -// 10 hidden donor market +// 12. hidden donor market { const s = pptx.addSlide(); fullImage(s, assets.market); - darkPlaque(s, 'Тайный рынок доноров', 5.35, 2.06, 2.1, 0.28, 16, { bold: true }); - darkPlaque(s, 'Элитные\nшколы', 0.95, 1.95, 1.35, 0.26, 10.6); - darkPlaque(s, 'Закрытые\nклубы', 2.78, 1.95, 1.35, 0.26, 10.6); - darkPlaque(s, 'Донорские\nдома', 9.0, 1.95, 1.48, 0.26, 10.4); - darkPlaque(s, 'Династии', 10.85, 1.95, 1.45, 0.26, 10.6); - darkPlaque(s, 'Клиники', 0.75, 4.13, 1.9, 0.22, 10.8); - darkPlaque(s, 'Медицинский\nотбор', 2.95, 4.13, 1.9, 0.22, 10.0); - lightPlaque(s, 'лаунджи для\nудержания доноров', 5.55, 4.88, 2.42, 0.34, 10.5); - darkPlaque(s, 'Биобанки', 9.02, 4.13, 1.9, 0.22, 10.8); - darkPlaque(s, 'Архивы и\nдосье', 11.18, 4.13, 1.72, 0.22, 10.0); - darkPlaque(s, 'доноры', 0.62, 6.86, 1.05, 0.2, 9.8); - darkPlaque(s, 'анкеты', 2.62, 6.86, 1.05, 0.2, 9.8); - darkPlaque(s, 'отбор', 4.83, 6.86, 1.05, 0.2, 9.8); - darkPlaque(s, 'пробирки', 6.93, 6.86, 1.05, 0.2, 9.8); - darkPlaque(s, 'архив', 9.13, 6.86, 1.05, 0.2, 9.8); - darkPlaque(s, 'сердце рынка', 11.28, 6.86, 1.18, 0.2, 9.4); - footer(s, 10, true); + put(s, 'Тайный рынок доноров', 0.28, 0.18, 12.75, 0.36, { fontSize: 22, bold: true, color: C.dark, align: 'center' }); + put(s, 'Критический поток идёт от источников и донорских домов к сортировке, биобанкам и узлам доставки. Бутылочные горлышки — пропускная способность, холодовая цепь и безопасность маршрутов. Система работает как дисциплинированная логистическая сеть, а не как хаотичный чёрный рынок.', 9.52, 5.85, 3.1, 1.0, { + fontSize: 10.8, color: C.ink, align: 'left', valign: 'top' + }); + footer(s, 12); } -// 11 donor house -{ - const s = pptx.addSlide(); - fullImage(s, assets.donorHouse); - darkPlaque(s, 'Донорский дом', 0.82, 0.52, 4.95, 0.4, 22, { bold: true }); - darkPlaque(s, 'санаторий, пансион и селекционный узел\nпод одной крышей', 0.92, 1.0, 4.7, 0.44, 12.8, { italic: true }); - darkPlaque(s, 'отбор', 7.15, 6.52, 1.1, 0.22, 10.5); - darkPlaque(s, 'обучение', 9.26, 6.52, 1.1, 0.22, 10.5); - darkPlaque(s, 'медицина', 11.32, 6.52, 1.1, 0.22, 10.5); - darkPlaque(s, 'селекция', 12.45, 6.52, 0.65, 0.22, 9.5); - footer(s, 11, true); -} - -// 12 blood etiquette -{ - const s = pptx.addSlide(); - fullImage(s, assets.etiquette); - lightPlaque(s, 'Кровяной этикет элиты', 3.95, 0.42, 5.38, 0.42, 22, { bold: true }); - darkPlaque(s, 'оценка донора', 3.05, 6.86, 2.05, 0.22, 11.2, { bold: true }); - darkPlaque(s, 'ритуал насыщения', 5.36, 6.86, 2.3, 0.22, 11.2, { bold: true }); - darkPlaque(s, 'учёт качества', 7.96, 6.86, 2.1, 0.22, 11.2, { bold: true }); - darkPlaque(s, 'документы допуска', 10.45, 6.86, 2.15, 0.22, 10.6, { bold: true }); - footer(s, 12, true); -} - -// 13 feeding zones +// 13. feeding zones map { const s = pptx.addSlide(); fullImage(s, assets.zones); - lightPlaque(s, 'Геополитика кормовых зон', 3.62, 0.34, 5.9, 0.34, 20, { bold: true }); - lightPlaque(s, 'резервуары\nнаселения', 0.68, 3.62, 1.8, 0.26, 10.4); - lightPlaque(s, 'морские\nкоридоры', 0.68, 4.07, 1.8, 0.26, 10.4); - lightPlaque(s, 'авиационные\nузлы', 0.68, 4.53, 1.8, 0.26, 10.2); - lightPlaque(s, 'убежища\nэлиты', 0.68, 4.99, 1.8, 0.26, 10.4); - lightPlaque(s, 'эксперименты\nи селекция', 0.68, 5.45, 1.8, 0.26, 10.0); - lightPlaque(s, 'карта показывает не государства,\nа контуры биологического снабжения', 4.72, 6.88, 3.95, 0.36, 11.6, { bold: true }); - footer(s, 13, true); + put(s, 'Геополитика кормовых зон', 1.02, 0.18, 10.6, 0.34, { fontSize: 22, bold: true, color: C.dark, align: 'center' }); + put(s, 'Карта показывает не государства, а контуры биологического снабжения: резервуары населения, коридоры доставки, безопасные зоны элиты и территории управляемых экспериментов.', 11.18, 5.2, 1.74, 1.2, { + fontSize: 10.2, color: C.ink, align: 'center' + }); + footer(s, 13); } -// 14 food chain chart +// 14. consequences matrix { const s = pptx.addSlide(); - fullImage(s, assets.chain); - lightPlaque(s, 'Пищевая цепочка: от тебя до теневого правительства', 1.82, 0.28, 9.72, 0.34, 17.5, { bold: true }); - darkPlaque(s, 'человек', 0.32, 1.8, 1.48, 0.2, 10.2); - darkPlaque(s, 'наблюдение', 2.45, 1.8, 1.48, 0.2, 10.2); - darkPlaque(s, 'сортировка', 4.64, 1.8, 1.48, 0.2, 10.2); - darkPlaque(s, 'логистика', 6.82, 1.8, 1.48, 0.2, 10.2); - darkPlaque(s, 'встреча\nэлиты', 9.02, 1.8, 1.48, 0.2, 9.8); - darkPlaque(s, 'досье', 11.18, 1.8, 1.48, 0.2, 10.2); - darkPlaque(s, 'гемарх', 12.08, 1.8, 0.95, 0.2, 10.0); - lightPlaque(s, 'массовая\nдонорская база', 0.33, 4.92, 1.7, 0.42, 10.3); - lightPlaque(s, 'отбор по\nбиометрии', 4.0, 6.16, 1.85, 0.3, 10.2); - lightPlaque(s, 'качество важнее\nколичества', 7.67, 6.16, 1.95, 0.3, 10.0); - lightPlaque(s, 'верхушка\nспроса', 11.32, 4.92, 1.6, 0.42, 10.4); - footer(s, 14, true); + textSlideBase(s, 'Следствия: почему вампиры именно такие'); + card(s, 0.92, 1.5, 5.8, 0.62, 'Биомеханизм', '', { fill: C.dark, line: C.dark, titleColor: C.white }); + card(s, 6.82, 1.5, 5.58, 0.62, 'Наблюдаемое следствие', '', { fill: C.red, line: C.red, titleColor: C.white }); + const left = [ + 'дефицит сигнальных молекул', + 'изменённые фоторецепторные пути', + 'усиленная регенеративная сигнализация', + 'перестройка клеточного цикла', + 'хронический голодный стресс', + 'высокая цена качественной крови' + ]; + const right = [ + 'питание кровью и отказ от стерильных суррогатов', + 'чувствительность к яркому солнечному свету', + 'быстрое восстановление после травм', + 'замедленное старение и накопление опыта', + 'ритуалы отбора, дисциплина и иерархия доступа', + 'скрытая политика, элитные сети и рынок доноров' + ]; + for (let i = 0; i < left.length; i += 1) { + const y = 2.35 + i * 0.7; + card(s, 0.92, y, 5.8, 0.56, '', left[i], { fill: C.white, line: C.line, bodySize: 13.3, bodyValign: 'mid' }); + card(s, 6.82, y, 5.58, 0.56, '', right[i], { fill: C.white, line: C.line, bodySize: 13.3, bodyValign: 'mid' }); + } + footer(s, 14); } -// 15 conclusion +// 15. conclusion { const s = pptx.addSlide(); - s.background = { color: C.bgDark }; - s.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: 13.333, h: 7.5, fill: { color: C.bgDark }, line: { color: C.bgDark } }); - s.addText('Вывод', { x: 0.92, y: 0.92, w: 3.0, h: 0.5, color: C.white, fontFace: 'Georgia', fontSize: 28, bold: true, margin: 0 }); - s.addText('Если теория верна, вершина мировой политики — это не кабинет и не трон, а хорошо организованная столовая премиум-класса, где человечество давно числится в меню.', { x: 0.95, y: 2.0, w: 8.15, h: 1.9, fontSize: 24, color: C.cream, margin: 0.02, valign: 'mid' }); - s.addShape(pptx.ShapeType.roundRect, { x: 9.15, y: 1.6, w: 2.85, h: 3.4, rectRadius: 0.08, fill: { color: '2A1419' }, line: { color: C.gold, pt: 1.3 } }); - s.addText('Ключевые\nформулы', { x: 9.72, y: 2.0, w: 1.75, h: 0.6, align: 'center', fontSize: 20, bold: true, color: C.white, margin: 0 }); - s.addText('• власть = кормовая логистика\n• кровь = валюта\n• элита скрывает не власть, а рацион', { x: 9.45, y: 2.9, w: 2.25, h: 1.25, fontSize: 15.5, color: C.cream, margin: 0.02 }); - s.addText('Жанр: академически поданная псевдонаука для клуба шапочек из фольги', { x: 1.0, y: 6.45, w: 7.4, h: 0.22, fontSize: 13, color: 'D2B8A5', italic: true, margin: 0 }); + s.background = { color: C.dark }; + put(s, 'Вывод', 0.95, 0.92, 2.5, 0.42, { fontSize: 28, bold: true, color: C.white, margin: 0 }); + put(s, + 'Если теория верна, то вершина мировой политики — это не кабинет и не трон, а хорошо организованная биологическая инфраструктура, где власть определяется устойчивым доступом к качественной крови.', + 0.95, 2.0, 7.35, 1.55, + { fontSize: 23, color: 'EAF2FB', margin: 0.02, valign: 'mid' } + ); + card(s, 9.0, 1.7, 3.15, 3.4, 'Ключевые формулы', '• вампиризм = биологическая зависимость + социальная инфраструктура\n\n• власть = устойчивый доступ к качественной крови\n\n• миф о монстре скрывает проблему системы снабжения', { + fill: '16324F', + line: '7FA6C9', + titleColor: C.white, + bodyColor: 'EAF2FB', + bodySize: 15, + bodyValign: 'mid' + }); + put(s, 'Жанр: строго стилизованная псевдонаука для клуба шапочек из фольги', 0.98, 6.48, 6.9, 0.2, { fontSize: 12.5, color: 'B8C7D9', italic: true, margin: 0 }); footer(s, 15, true); } @@ -372,4 +402,4 @@ async function main() { main().catch((err) => { console.error(err.stack || err.message || String(err)); process.exit(1); -}); +}); \ No newline at end of file diff --git a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf index ea9e546..97ae25c 100644 Binary files a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf and b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pdf differ diff --git a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx index 034daf8..b611be6 100644 Binary files a/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx and b/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.pptx differ diff --git a/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png b/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png index 2e8fa59..883d06e 100644 Binary files a/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png and b/rendered_check/prezentaciya-vampiricheskoe-tenevoe-pravitelstvo.png differ diff --git a/verify.js b/verify.js index ba4759c..74dedef 100644 --- a/verify.js +++ b/verify.js @@ -24,11 +24,12 @@ async function main() { const report = fs.readFileSync(reportPath, 'utf8'); const handout = fs.readFileSync(handoutPath, 'utf8'); const generator = fs.readFileSync(generatorPath, 'utf8'); + assert(report.includes('Sanguis Noctis Virus'), 'В докладе отсутствует ключевой термин'); assert(report.includes('Экономика качественной крови'), 'В докладе нет раздела о качественной крови'); assert(report.includes('Почему искусственная кровь им не подходит'), 'В докладе нет раздела про искусственную кровь'); assert(handout.includes('Тайный рынок доноров'), 'В раздатке нет блока про тайный рынок доноров'); - assert(generator.includes("12-food-chain-chart.png") && generator.includes("assets', 'generated'"), 'Генератор не использует пакет generated PNG'); + assert(generator.includes('ai-01-snv12-agent.png') && generator.includes('ai-08-feeding-zones-map.png'), 'Генератор не использует новый набор scientific PNG'); const pptxBuf = fs.readFileSync(pptxPath); const zip = await JSZip.loadAsync(pptxBuf); @@ -38,10 +39,13 @@ async function main() { assert(slideFiles.length === 15, `Ожидалось 15 слайдов, получено ${slideFiles.length}`); const firstSlide = await zip.files[slideFiles[0]].async('string'); - const chainSlide = await zip.files[slideFiles[13]].async('string'); + const agentSlide = await zip.files[slideFiles[2]].async('string'); + const marketSlide = await zip.files[slideFiles[11]].async('string'); const lastSlide = await zip.files[slideFiles[slideFiles.length - 1]].async('string'); + assert(firstSlide.includes('Пищевая цепочка:'), 'На первом слайде нет заголовка'); - assert(chainSlide.includes('Пищевая цепочка: от тебя до теневого правительства'), 'На слайде пищевой цепочки нет подписанного изображения'); + assert(agentSlide.includes('SNV-12'), 'На биологическом слайде нет SNV-12'); + assert(marketSlide.includes('Тайный рынок доноров'), 'На слайде рынка доноров нет заголовка'); assert(lastSlide.includes('Вывод'), 'На последнем слайде нет слайда с выводом'); try { @@ -67,4 +71,4 @@ async function main() { main().catch((err) => { console.error(err.stack || err.message || String(err)); process.exit(1); -}); +}); \ No newline at end of file