sozday-analiz-rashodov-s-uka/presentation.html

478 lines
31 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Оптимизация расходов — презентация</title>
<script src="https://cdn.jsdelivr.net/npm/pptxgenjs@3.12.0/dist/pptxgen.bundle.js"></script>
<style>
* { margin: 0; box-sizing: border-box; }
body { font-family: "Segoe UI", "Roboto", "Helvetica Neue", -apple-system, sans-serif; background: #0D1B2A; color: #F0F4F8; }
.slide { display: none; min-height: 100vh; padding: 7vh 8vw; flex-direction: column; justify-content: flex-start; }
.slide.on { display: flex; }
.slide h1 { font-size: clamp(28px, 4.6vw, 54px); margin-bottom: 20px; line-height: 1.15; letter-spacing: -.01em; font-weight: 600; color: #F0F4F8; }
.slide .accent { color: #8EAEC8; }
.slide .kpi-row { display: flex; gap: 14px; flex-wrap: wrap; margin: 18px 0 14px; }
.slide .kpi { flex: 1 1 180px; background: #142433; border: 1px solid #1B4F72; border-radius: 10px; padding: 14px 16px; min-width: 160px; }
.slide .kpi .num { font-size: clamp(22px, 3.4vw, 36px); font-weight: 700; color: #8EAEC8; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1; }
.slide .kpi .lbl { font-size: clamp(11px, 1.4vw, 14px); color: #8899A6; margin-top: 6px; line-height: 1.35; }
.slide .kpi.warn .num { color: #D4680A; }
.slide .kpi.risk .num { color: #C0392B; }
.slide .kpi.ok .num { color: #1A7F4B; }
.slide ul { list-style: none; margin: 14px 0; display: flex; flex-direction: column; gap: 12px; }
.slide li { font-size: clamp(15px, 2vw, 22px); line-height: 1.55; padding-left: 28px; position: relative; color: #F0F4F8; }
.slide li::before { content: ""; position: absolute; left: 0; top: .55em; width: 10px; height: 10px; border-radius: 3px; background: #8EAEC8; }
.slide li::after { display: none; }
.slide li.sub { font-size: clamp(12px, 1.5vw, 16px); color: #8899A6; padding-left: 46px; line-height: 1.5; }
.slide li.sub::before { width: 6px; height: 6px; border-radius: 50%; background: #3A5A70; top: .65em; left: 18px; }
.slide table { width: 100%; border-collapse: collapse; font-size: clamp(11px, 1.5vw, 15px); margin-top: 10px; }
.slide th { text-align: left; padding: 8px 10px; background: #142433; color: #8899A6; font-weight: 600; font-size: clamp(10px, 1.3vw, 13px); text-transform: uppercase; letter-spacing: .04em; border-bottom: 1px solid #1B4F72; }
.slide th.ta-r { text-align: right; }
.slide td { padding: 8px 10px; border-bottom: 1px solid #1E3A52; color: #E8F0F8; font-variant-numeric: tabular-nums; vertical-align: top; }
.slide td.ta-r { text-align: right; }
.slide .pos { color: #C0392B; font-weight: 600; }
.slide .neg { color: #1A7F4B; font-weight: 600; }
.slide .dim { color: #6C8FA8; }
.slide .note { font-size: clamp(11px, 1.4vw, 14px); color: #8899A6; margin-top: 14px; line-height: 1.45; }
.slide .footer { margin-top: auto; padding-top: 18px; font-size: 12px; color: #6C8FA8; display: flex; gap: 18px; flex-wrap: wrap; }
.slide .footer .sep { width: 4px; height: 4px; border-radius: 50%; background: #3A5A70; align-self: center; }
.num-page { position: fixed; bottom: 18px; right: 22px; color: #6C8FA8; font-size: 13px; font-variant-numeric: tabular-nums; }
.nav { position: fixed; bottom: 14px; left: 22px; display: flex; gap: 8px; z-index: 10; }
.nav button { border: 1px solid #1B4F72; background: #142433; color: #F0F4F8; border-radius: 8px; padding: 8px 14px; cursor: pointer; font-size: 14px; transition: background .15s; }
.nav button:hover { background: #1E3A52; }
.nav .pptx { border-color: #8EAEC8; color: #8EAEC8; }
.nav .pptx:hover { background: #1B4F72; }
.title-slide { justify-content: center; }
.title-slide h0 { font-size: clamp(36px, 6vw, 72px); font-weight: 600; line-height: 1.1; margin-bottom: 12px; letter-spacing: -.02em; }
.title-slide h2 { font-size: clamp(18px, 2.4vw, 28px); color: #8899A6; font-weight: 400; margin-bottom: 30px; line-height: 1.35; max-width: 80ch; }
.title-slide .badge { display: inline-block; background: #142433; border: 1px solid #1B4F72; color: #8EAEC8; padding: 4px 12px; border-radius: 20px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 22px; }
@media print {
.nav, .num-page { display: none; }
.slide { display: flex; page-break-after: always; min-height: 100vh; }
}
</style>
</head>
<body>
<div id="deck"></div>
<div class="nav">
<button onclick="go(-1)">← Назад</button>
<button onclick="go(1)">Вперёд →</button>
<button class="pptx" onclick="downloadPptx()">Скачать .pptx</button>
</div>
<div class="num-page" id="numPage"></div>
<script>
var SLIDES = [
// 1
{ type: 'title',
title: 'ОПТИМИЗАЦИЯ РАСХОДОВ ПО СЕРВИСНЫМ КОНТРАКТАМ',
subtitle: 'Анализ детализации 2023 – 1-е полугодие 2026 гг. · 103 позиции · отклонения и периметры',
chips: ['103 позиции', '2023 · 2024 · 2025 · 1пг 2026', '4 227 млн тг за 1пг 2026', 'Тенге, факт'] },
// 2
{ type: 'kpi', title: 'Итоговый свод',
kpi: [
{ num: '9,58', unit: 'млрд тг', lbl: 'Всего за 2023 (55 поз.)', tone: '' },
{ num: '10,83', unit: 'млрд тг', lbl: 'Всего за 2024 (54 поз.) — пик', tone: 'risk' },
{ num: '8,35', unit: 'млрд тг', lbl: 'Всего за 2025 (45 поз.)', tone: '' },
{ num: '4,227', unit: 'млрд тг', lbl: '1пг 2026 (31 поз.)', tone: 'ok' },
],
bullets: [
'2024 → 2025: падение <b class="neg">−2,48 млрд тг (−22,9 %)</b> — сильнее прироста 2024 (+13,1 %), это не экономия, а смена номенклатуры',
'1пг 2026: <b>4,227 млрд</b> — на <b class="pos">+52 млн тг (+1,3 %)</b> выше темпа 2025, т. е. при сохранении темпа год даст ≈ 8,45 млрд',
'По годам: 2026 (по темпу ×2) ≈ <b>8,45 млрд</b>, т. е. возврат на уровень 2024',
],
footnote: 'Источник: «Расходы по сервисным контрактам.xlsx», факт, 103 позиции.' },
// 3
{ type: 'table', title: 'Топ-10 отклонений: 2025 vs 2024',
hint: 'Статьи с Δ ≥ 0,1 млрд тг, где есть факт за оба года. Красное — рост, зелёное — снижение.',
table: [
['#', 'Позиция', '2024, млн тг', '2025, млн тг', 'Δ, млн тг', 'Δ %'],
['1', 'Техническая поддержка Ericsson (CS part)', '963,8', '268,9', '<span class="neg">−694,9</span>', '<span class="neg">−72,1 %</span>'],
['2', 'Техническая поддержка Ericsson (5G part)', '308,1', '134,5', '<span class="neg">−173,6</span>', '<span class="neg">−56,4 %</span>'],
['3', 'Сервис отправки микровызовов', '283,3', '98,9', '<span class="neg">−184,3</span>', '<span class="neg">−65,1 %</span>'],
['4', 'SUS подписка vEPC проект', '150,4', '116,3', '<span class="neg">−34,1</span>', '<span class="neg">−22,7 %</span>'],
['5', 'Мегакам лицензии / vPBX (базовая строка)', '40,7', '86,8', '<span class="pos">+46,1</span>', '<span class="pos">+113,2 %</span>'],
],
note: 'Помимо 5 строк с фактом за оба года — 19 новых статей 2025 (3,635 млрд тг): Ericsson 1 057, MS EA 630, MS EA COGS 513, Микровызовы 283, Veritas 257 и т. д.' },
// 4
{ type: 'table', title: '1пг 2026 vs 1пг 2025 — существующие статьи',
hint: '1пг 2025 = факт 2025 / 2 (ориентир при равномерном распределении). Отклонение ≥ 0,05 млрд тг.',
table: [
['Позиция', '1пг 2025, млн', '1пг 2026, млн', 'Δ, млн тг', 'Δ %'],
['Серверные лицензии MS EA', '315,1', '630,2', '<span class="pos">+315,1</span>', '<span class="pos">+100,0 %</span>'],
['Техническая поддержка Huawei', '53,7', '171,5', '<span class="pos">+117,8</span>', '<span class="pos">+219,5 %</span>'],
['Техническая поддержка Checkpoint Diamont', '36,5', '101,4', '<span class="pos">+64,9</span>', '<span class="pos">+177,6 %</span>'],
['Техническая поддержка Nexign', '630,2', '686,3', '<span class="pos">+56,1</span>', '<span class="pos">+8,9 %</span>'],
['СОРМ-Ронекс', '56,9', '30,0', '<span class="neg">−26,9</span>', '<span class="neg">−47,3 %</span>'],
['Aitu Passport (облако УЦ)', '80,2', '58,3', '<span class="neg">−21,9</span>', '<span class="neg">−27,3 %</span>'],
],
note: 'Существенные сокращения на фоне роста MS EA: в 1пг 2026 на 103 млн тг больше, чем по темпу 2025 — это рост именно по MS EA +15,7 млн и Checkpoint +64,9 млн.' },
// 5
{ type: 'table', title: 'Новые статьи 1пг 2026 (нет в 2025)',
hint: '4 статьи, которых не было в 2025 году. Суммарно 1 276 млн тг за 1пг 2026.',
table: [
['Позиция', '1пг 2026, млн тг', 'Комментарий'],
['Техническая поддержка Ericsson (общий новый договор)', '826,6', 'объединила CS part + 5G part'],
['Техническая поддержка Oracle HW', '376,0', 'новая строка (в 2025 была как Oracle HW 73,5)'],
['Мегакам лицензии', '49,0', 'лицензии'],
['Техническая поддержка Cisco smartnet', '25,0', 'встречный контракт'],
],
note: 'Ключевой сдвиг: Ericsson (общий новый договор) 827 млн тг за 1пг 2026 — это объединение двух старых строк, т. е. периметр сменился, а не появился новый расход.' },
// 6
{ type: 'two', title: 'Номенклатура 2025: что ушло и что пришло',
tableA: {
title: 'Появились в 2025 (нет в 2024)',
rows: [
['Ericsson', '1 057,0', ''],
['MS EA (базовая)', '630,2', ''],
['MS EA / 3 транш / COGS', '513,4', ''],
['Сервис отправки микровызовов', '283,3', ''],
['Veritas', '257,4', ''],
['SUS подписка vEPC проект', '150,4', ''],
['Huawei', '107,3', ''],
['Steering of Roaming, SMSW', '106,0', ''],
['…и ещё 11 позиций', '154,0', ''],
['Итого новых: 19 шт.', '3 635,2', ''],
]
},
tableB: {
title: 'Исчезли в 2025 (были в 2024)',
rows: [
['FLM Expenses', '3 481,0', '→ FLM (3 232 млн)'],
['Прочие', '500,8', ''],
['Video Conference System (Cisco)', '446,7', ''],
['Veritas', '132,2', ''],
['System SUPPORT of ZTE', '80,3', ''],
['Услуги тех. поддержки HP', '76,9', ''],
['Ремонт ФА3 гр. (Dell)', '69,5', ''],
['Maintenance FOCL (ВОЛС)', '55,1', ''],
['…и ещё 19 позиций', '270,5', ''],
['Итого исчезнувших: 29 шт.', '5 142,2', ''],
]
},
note: 'Чистая смена номенклатуры: пришло 3635 млн, ушло 5142 млн. Разница −1507 млн тг — это механика спада 2025.' },
// 7
{ type: 'text', title: 'Эффективный анализ статей 2025',
bullets: [
'<b>FLM: 3 481 млн (2024) → 3 232 млн (2025) → 2 184 млн (1пг 2026)</b>. В 2025 перенесено из «FLM Expenses» в «FLM».',
'Внутри FLM: 1пг 2026 vs 1пг 2025 — <b class="pos">+568 млн тг (+35,1 %)</b>. Статья растёт.',
'<b>Ericsson суммарно: 1 186 млн (2024) → 790 млн (2025)</b> — минус 33%. При этом 5G часть перешла в «общий новый договор» 2026 (827 млн за 1пг 2026).',
'<b>MS EA (базовая строка): 630 млн тг за 1пг 2026 = как за весь 2025</b>. При сохранении темпа год даст ≈ 1 260 млн (+100 %).',
'Строки «MS EA / 3 транш / COGS» (513 млн) и «G&A» (45 млн) в 2026 не фигурируют — сверить периметр договоров.',
'Сокращения в 1пг 2026: CORM-Ронекс −26,9 млн, Aitu Passport −21,9 млн, Nехign −68 млн (к темпу 2025).',
] },
// 8
{ type: 'recommendations', title: 'Рекомендации',
bullets: [
{ b: 'Приоритет 1 — сверить периметры 1пг 2026.', s: 'MS EA (базовая = как за весь 2025), Oracle HW (376 млн, новая), Ericsson (общий новый договор, 827 млн, объединение).', tone: 'risk' },
{ b: 'Приоритет 2 — консолидация Ericsson.', s: 'Объединение CS part + 5G part уже сделано в 2026. Следующий шаг — переход на гибридную модель (P1 + RMA за вендора, P2/P3 силами КТ), как в референсе ОДС.', tone: 'warn' },
{ b: 'Приоритет 3 — проверить FLM.', s: '+35,1 % к темпу 2025. 2 184 млн за 1пг 2026. Если рост продолжается — пересмотреть условия.', tone: 'warn' },
{ b: 'Приоритет 4 — зафиксировать сокращения.', s: 'CORM-Ронекс −26,9 млн, Aitu Passport −21,9 млн, Nехign −68 млн (к темпу 2025). Заложить в план 2027.', tone: 'ok' },
{ b: 'Приоритет 5 — реестр статусов.', s: 'К каждой статье: «прямой / посредник / дистрибьютор», «готов к инсорсингу / нужен вендор», P1/RMA за период.', tone: '' },
] },
// 9
{ type: 'close', title: 'Итого',
big: '−2,48 млрд тг\n(−22,9 %)\nк 2025',
bullets: [
'Падение 2025 — не экономия, а смена номенклатуры (FLM Expenses → FLM, Ericsson part → общий договор, MS EA COGS/G&A).',
'1пг 2026 показывает <b>рост +1,3 % к темпу 2025</b>: драйверы — MS EA +15,7 млн, Checkpoint +64,9 млн.',
'Главный риск 2027 — <b>MS EA</b>: 630 млн за 1пг 2026 = как за весь 2025. При сохранении темпа год ≈ +100 %.',
'Следующий шаг — сверить периметры договоров и зафиксировать реестр статусов (прямой / посредник, инсорсинг / вендор).',
],
footnote: 'Итоговый отчёт (Excel) + полная детализация 103 позиций прилагаются.' },
];
var cur = 0;
function render() {
var html = SLIDES.map(function (s, i) {
var on = i === cur ? ' on' : '';
var inner = renderSlide(s);
return '<section class="slide' + on + '"' + (s.type === 'title' || s.type === 'close' ? ' data-center="1"' : '') + '>' + inner + '</section>';
}).join('');
document.getElementById('deck').innerHTML = html;
document.getElementById('numPage').textContent = (cur + 1) + ' / ' + SLIDES.length;
}
function renderSlide(s) {
if (s.type === 'title') {
return '<span class="badge">' + esc(s.subtitle.split(' · ')[0]) + '</span>' +
'<h0>' + esc(s.title) + '</h0>' +
'<h2>' + esc(s.subtitle) + '</h2>' +
'<div class="kpi-row">' + s.chips.map(function (c) {
return '<div class="kpi"><div class="num" style="font-size:20px">' + esc(c) + '</div></div>';
}).join('') + '</div>' +
footer();
}
if (s.type === 'kpi') {
return '<div class="kpi-row">' + s.kpi.map(function (k) {
return '<div class="kpi ' + (k.tone || '') + '"><div class="num">' + esc(k.num) + ' ' + esc(k.unit || '') + '</div><div class="lbl">' + esc(k.lbl) + '</div></div>';
}).join('') + '</div>' +
'<ul>' + s.bullets.map(function (b) { return '<li>' + b + '</li>'; }).join('') + '</ul>' +
'<div class="note">' + esc(s.footnote || '') + '</div>' + footer();
}
if (s.type === 'table') {
var th = s.table[0].map(function (h, i) {
return '<th' + (i > 0 ? ' class="ta-r"' : '') + '>' + esc(h) + '</th>';
}).join('');
var body = s.table.slice(1).map(function (row) {
return '<tr>' + row.map(function (c, i) {
return '<td' + (i > 0 ? ' class="ta-r"' : '') + '>' + c + '</td>';
}).join('') + '</tr>';
}).join('');
return '<h1>' + esc(s.title) + '</h1>' +
'<div class="note" style="margin-top:0">' + esc(s.hint || '') + '</div>' +
'<table><thead><tr>' + th + '</tr></thead><tbody>' + body + '</tbody></table>' +
(s.note ? '<div class="note">' + esc(s.note) + '</div>' : '') + footer();
}
if (s.type === 'two') {
function mini(t) {
var rows = t.rows.map(function (r) {
return '<tr><td>' + esc(r[0]) + '</td><td class="ta-r">' + esc(r[1]) + '</td><td class="ta-r dim" style="text-align:left;width:35%;font-weight:400">' + (r[2] ? esc(r[2]) : '') + '</td></tr>';
}).join('');
return '<div style="flex:1 1 45%;min-width:300px"><table><thead><tr><th>' + esc(t.title) + '</th><th class="ta-r">млн тг</th><th class="ta-r"></th></tr></thead><tbody>' + rows + '</tbody></table></div>';
}
return '<h1>' + esc(s.title) + '</h1>' +
'<div style="display:flex;gap:20px;flex-wrap:wrap;flex:1">' + mini(s.tableA) + mini(s.tableB) + '</div>' +
(s.note ? '<div class="note">' + esc(s.note) + '</div>' : '') + footer();
}
if (s.type === 'text') {
return '<h1>' + esc(s.title) + '</h1>' +
'<ul>' + s.bullets.map(function (b) { return '<li>' + b + '</li>'; }).join('') + '</ul>' + footer();
}
if (s.type === 'recommendations') {
var items = s.bullets.map(function (b) {
var cls = b.tone === 'risk' ? 'kpi risk' : b.tone === 'warn' ? 'kpi warn' : b.tone === 'ok' ? 'kpi ok' : 'kpi';
return '<div class="' + cls + '" style="margin-bottom:10px"><div class="num" style="font-size:15px;font-weight:600;color:inherit">' + b.b + '</div><div class="lbl" style="margin-top:4px;font-size:13px">' + b.s + '</div></div>';
}).join('');
return '<h1>' + esc(s.title) + '</h1>' + items + footer();
}
if (s.type === 'close') {
return '<h1>' + esc(s.title) + '</h1>' +
'<div class="kpi-row" style="flex-direction:row;align-items:center">' +
'<div class="kpi" style="flex:0 0 260px;border-width:2px;border-color:#8EAEC8"><div class="num" style="font-size:40px;line-height:1.1;white-space:pre-wrap">' + esc(s.big) + '</div><div class="lbl">Итог 2025 vs 2024</div></div>' +
'<div style="flex:1"><ul style="margin:0">' + s.bullets.map(function (b) { return '<li>' + b + '</li>'; }).join('') + '</ul>' +
'<div class="note">' + esc(s.footnote || '') + '</div></div></div>' + footer();
}
return '';
}
function footer() {
return '<div class="footer"><span>Опти­миза­ция расхо­дов</span><span class="sep"></span><span>103 пози­ции · 2023 – 1пг 2026</span><span class="sep"></span><span>Источ­ник: Расхо­ды по сер­вис­ным кон­трак­там.xlsx</span></div>';
}
function esc(s) {
return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
function go(d) {
cur = Math.min(SLIDES.length - 1, Math.max(0, cur + d));
render();
}
document.addEventListener('keydown', function (e) {
if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'PageDown') go(1);
if (e.key === 'ArrowLeft' || e.key === 'PageUp') go(-1);
});
// ============ PPTX ============
// Палитра из референса
var C = { bg: '0D1B2A', panel: '142433', border: '1B4F72', accent: '8EAEC8', mute: '8899A6', dim: '6C8FA8', ok: '1A7F4B', warn: 'D4680A', risk: 'C0392B', fg: 'F0F4F8', line: '1E3A52' };
function downloadPptx() {
var p = new PptxGenJS();
p.defineLayout({ name: 'W', width: 13.33, height: 7.5 });
p.layout = 'W';
p.author = 'Vibe42';
p.company = 'Анализ сервисных контрактов';
function addBg(sl) {
sl.background = { color: C.bg };
sl.addText('Оптимизация расходов · 103 позиции · 2023 – 1пг 2026', { x: 0.5, y: 7.0, w: 12, h: 0.4, fontSize: 9, color: C.dim, fontFace: 'Segoe UI' });
}
function addTitle(sl, text, opts) {
sl.addText(text, Object.assign({ x: 0.5, y: 0.35, w: 12, h: 0.9, fontSize: 30, bold: true, color: C.fg, fontFace: 'Segoe UI' }, opts || {}));
}
function addKpiRow(sl, items, y) {
var n = items.length;
var w = 12.4 / n;
items.forEach(function (k, i) {
var x = 0.5 + i * w;
sl.addShape(p.ShapeType.roundRect, { x: x, y: y, w: w - 0.12, h: 1.4, fill: { color: C.panel }, line: { color: C.border, width: 1 }, rectRadius: 0.06 });
var tone = k.tone === 'risk' ? C.risk : k.tone === 'warn' ? C.warn : k.tone === 'ok' ? C.ok : C.accent;
sl.addText(k.num + (k.unit ? ' ' + k.unit : ''), { x: x + 0.15, y: y + 0.15, w: w - 0.4, h: 0.6, fontSize: 24, bold: true, color: tone, fontFace: 'Segoe UI' });
sl.addText(k.lbl, { x: x + 0.15, y: y + 0.75, w: w - 0.4, h: 0.6, fontSize: 10, color: C.mute, fontFace: 'Segoe UI' });
});
}
function addBullets(sl, bullets, opts) {
sl.addText(bullets.map(function (b, idx) {
return { text: b, options: { bullet: { code: '2022', indent: 14 }, color: C.fg, breakLine: true, paraSpaceAfter: 8 } };
}), Object.assign({ x: 0.5, y: 2.0, w: 12.4, h: 4.8, fontSize: 14, fontFace: 'Segoe UI', color: C.fg }, opts || {}));
}
function addRowsTable(sl, headers, rows, opts) {
var header = headers.map(function (h) { return { text: h, options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 11, valign: 'middle' } }; });
var body = rows.map(function (row, ri) {
return row.map(function (cell, ci) {
var color = C.fg;
var bold = false;
if (typeof cell === 'string') {
if (cell.indexOf('class="pos"') >= 0 || (cell.indexOf('+') === 0 && ci > 0)) { color = C.risk; bold = true; }
if (cell.indexOf('class="neg"') >= 0 || (ci > 0 && cell.indexOf('−') === 0)) { color = C.ok; bold = true; }
cell = cell.replace(/<[^>]+>/g, '');
}
return { text: String(cell), options: { color: color, bold: bold, fill: { color: ri % 2 ? C.bg : '101D2A' }, fontSize: 11 } };
});
});
var table = [header].concat(body);
sl.addTable(table, Object.assign({ x: 0.5, y: 2.4, w: 12.4, fontFace: 'Segoe UI', rowH: 0.4, autoPage: false, valign: 'middle' }, opts || {}));
}
// 1: title
(function () {
var s = SLIDES[0];
var sl = p.addSlide(); addBg(sl);
sl.addShape(p.ShapeType.rect, { x: 0.5, y: 0.5, w: 0.35, h: 0.35, fill: { color: C.accent } });
sl.addText(s.subtitle, { x: 1.0, y: 0.5, w: 12, h: 0.5, fontSize: 12, color: C.accent, fontFace: 'Segoe UI', charSpacing: 4 });
sl.addText(s.title, { x: 0.5, y: 2.2, w: 12.4, h: 1.8, fontSize: 50, bold: true, color: C.fg, fontFace: 'Segoe UI', charSpacing: -1 });
var chips = s.chips.map(function (c) { return { text: c, options: { bullet: false, color: C.accent, breakLine: true } }; });
sl.addText(chips, { x: 0.5, y: 4.6, w: 12.4, h: 1.6, fontSize: 14, fontFace: 'Segoe UI' });
})();
// 2: KPI + bullets
(function () {
var s = SLIDES[1];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
addKpiRow(sl, s.kpi, 1.5);
sl.addText(s.bullets.map(function (b) {
return { text: b.replace(/<[^>]+>/g, ''), options: { bullet: { code: '2022', indent: 14 }, color: C.fg, breakLine: true, paraSpaceAfter: 10 } };
}), { x: 0.5, y: 3.3, w: 12.4, h: 2.8, fontSize: 14, fontFace: 'Segoe UI' });
sl.addText(s.footnote, { x: 0.5, y: 6.2, w: 12.4, h: 0.4, fontSize: 10, color: C.mute, italic: true, fontFace: 'Segoe UI' });
})();
// 3: dev25
(function () {
var s = SLIDES[2];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
sl.addText(s.hint, { x: 0.5, y: 1.3, w: 12.4, h: 0.4, fontSize: 11, color: C.mute, italic: true, fontFace: 'Segoe UI' });
var headers = s.table[0].map(function (h, i) { return { text: h, options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 11, valign: 'middle' } }; });
var rows = s.table.slice(1).map(function (row, ri) {
return row.map(function (cell, ci) {
var color = C.fg, bold = false, txt = String(cell).replace(/<[^>]+>/g, '');
if (ci === 4) { color = txt.indexOf('+') === 0 ? C.risk : C.ok; bold = true; }
if (ci === 5) { color = txt.indexOf('+') === 0 ? C.risk : C.ok; bold = true; }
if (ri % 2 === 1) return { text: txt, options: { color: color, bold: bold, fill: { color: '101D2A' }, fontSize: 11 } };
return { text: txt, options: { color: color, bold: bold, fontSize: 11 } };
});
});
sl.addTable([headers].concat(rows), { x: 0.5, y: 1.9, w: 12.4, fontFace: 'Segoe UI', rowH: 0.55, autoPage: false, valign: 'middle' });
sl.addText(s.note, { x: 0.5, y: 5.6, w: 12.4, h: 0.9, fontSize: 11, color: C.mute, fontFace: 'Segoe UI' });
})();
// 4: dev26
(function () {
var s = SLIDES[3];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
sl.addText(s.hint, { x: 0.5, y: 1.3, w: 12.4, h: 0.4, fontSize: 11, color: C.mute, italic: true, fontFace: 'Segoe UI' });
var headers = s.table[0].map(function (h, i) { return { text: h, options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 11, valign: 'middle' } }; });
var rows = s.table.slice(1).map(function (row, ri) {
return row.map(function (cell, ci) {
var color = C.fg, bold = false, txt = String(cell).replace(/<[^>]+>/g, '');
if (ci === 3 || ci === 4) { color = txt.indexOf('+') === 0 ? C.risk : C.ok; bold = true; }
if (ri % 2 === 1) return { text: txt, options: { color: color, bold: bold, fill: { color: '101D2A' }, fontSize: 11 } };
return { text: txt, options: { color: color, bold: bold, fontSize: 11 } };
});
});
sl.addTable([headers].concat(rows), { x: 0.5, y: 1.9, w: 12.4, fontFace: 'Segoe UI', rowH: 0.5, autoPage: false, valign: 'middle' });
sl.addText(s.note, { x: 0.5, y: 5.4, w: 12.4, h: 0.9, fontSize: 11, color: C.mute, fontFace: 'Segoe UI' });
})();
// 5: new26
(function () {
var s = SLIDES[4];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
sl.addText(s.hint, { x: 0.5, y: 1.3, w: 12.4, h: 0.4, fontSize: 11, color: C.mute, italic: true, fontFace: 'Segoe UI' });
var headers = s.table[0].map(function (h, i) { return { text: h, options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 11, valign: 'middle' } }; });
var rows = s.table.slice(1).map(function (row, ri) {
return row.map(function (cell, ci) {
if (ci === 1) return { text: String(cell), options: { bold: true, color: C.accent, fill: ri % 2 ? { color: '101D2A' } : undefined, fontSize: 12 } };
return { text: String(cell), options: { fill: ri % 2 ? { color: '101D2A' } : undefined, fontSize: 11 } };
});
});
sl.addTable([headers].concat(rows), { x: 0.5, y: 1.9, w: 12.4, fontFace: 'Segoe UI', rowH: 0.6, autoPage: false, valign: 'middle' });
sl.addText(s.note, { x: 0.5, y: 4.8, w: 12.4, h: 1.2, fontSize: 11, color: C.mute, fontFace: 'Segoe UI' });
})();
// 6: two
(function () {
var s = SLIDES[5];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
function mini(t, x) {
sl.addText(t.title, { x: x, y: 1.5, w: 6.0, h: 0.4, fontSize: 12, bold: true, color: C.accent, fontFace: 'Segoe UI' });
var header = [{ text: '', options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 10 } }, { text: 'млн тг', options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 10, valign: 'middle', align: 'right' } }, { text: '', options: { bold: true, color: '8899A6', fill: { color: C.panel }, fontSize: 10 } }];
var rows = t.rows.map(function (row, ri) {
var bg = ri % 2 ? { color: '101D2A' } : undefined;
var isTotal = ri === t.rows.length - 1;
return [
{ text: row[0], options: { bold: isTotal, fill: bg, fontSize: 10 } },
{ text: row[1], options: { bold: isTotal, align: 'right', fill: bg, fontSize: 10 } },
{ text: row[2] || '', options: { color: C.dim, fill: bg, fontSize: 10 } },
];
});
sl.addTable([header].concat(rows), { x: x, y: 1.95, w: 6.0, fontFace: 'Segoe UI', rowH: 0.35, autoPage: false, valign: 'middle' });
}
mini(s.tableA, 0.5);
mini(s.tableB, 6.8);
sl.addText(s.note, { x: 0.5, y: 5.8, w: 12.4, h: 0.6, fontSize: 11, color: C.mute, fontFace: 'Segoe UI' });
})();
// 7: text
(function () {
var s = SLIDES[6];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
sl.addText(s.bullets.map(function (b) {
return { text: b.replace(/<[^>]+>/g, ''), options: { bullet: { code: '2022', indent: 14 }, color: C.fg, breakLine: true, paraSpaceAfter: 12 } };
}), { x: 0.5, y: 1.7, w: 12.4, h: 4.8, fontSize: 14, fontFace: 'Segoe UI' });
})();
// 8: recommendations
(function () {
var s = SLIDES[7];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
var y = 1.55;
s.bullets.forEach(function (b) {
var tone = b.tone === 'risk' ? C.risk : b.tone === 'warn' ? C.warn : b.tone === 'ok' ? C.ok : C.accent;
sl.addShape(p.ShapeType.roundRect, { x: 0.5, y: y, w: 12.4, h: 0.85, fill: { color: C.panel }, line: { color: C.border, width: 1 }, rectRadius: 0.05 });
sl.addShape(p.ShapeType.rect, { x: 0.5, y: y, w: 0.08, h: 0.85, fill: { color: tone } });
sl.addText(b.b, { x: 0.75, y: y + 0.05, w: 12, h: 0.4, fontSize: 13, bold: true, color: C.fg, fontFace: 'Segoe UI' });
sl.addText(b.s, { x: 0.75, y: y + 0.45, w: 12, h: 0.35, fontSize: 10, color: C.mute, fontFace: 'Segoe UI' });
y += 1.0;
});
})();
// 9: close
(function () {
var s = SLIDES[8];
var sl = p.addSlide(); addBg(sl); addTitle(sl, s.title);
sl.addShape(p.ShapeType.roundRect, { x: 0.5, y: 1.7, w: 4.4, h: 4.4, fill: { color: C.panel }, line: { color: C.accent, width: 2 }, rectRadius: 0.15 });
sl.addText(s.big, { x: 0.7, y: 2.2, w: 4.0, h: 2.0, fontSize: 30, bold: true, color: C.accent, fontFace: 'Segoe UI', paraSpaceBefore: 6, lineSpacingMultiple: 1.2 });
sl.addText('Итог 2025 vs 2024', { x: 0.7, y: 4.4, w: 4.0, h: 0.6, fontSize: 12, color: C.mute, fontFace: 'Segoe UI' });
sl.addText(s.bullets.map(function (b) {
return { text: b.replace(/<[^>]+>/g, ''), options: { bullet: { code: '2022', indent: 14 }, color: C.fg, breakLine: true, paraSpaceAfter: 10 } };
}), { x: 5.3, y: 1.7, w: 7.4, h: 4.4, fontSize: 13, fontFace: 'Segoe UI' });
sl.addText(s.footnote, { x: 5.3, y: 6.1, w: 7.4, h: 0.5, fontSize: 10, color: C.mute, italic: true, fontFace: 'Segoe UI' });
})();
p.writeFile({ fileName: "Оптимизация_расходов_2023-1пг26.pptx" });
}
render();
</script>
</body>
</html>