@thanh01.pmt/presentation-kit 0.2.13 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/index.cjs +14 -14
- package/dist/ai/index.js +1 -1
- package/dist/{chunk-53GLUCYC.cjs → chunk-SUGKWGJJ.cjs} +161 -199
- package/dist/chunk-SUGKWGJJ.cjs.map +1 -0
- package/dist/{chunk-3VGV5KYZ.js → chunk-YPYAP4TF.js} +161 -199
- package/dist/chunk-YPYAP4TF.js.map +1 -0
- package/dist/index.cjs +15 -15
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/react/index.cjs +43 -24
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +39 -20
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-3VGV5KYZ.js.map +0 -1
- package/dist/chunk-53GLUCYC.cjs.map +0 -1
|
@@ -1276,9 +1276,9 @@ var HTML_SLIDE_PRESETS = {
|
|
|
1276
1276
|
|
|
1277
1277
|
// src/html-engine/shell.ts
|
|
1278
1278
|
function generateHtmlShell(options) {
|
|
1279
|
-
const { title, theme, slidesHtml, slideCount, customHeadTags = "" } = options;
|
|
1279
|
+
const { title, theme, slidesHtml, slideCount, customHeadTags = "", deckId = "" } = options;
|
|
1280
1280
|
return `<!DOCTYPE html>
|
|
1281
|
-
<html lang="en" class="${theme.scheme}">
|
|
1281
|
+
<html lang="en" class="${theme.scheme}"${deckId ? ` data-deck-id="${deckId}"` : ""}>
|
|
1282
1282
|
<head>
|
|
1283
1283
|
<meta charset="UTF-8">
|
|
1284
1284
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
@@ -1292,6 +1292,7 @@ function generateHtmlShell(options) {
|
|
|
1292
1292
|
<!-- Core Presentation Styling & 1920x1080 Scaled Tailwind Configuration -->
|
|
1293
1293
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
1294
1294
|
<script>
|
|
1295
|
+
window.tailwind = window.tailwind || {};
|
|
1295
1296
|
tailwind.config = {
|
|
1296
1297
|
darkMode: 'class',
|
|
1297
1298
|
theme: {
|
|
@@ -1415,6 +1416,7 @@ function generateHtmlShell(options) {
|
|
|
1415
1416
|
left: 50%;
|
|
1416
1417
|
width: 1920px;
|
|
1417
1418
|
height: 1080px;
|
|
1419
|
+
transform: translate(-50%, -50%);
|
|
1418
1420
|
transform-origin: center center;
|
|
1419
1421
|
background-color: var(--bg);
|
|
1420
1422
|
overflow: hidden;
|
|
@@ -2233,7 +2235,7 @@ function generateHtmlShell(options) {
|
|
|
2233
2235
|
<!-- WYSIWYG Inline Edit UI (Level 1) -->
|
|
2234
2236
|
<div class="edit-hotzone" id="edit-hotzone"></div>
|
|
2235
2237
|
<button class="edit-toggle" id="btn-edit-toggle" title="Toggle Inline Edit Mode (E)">
|
|
2236
|
-
<
|
|
2238
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
|
|
2237
2239
|
<span id="edit-toggle-label">Edit Mode (E)</span>
|
|
2238
2240
|
</button>
|
|
2239
2241
|
|
|
@@ -2248,7 +2250,9 @@ function generateHtmlShell(options) {
|
|
|
2248
2250
|
<button type="button" class="mode-tab active" id="tab-mode-unified">Unified</button>
|
|
2249
2251
|
<button type="button" class="mode-tab" id="tab-mode-independent">Independent</button>
|
|
2250
2252
|
</div>
|
|
2251
|
-
<button type="button" class="scale-panel-close" id="btn-scale-panel-close" title="Close Panel"
|
|
2253
|
+
<button type="button" class="scale-panel-close" id="btn-scale-panel-close" title="Close Panel" style="display: flex; align-items: center; justify-content: center;">
|
|
2254
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
|
2255
|
+
</button>
|
|
2252
2256
|
</div>
|
|
2253
2257
|
|
|
2254
2258
|
<!-- Unified Mode Content -->
|
|
@@ -2298,7 +2302,10 @@ function generateHtmlShell(options) {
|
|
|
2298
2302
|
<input type="range" id="input-scale-spacing" min="70" max="150" value="100" class="scale-range-slider" />
|
|
2299
2303
|
</div>
|
|
2300
2304
|
<div class="scale-independent-footer">
|
|
2301
|
-
<button type="button" class="btn-reset-scales" id="btn-reset-scales"
|
|
2305
|
+
<button type="button" class="btn-reset-scales" id="btn-reset-scales" style="display: flex; align-items: center; gap: 4px;">
|
|
2306
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
|
|
2307
|
+
<span>Reset All</span>
|
|
2308
|
+
</button>
|
|
2302
2309
|
</div>
|
|
2303
2310
|
</div>
|
|
2304
2311
|
</div>
|
|
@@ -2311,13 +2318,22 @@ function generateHtmlShell(options) {
|
|
|
2311
2318
|
<button class="edit-bar-btn" id="btn-format-underline" title="Underline (Cmd+U)"><u>U</u></button>
|
|
2312
2319
|
<div class="edit-bar-divider"></div>
|
|
2313
2320
|
<button class="edit-bar-btn" id="btn-editbar-scale" title="Tune Element Scales (Unified / Independent)">
|
|
2314
|
-
<
|
|
2321
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 3 3 21"/><path d="m14 4 6 6"/><path d="m4 14 6 6"/></svg>
|
|
2315
2322
|
<span>Scale</span>
|
|
2316
2323
|
</button>
|
|
2317
2324
|
<div class="edit-bar-divider"></div>
|
|
2318
|
-
<button class="edit-bar-btn" id="btn-reset-edits" title="Restore original content"
|
|
2319
|
-
|
|
2320
|
-
|
|
2325
|
+
<button class="edit-bar-btn" id="btn-reset-edits" title="Restore original content">
|
|
2326
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
|
|
2327
|
+
<span>Reset</span>
|
|
2328
|
+
</button>
|
|
2329
|
+
<button class="edit-bar-btn save-btn" id="btn-save-html" title="Save and download clean HTML file">
|
|
2330
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
|
2331
|
+
<span>Save HTML</span>
|
|
2332
|
+
</button>
|
|
2333
|
+
<button class="edit-bar-btn" id="btn-done-edit" title="Done editing (E)">
|
|
2334
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
|
|
2335
|
+
<span>Done</span>
|
|
2336
|
+
</button>
|
|
2321
2337
|
</div>
|
|
2322
2338
|
|
|
2323
2339
|
<!-- Presenter Drawer (Quick In-Page Notes & Timer) -->
|
|
@@ -2326,15 +2342,18 @@ function generateHtmlShell(options) {
|
|
|
2326
2342
|
<div class="presenter-meta-group">
|
|
2327
2343
|
<span style="font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #a1a1aa;">Presenter Console</span>
|
|
2328
2344
|
<div class="presenter-timer-badge">
|
|
2329
|
-
<
|
|
2345
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
|
2330
2346
|
<span id="presenter-timer-text">00:00</span>
|
|
2331
2347
|
</div>
|
|
2332
2348
|
</div>
|
|
2333
2349
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
2334
|
-
<button type="button" class="btn-reset-scales" id="btn-open-dual-presenter" title="Open separate synced presenter console window for multi-monitor display">
|
|
2335
|
-
<span>Launch 2nd Window
|
|
2350
|
+
<button type="button" class="btn-reset-scales" id="btn-open-dual-presenter" title="Open separate synced presenter console window for multi-monitor display" style="display: flex; align-items: center; gap: 4px;">
|
|
2351
|
+
<span>Launch 2nd Window</span>
|
|
2352
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17 17 7"/><path d="M7 7h10v10"/></svg>
|
|
2353
|
+
</button>
|
|
2354
|
+
<button type="button" class="scale-panel-close" id="btn-close-presenter-drawer" title="Close Drawer (P)" style="display: flex; align-items: center; justify-content: center;">
|
|
2355
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
|
2336
2356
|
</button>
|
|
2337
|
-
<button type="button" class="scale-panel-close" id="btn-close-presenter-drawer" title="Close Drawer (P)">\u2715</button>
|
|
2338
2357
|
</div>
|
|
2339
2358
|
</div>
|
|
2340
2359
|
<div class="presenter-notes-box" id="presenter-notes-text">
|
|
@@ -2354,11 +2373,14 @@ function generateHtmlShell(options) {
|
|
|
2354
2373
|
<span style="user-select: none;">In k\xE8m ghi ch\xFA gi\u1EA3ng vi\xEAn (Handout / Teacher Notes)</span>
|
|
2355
2374
|
</label>
|
|
2356
2375
|
<p style="font-size: 12px; color: #a1a1aa; line-height: 1.5; margin: 0;">
|
|
2357
|
-
\
|
|
2376
|
+
L\u01B0u \xFD: Ch\u1ECDn trang in Kh\u1ED5 ngang (Landscape), B\u1EADt "Background graphics" trong h\u1ED9p tho\u1EA1i in c\u1EE7a tr\xECnh duy\u1EC7t \u0111\u1EC3 m\xE0u s\u1EAFc hi\u1EC3n th\u1ECB \u0111\xFAng 100%.
|
|
2358
2377
|
</p>
|
|
2359
2378
|
<div class="print-dialog-actions">
|
|
2360
2379
|
<button type="button" class="btn-reset-scales" id="btn-cancel-print">H\u1EE7y</button>
|
|
2361
|
-
<button type="button" class="edit-bar-btn save-btn" id="btn-start-print" style="padding: 6px 16px;
|
|
2380
|
+
<button type="button" class="edit-bar-btn save-btn" id="btn-start-print" style="padding: 6px 16px; display: flex; align-items: center; gap: 6px;">
|
|
2381
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>
|
|
2382
|
+
<span>In ngay (Print)</span>
|
|
2383
|
+
</button>
|
|
2362
2384
|
</div>
|
|
2363
2385
|
</div>
|
|
2364
2386
|
</div>
|
|
@@ -2382,7 +2404,7 @@ function generateHtmlShell(options) {
|
|
|
2382
2404
|
<button class="control-btn" id="btn-controls-print" title="Print & Export PDF (Cmd+P)">
|
|
2383
2405
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>
|
|
2384
2406
|
</button>
|
|
2385
|
-
<button class="control-btn" id="btn-controls-scale" title="Tune Scale
|
|
2407
|
+
<button class="control-btn" id="btn-controls-scale" title="Tune Scale">
|
|
2386
2408
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 3 3 21"/><path d="m14 4 6 6"/><path d="m4 14 6 6"/></svg>
|
|
2387
2409
|
</button>
|
|
2388
2410
|
<button class="control-btn" id="btn-fullscreen" title="Toggle Fullscreen (F)">
|
|
@@ -2395,10 +2417,21 @@ function generateHtmlShell(options) {
|
|
|
2395
2417
|
const TOTAL_SLIDES = ${slideCount};
|
|
2396
2418
|
let currentSlide = 0;
|
|
2397
2419
|
let isEditMode = false;
|
|
2398
|
-
const STORAGE_KEY = 'deck_edit_' + encodeURIComponent(document.title.trim() || 'default');
|
|
2399
|
-
const originalCanvasHtml = document.getElementById('canvas').innerHTML;
|
|
2400
|
-
|
|
2401
2420
|
const canvas = document.getElementById('canvas');
|
|
2421
|
+
const originalCanvasHtml = canvas ? canvas.innerHTML : '';
|
|
2422
|
+
|
|
2423
|
+
function computeDeckContentHash(str) {
|
|
2424
|
+
let h = 0;
|
|
2425
|
+
for (let i = 0; i < str.length; i++) {
|
|
2426
|
+
h = (Math.imul(31, h) + str.charCodeAt(i)) | 0;
|
|
2427
|
+
}
|
|
2428
|
+
return Math.abs(h).toString(36);
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
const deckIdAttr = document.documentElement.getAttribute('data-deck-id');
|
|
2432
|
+
const contentHash = computeDeckContentHash(originalCanvasHtml);
|
|
2433
|
+
const deckKeyPrefix = deckIdAttr ? encodeURIComponent(deckIdAttr) : (encodeURIComponent(document.title.trim() || 'deck') + '_' + contentHash);
|
|
2434
|
+
const STORAGE_KEY = 'deck_edit_' + deckKeyPrefix;
|
|
2402
2435
|
const slides = document.querySelectorAll('.slide-page');
|
|
2403
2436
|
const progressBar = document.getElementById('progress-bar');
|
|
2404
2437
|
const counter = document.getElementById('slide-counter');
|
|
@@ -2458,7 +2491,7 @@ function generateHtmlShell(options) {
|
|
|
2458
2491
|
let timerInterval = null;
|
|
2459
2492
|
let isTimerRunning = false;
|
|
2460
2493
|
|
|
2461
|
-
const SCALE_STORAGE_KEY = 'deck_scale_' +
|
|
2494
|
+
const SCALE_STORAGE_KEY = 'deck_scale_' + deckKeyPrefix;
|
|
2462
2495
|
let scaleState = {
|
|
2463
2496
|
mode: 'unified', // 'unified' | 'independent'
|
|
2464
2497
|
factor: 1.0,
|
|
@@ -2482,8 +2515,9 @@ function generateHtmlShell(options) {
|
|
|
2482
2515
|
// Auto-scale 1920x1080 canvas to fit window
|
|
2483
2516
|
function resizeCanvas() {
|
|
2484
2517
|
if (isDeckMode) return;
|
|
2485
|
-
const vw = window.innerWidth;
|
|
2486
|
-
const vh = window.innerHeight;
|
|
2518
|
+
const vw = window.innerWidth || document.documentElement.clientWidth || 1920;
|
|
2519
|
+
const vh = window.innerHeight || document.documentElement.clientHeight || 1080;
|
|
2520
|
+
if (vw <= 0 || vh <= 0) return;
|
|
2487
2521
|
const scaleX = vw / 1920;
|
|
2488
2522
|
const scaleY = vh / 1080;
|
|
2489
2523
|
const scale = Math.min(scaleX, scaleY);
|
|
@@ -2491,7 +2525,10 @@ function generateHtmlShell(options) {
|
|
|
2491
2525
|
}
|
|
2492
2526
|
|
|
2493
2527
|
window.addEventListener('resize', resizeCanvas);
|
|
2528
|
+
window.addEventListener('load', resizeCanvas);
|
|
2529
|
+
document.addEventListener('DOMContentLoaded', resizeCanvas);
|
|
2494
2530
|
resizeCanvas();
|
|
2531
|
+
requestAnimationFrame(resizeCanvas);
|
|
2495
2532
|
|
|
2496
2533
|
function getSlideNotes(slideIndex) {
|
|
2497
2534
|
if (slideIndex < 0 || slideIndex >= slides.length) return '';
|
|
@@ -2664,8 +2701,7 @@ function generateHtmlShell(options) {
|
|
|
2664
2701
|
if (!presenterNotesText) return;
|
|
2665
2702
|
const notes = getSlideNotes(currentSlide);
|
|
2666
2703
|
if (notes && notes.trim()) {
|
|
2667
|
-
presenterNotesText.innerHTML = notes.
|
|
2668
|
-
/g, '<br/>');
|
|
2704
|
+
presenterNotesText.innerHTML = notes.split('\\n').join('<br/>');
|
|
2669
2705
|
} else {
|
|
2670
2706
|
presenterNotesText.innerHTML = '<span style="opacity: 0.5; font-style: italic;">No speaker notes for Slide ' + (currentSlide + 1) + '.</span>';
|
|
2671
2707
|
}
|
|
@@ -2682,7 +2718,7 @@ function generateHtmlShell(options) {
|
|
|
2682
2718
|
|
|
2683
2719
|
function openPresenterConsole() {
|
|
2684
2720
|
startTimer();
|
|
2685
|
-
const popupName = 'PresenterConsole_' + encodeURIComponent(document.title.replace(/
|
|
2721
|
+
const popupName = 'PresenterConsole_' + encodeURIComponent(document.title.replace(/[^a-zA-Z0-9_]/g, ''));
|
|
2686
2722
|
const win = window.open('', popupName, 'width=1100,height=720,menubar=no,toolbar=no,location=no,status=no');
|
|
2687
2723
|
if (!win) {
|
|
2688
2724
|
togglePresenterDrawer();
|
|
@@ -2693,151 +2729,84 @@ function generateHtmlShell(options) {
|
|
|
2693
2729
|
const currentNotes = getSlideNotes(currentSlide);
|
|
2694
2730
|
const curSlideTitle = 'Slide ' + (currentSlide + 1) + ' / ' + TOTAL_SLIDES;
|
|
2695
2731
|
|
|
2696
|
-
const consoleHtml =
|
|
2697
|
-
|
|
2698
|
-
<
|
|
2699
|
-
'
|
|
2700
|
-
'<meta charset="UTF-8"><title>Presenter Console \u2014 ' + (document.title || 'Slides') + '</title>
|
|
2701
|
-
'
|
|
2702
|
-
'
|
|
2703
|
-
'
|
|
2704
|
-
'
|
|
2705
|
-
'
|
|
2706
|
-
'
|
|
2707
|
-
'
|
|
2708
|
-
'.
|
|
2709
|
-
'
|
|
2710
|
-
'.
|
|
2711
|
-
'
|
|
2712
|
-
'.
|
|
2713
|
-
'
|
|
2714
|
-
'.
|
|
2715
|
-
'
|
|
2716
|
-
'
|
|
2717
|
-
'
|
|
2718
|
-
'
|
|
2719
|
-
' +
|
|
2720
|
-
'
|
|
2721
|
-
'
|
|
2722
|
-
'
|
|
2723
|
-
'
|
|
2724
|
-
'
|
|
2725
|
-
'
|
|
2726
|
-
'
|
|
2727
|
-
'
|
|
2728
|
-
'
|
|
2729
|
-
'
|
|
2730
|
-
'
|
|
2731
|
-
</
|
|
2732
|
-
|
|
2733
|
-
'
|
|
2734
|
-
'<div class="
|
|
2735
|
-
' +
|
|
2736
|
-
'
|
|
2737
|
-
'
|
|
2738
|
-
'
|
|
2739
|
-
'
|
|
2740
|
-
'
|
|
2741
|
-
'
|
|
2742
|
-
'
|
|
2743
|
-
'
|
|
2744
|
-
'
|
|
2745
|
-
' +
|
|
2746
|
-
'
|
|
2747
|
-
'
|
|
2748
|
-
'
|
|
2749
|
-
'
|
|
2750
|
-
'
|
|
2751
|
-
'
|
|
2752
|
-
'
|
|
2753
|
-
' +
|
|
2754
|
-
'
|
|
2755
|
-
'
|
|
2756
|
-
'
|
|
2757
|
-
'
|
|
2758
|
-
'
|
|
2759
|
-
'
|
|
2760
|
-
'
|
|
2761
|
-
'
|
|
2762
|
-
'
|
|
2763
|
-
'
|
|
2764
|
-
'
|
|
2765
|
-
'
|
|
2766
|
-
'
|
|
2767
|
-
'
|
|
2768
|
-
'
|
|
2769
|
-
'
|
|
2770
|
-
'
|
|
2771
|
-
'
|
|
2772
|
-
'</
|
|
2773
|
-
'
|
|
2774
|
-
'<div class="bottom-nav">
|
|
2775
|
-
' +
|
|
2776
|
-
' <button class="btn btn-nav" id="btn-prev-p">\u2039 Previous (\u2190)</button>
|
|
2777
|
-
' +
|
|
2778
|
-
' <span style="font-size: 14px; color: #a1a1aa;">Use Arrow Keys or Space to advance</span>
|
|
2779
|
-
' +
|
|
2780
|
-
' <button class="btn btn-nav" id="btn-next-p" style="background: #0284c7; border-color: #0284c7;">Next (\u2192 / Space) \u203A</button>
|
|
2781
|
-
' +
|
|
2782
|
-
'</div>
|
|
2783
|
-
' +
|
|
2784
|
-
'<script>
|
|
2785
|
-
' +
|
|
2786
|
-
' const bc = new BroadcastChannel("' + SYNC_CHANNEL_NAME + '");
|
|
2787
|
-
' +
|
|
2788
|
-
' let curSecs = ' + timerSeconds + ';
|
|
2789
|
-
' +
|
|
2790
|
-
' function sendCmd(action, idx) { bc.postMessage({ type: "COMMAND", action: action, index: idx }); }
|
|
2791
|
-
' +
|
|
2792
|
-
' document.getElementById("btn-prev-p").onclick = () => sendCmd("PREV");
|
|
2793
|
-
' +
|
|
2794
|
-
' document.getElementById("btn-next-p").onclick = () => sendCmd("NEXT");
|
|
2795
|
-
' +
|
|
2796
|
-
' document.getElementById("btn-reset-t").onclick = () => sendCmd("RESET_TIMER");
|
|
2797
|
-
' +
|
|
2798
|
-
' document.getElementById("btn-toggle-t").onclick = () => sendCmd("TOGGLE_TIMER");
|
|
2799
|
-
' +
|
|
2800
|
-
' let curFontSize = 19;
|
|
2801
|
-
' +
|
|
2802
|
-
' document.getElementById("font-up").onclick = () => { curFontSize += 2; document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };
|
|
2803
|
-
' +
|
|
2804
|
-
' document.getElementById("font-dn").onclick = () => { curFontSize = Math.max(12, curFontSize - 2); document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };
|
|
2805
|
-
' +
|
|
2806
|
-
' window.onkeydown = (e) => {
|
|
2807
|
-
' +
|
|
2808
|
-
' if (["ArrowRight", "Space", "PageDown"].includes(e.code)) { e.preventDefault(); sendCmd("NEXT"); }
|
|
2809
|
-
' +
|
|
2810
|
-
' else if (["ArrowLeft", "PageUp"].includes(e.code)) { e.preventDefault(); sendCmd("PREV"); }
|
|
2811
|
-
' +
|
|
2812
|
-
' };
|
|
2813
|
-
' +
|
|
2814
|
-
' bc.onmessage = (e) => {
|
|
2815
|
-
' +
|
|
2816
|
-
' if (!e.data || e.data.type !== "STATE_UPDATE") return;
|
|
2817
|
-
' +
|
|
2818
|
-
' document.getElementById("slide-num").textContent = "Slide " + (e.data.currentSlide + 1) + " / " + e.data.totalSlides;
|
|
2819
|
-
' +
|
|
2820
|
-
' document.getElementById("speaker-notes").textContent = e.data.notes || "No speaker notes for this slide.";
|
|
2821
|
-
' +
|
|
2822
|
-
' document.getElementById("next-preview-text").textContent = e.data.nextNotes ? "Next Notes: " + e.data.nextNotes : "Next: Slide " + (e.data.currentSlide + 2);
|
|
2823
|
-
' +
|
|
2824
|
-
' curSecs = e.data.timerSeconds || 0;
|
|
2825
|
-
' +
|
|
2826
|
-
' const m = String(Math.floor(curSecs / 60)).padStart(2, "0");
|
|
2827
|
-
' +
|
|
2828
|
-
' const s = String(curSecs % 60).padStart(2, "0");
|
|
2829
|
-
' +
|
|
2830
|
-
' document.getElementById("timer-val").textContent = m + ":" + s;
|
|
2831
|
-
' +
|
|
2832
|
-
' document.getElementById("btn-toggle-t").textContent = e.data.timerRunning ? "Pause" : "Start";
|
|
2833
|
-
' +
|
|
2834
|
-
' };
|
|
2835
|
-
' +
|
|
2836
|
-
' bc.postMessage({ type: "REQUEST_STATE" });
|
|
2837
|
-
' +
|
|
2838
|
-
'<' + '/script>
|
|
2839
|
-
</body>
|
|
2840
|
-
</html>';
|
|
2732
|
+
const consoleHtml = [
|
|
2733
|
+
'<!DOCTYPE html>',
|
|
2734
|
+
'<html>',
|
|
2735
|
+
'<head>',
|
|
2736
|
+
'<meta charset="UTF-8"><title>Presenter Console \u2014 ' + (document.title || 'Slides') + '</title>',
|
|
2737
|
+
'<style>',
|
|
2738
|
+
'* { box-sizing: border-box; margin: 0; padding: 0; }',
|
|
2739
|
+
'body { background: #0c0d14; color: #f4f4f5; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; display: flex; flex-direction: column; height: 100vh; overflow: hidden; user-select: none; }',
|
|
2740
|
+
'.top-bar { display: flex; align-items: center; justify-content: space-between; padding: 12px 24px; background: #141522; border-bottom: 1px solid rgba(255,255,255,0.12); }',
|
|
2741
|
+
'.timer-badge { font-family: monospace; font-size: 20px; font-weight: 700; color: #38bdf8; background: rgba(56,189,248,0.15); border: 1px solid rgba(56,189,248,0.3); padding: 4px 14px; border-radius: 8px; display: flex; align-items: center; gap: 8px; }',
|
|
2742
|
+
'.grid-container { flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 20px 24px; overflow: hidden; }',
|
|
2743
|
+
'.panel-card { background: #181926; border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; }',
|
|
2744
|
+
'.card-header { padding: 10px 16px; background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.08); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #a1a1aa; display: flex; justify-content: space-between; }',
|
|
2745
|
+
'.notes-content { flex: 1; padding: 20px; font-size: 19px; line-height: 1.7; overflow-y: auto; color: #f1f5f9; user-select: text; white-space: pre-wrap; }',
|
|
2746
|
+
'.preview-box { flex: 1; display: flex; align-items: center; justify-content: center; background: #000; overflow: hidden; padding: 16px; }',
|
|
2747
|
+
'.btn { background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.15); color: #fff; padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 600; }',
|
|
2748
|
+
'.btn:hover { background: rgba(255,255,255,0.2); }',
|
|
2749
|
+
'.btn-nav { font-size: 16px; padding: 10px 24px; border-radius: 8px; }',
|
|
2750
|
+
'.bottom-nav { display: flex; align-items: center; justify-content: space-between; padding: 14px 24px; background: #141522; border-top: 1px solid rgba(255,255,255,0.12); }',
|
|
2751
|
+
'</style>',
|
|
2752
|
+
'</head>',
|
|
2753
|
+
'<body>',
|
|
2754
|
+
'<div class="top-bar">',
|
|
2755
|
+
' <div style="font-weight: 700; font-size: 16px;">' + (document.title || 'Slide Deck') + '</div>',
|
|
2756
|
+
' <div style="display: flex; align-items: center; gap: 12px;">',
|
|
2757
|
+
' <div class="timer-badge">\u23F1 <span id="timer-val">00:00</span></div>',
|
|
2758
|
+
' <button class="btn" id="btn-toggle-t">Pause</button>',
|
|
2759
|
+
' <button class="btn" id="btn-reset-t">Reset</button>',
|
|
2760
|
+
' </div>',
|
|
2761
|
+
'</div>',
|
|
2762
|
+
'<div class="grid-container">',
|
|
2763
|
+
' <div class="panel-card">',
|
|
2764
|
+
' <div class="card-header"><span>CURRENT SLIDE</span><span id="slide-num">' + curSlideTitle + '</span></div>',
|
|
2765
|
+
' <div class="preview-box"><div style="font-size: 22px; color: #94a3b8; text-align: center;">Active Slide On Screen<br/><span style="font-size: 14px; color: #38bdf8;">(Broadcasting Synced)</span></div></div>',
|
|
2766
|
+
' <div class="card-header" style="border-top: 1px solid rgba(255,255,255,0.08);"><span>NEXT SLIDE PREVIEW</span></div>',
|
|
2767
|
+
' <div style="padding: 12px 16px; font-size: 14px; color: #94a3b8; background: rgba(0,0,0,0.3); min-height: 80px;" id="next-preview-text">Upcoming: Slide ' + (currentSlide + 2) + '</div>',
|
|
2768
|
+
' </div>',
|
|
2769
|
+
' <div class="panel-card">',
|
|
2770
|
+
' <div class="card-header"><span>SPEAKER NOTES / TALK TRACK</span><div><button class="btn" id="font-dn" style="padding: 2px 8px;">A-</button> <button class="btn" id="font-up" style="padding: 2px 8px;">A+</button></div></div>',
|
|
2771
|
+
' <div class="notes-content" id="speaker-notes">' + (currentNotes ? currentNotes : '<span style="opacity: 0.4;">No speaker notes for this slide.</span>') + '</div>',
|
|
2772
|
+
' </div>',
|
|
2773
|
+
'</div>',
|
|
2774
|
+
'<div class="bottom-nav">',
|
|
2775
|
+
' <button class="btn btn-nav" id="btn-prev-p">\u2039 Previous (\u2190)</button>',
|
|
2776
|
+
' <span style="font-size: 14px; color: #a1a1aa;">Use Arrow Keys or Space to advance</span>',
|
|
2777
|
+
' <button class="btn btn-nav" id="btn-next-p" style="background: #0284c7; border-color: #0284c7;">Next (\u2192 / Space) \u203A</button>',
|
|
2778
|
+
'</div>',
|
|
2779
|
+
'<script>',
|
|
2780
|
+
' const bc = new BroadcastChannel("' + SYNC_CHANNEL_NAME + '");',
|
|
2781
|
+
' let curSecs = ' + timerSeconds + ';',
|
|
2782
|
+
' function sendCmd(action, idx) { bc.postMessage({ type: "COMMAND", action: action, index: idx }); }',
|
|
2783
|
+
' document.getElementById("btn-prev-p").onclick = () => sendCmd("PREV");',
|
|
2784
|
+
' document.getElementById("btn-next-p").onclick = () => sendCmd("NEXT");',
|
|
2785
|
+
' document.getElementById("btn-reset-t").onclick = () => sendCmd("RESET_TIMER");',
|
|
2786
|
+
' document.getElementById("btn-toggle-t").onclick = () => sendCmd("TOGGLE_TIMER");',
|
|
2787
|
+
' let curFontSize = 19;',
|
|
2788
|
+
' document.getElementById("font-up").onclick = () => { curFontSize += 2; document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };',
|
|
2789
|
+
' document.getElementById("font-dn").onclick = () => { curFontSize = Math.max(12, curFontSize - 2); document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };',
|
|
2790
|
+
' window.onkeydown = (e) => {',
|
|
2791
|
+
' if (["ArrowRight", "Space", "PageDown"].includes(e.code)) { e.preventDefault(); sendCmd("NEXT"); }',
|
|
2792
|
+
' else if (["ArrowLeft", "PageUp"].includes(e.code)) { e.preventDefault(); sendCmd("PREV"); }',
|
|
2793
|
+
' };',
|
|
2794
|
+
' bc.onmessage = (e) => {',
|
|
2795
|
+
' if (!e.data || e.data.type !== "STATE_UPDATE") return;',
|
|
2796
|
+
' document.getElementById("slide-num").textContent = "Slide " + (e.data.currentSlide + 1) + " / " + e.data.totalSlides;',
|
|
2797
|
+
' document.getElementById("speaker-notes").textContent = e.data.notes || "No speaker notes for this slide.";',
|
|
2798
|
+
' document.getElementById("next-preview-text").textContent = e.data.nextNotes ? "Next Notes: " + e.data.nextNotes : "Next: Slide " + (e.data.currentSlide + 2);',
|
|
2799
|
+
' curSecs = e.data.timerSeconds || 0;',
|
|
2800
|
+
' const m = String(Math.floor(curSecs / 60)).padStart(2, "0");',
|
|
2801
|
+
' const s = String(curSecs % 60).padStart(2, "0");',
|
|
2802
|
+
' document.getElementById("timer-val").textContent = m + ":" + s;',
|
|
2803
|
+
' document.getElementById("btn-toggle-t").textContent = e.data.timerRunning ? "Pause" : "Start";',
|
|
2804
|
+
' };',
|
|
2805
|
+
' bc.postMessage({ type: "REQUEST_STATE" });',
|
|
2806
|
+
'<' + '/script>',
|
|
2807
|
+
'</body>',
|
|
2808
|
+
'</html>'
|
|
2809
|
+
].join('\\n');
|
|
2841
2810
|
|
|
2842
2811
|
win.document.open();
|
|
2843
2812
|
win.document.write(consoleHtml);
|
|
@@ -2853,8 +2822,7 @@ function generateHtmlShell(options) {
|
|
|
2853
2822
|
const card = document.createElement('div');
|
|
2854
2823
|
card.className = 'deck-notes-card';
|
|
2855
2824
|
card.setAttribute('data-for-slide', String(idx));
|
|
2856
|
-
card.innerHTML = '<div class="deck-notes-card-header"><span>\u{1F4DD}</span><span>Presenter Notes (Slide ' + (idx + 1) + ')</span></div><div>' + notes.
|
|
2857
|
-
/g, '<br/>') + '</div>';
|
|
2825
|
+
card.innerHTML = '<div class="deck-notes-card-header"><span>\u{1F4DD}</span><span>Presenter Notes (Slide ' + (idx + 1) + ')</span></div><div>' + notes.split('\\n').join('<br/>') + '</div>';
|
|
2858
2826
|
slide.after(card);
|
|
2859
2827
|
}
|
|
2860
2828
|
});
|
|
@@ -3194,8 +3162,7 @@ function generateHtmlShell(options) {
|
|
|
3194
3162
|
if (scalePanel) scalePanel.style.display = 'none';
|
|
3195
3163
|
|
|
3196
3164
|
// Take snapshot of full HTML
|
|
3197
|
-
let cleanHtml = '<!DOCTYPE html>
|
|
3198
|
-
' + document.documentElement.outerHTML;
|
|
3165
|
+
let cleanHtml = '<!DOCTYPE html>' + '\\n' + document.documentElement.outerHTML;
|
|
3199
3166
|
|
|
3200
3167
|
// Clean any temporary runtime inline styles or attributes
|
|
3201
3168
|
cleanHtml = cleanHtml
|
|
@@ -3205,28 +3172,20 @@ function generateHtmlShell(options) {
|
|
|
3205
3172
|
.replace(/class="edit-toggle[^"]*"/g, 'class="edit-toggle"');
|
|
3206
3173
|
|
|
3207
3174
|
// Embed current scale settings into :root style definition so exported HTML is permanently styled with chosen scales
|
|
3208
|
-
const scaleVarsReplacement =
|
|
3209
|
-
'--scale-mode: ' + scaleState.mode + ';
|
|
3210
|
-
' +
|
|
3211
|
-
' --scale-
|
|
3212
|
-
' +
|
|
3213
|
-
' --scale-
|
|
3214
|
-
' +
|
|
3215
|
-
' --scale-
|
|
3216
|
-
' +
|
|
3217
|
-
' --scale-code: ' + scaleState.code + ';
|
|
3218
|
-
' +
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
' +
|
|
3223
|
-
' --scale-body-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.body) + ';
|
|
3224
|
-
' +
|
|
3225
|
-
' --scale-code-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.code) + ';
|
|
3226
|
-
' +
|
|
3227
|
-
' --scale-spacing-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.spacing) + ';';
|
|
3228
|
-
|
|
3229
|
-
cleanHtml = cleanHtml.replace(/--scale-mode:s*unified;[sS]*?--scale-spacing-eff:s*1.0;/, scaleVarsReplacement);
|
|
3175
|
+
const scaleVarsReplacement = [
|
|
3176
|
+
'--scale-mode: ' + scaleState.mode + ';',
|
|
3177
|
+
' --scale-factor: ' + scaleState.factor + ';',
|
|
3178
|
+
' --scale-headings: ' + scaleState.headings + ';',
|
|
3179
|
+
' --scale-body: ' + scaleState.body + ';',
|
|
3180
|
+
' --scale-code: ' + scaleState.code + ';',
|
|
3181
|
+
' --scale-spacing: ' + scaleState.spacing + ';',
|
|
3182
|
+
' --scale-headings-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.headings) + ';',
|
|
3183
|
+
' --scale-body-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.body) + ';',
|
|
3184
|
+
' --scale-code-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.code) + ';',
|
|
3185
|
+
' --scale-spacing-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.spacing) + ';'
|
|
3186
|
+
].join('\\n');
|
|
3187
|
+
|
|
3188
|
+
cleanHtml = cleanHtml.replace(/--scale-mode:\\s*[^;]+;[\\s\\S]*?--scale-spacing-eff:\\s*[^;]+;/, scaleVarsReplacement);
|
|
3230
3189
|
|
|
3231
3190
|
// Create Blob and trigger download
|
|
3232
3191
|
const blob = new Blob([cleanHtml], { type: 'text/html;charset=utf-8' });
|
|
@@ -3395,6 +3354,8 @@ function generateHtmlShell(options) {
|
|
|
3395
3354
|
applyScales();
|
|
3396
3355
|
} else if (e.data.type === 'TOGGLE_SCALE_PANEL') {
|
|
3397
3356
|
toggleScalePanel();
|
|
3357
|
+
} else if (e.data.type === 'RESIZE') {
|
|
3358
|
+
resizeCanvas();
|
|
3398
3359
|
}
|
|
3399
3360
|
});
|
|
3400
3361
|
|
|
@@ -3431,7 +3392,8 @@ function compileHtmlDeck(deckData, options) {
|
|
|
3431
3392
|
theme,
|
|
3432
3393
|
slidesHtml,
|
|
3433
3394
|
slideCount,
|
|
3434
|
-
customHeadTags: options?.customHeadTags
|
|
3395
|
+
customHeadTags: options?.customHeadTags,
|
|
3396
|
+
deckId: deckData?.id || options?.deckId
|
|
3435
3397
|
});
|
|
3436
3398
|
return {
|
|
3437
3399
|
html: fullHtml,
|
|
@@ -3442,5 +3404,5 @@ function compileHtmlDeck(deckData, options) {
|
|
|
3442
3404
|
}
|
|
3443
3405
|
|
|
3444
3406
|
export { HTML_SLIDE_PRESETS, HTML_THEMES, SLIDE_LAYOUT_PRESETS, compileHtmlDeck, generateHtmlShell, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, removeSlideElementFromMarkdown, resolveHtmlTheme, serializeLayoutToComment, splitMarkdownSlides, updateSlideLayoutInMarkdown, updateSlideTextInMarkdown };
|
|
3445
|
-
//# sourceMappingURL=chunk-
|
|
3446
|
-
//# sourceMappingURL=chunk-
|
|
3407
|
+
//# sourceMappingURL=chunk-YPYAP4TF.js.map
|
|
3408
|
+
//# sourceMappingURL=chunk-YPYAP4TF.js.map
|