@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
|
@@ -1282,9 +1282,9 @@ var HTML_SLIDE_PRESETS = {
|
|
|
1282
1282
|
|
|
1283
1283
|
// src/html-engine/shell.ts
|
|
1284
1284
|
function generateHtmlShell(options) {
|
|
1285
|
-
const { title, theme, slidesHtml, slideCount, customHeadTags = "" } = options;
|
|
1285
|
+
const { title, theme, slidesHtml, slideCount, customHeadTags = "", deckId = "" } = options;
|
|
1286
1286
|
return `<!DOCTYPE html>
|
|
1287
|
-
<html lang="en" class="${theme.scheme}">
|
|
1287
|
+
<html lang="en" class="${theme.scheme}"${deckId ? ` data-deck-id="${deckId}"` : ""}>
|
|
1288
1288
|
<head>
|
|
1289
1289
|
<meta charset="UTF-8">
|
|
1290
1290
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
@@ -1298,6 +1298,7 @@ function generateHtmlShell(options) {
|
|
|
1298
1298
|
<!-- Core Presentation Styling & 1920x1080 Scaled Tailwind Configuration -->
|
|
1299
1299
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
1300
1300
|
<script>
|
|
1301
|
+
window.tailwind = window.tailwind || {};
|
|
1301
1302
|
tailwind.config = {
|
|
1302
1303
|
darkMode: 'class',
|
|
1303
1304
|
theme: {
|
|
@@ -1421,6 +1422,7 @@ function generateHtmlShell(options) {
|
|
|
1421
1422
|
left: 50%;
|
|
1422
1423
|
width: 1920px;
|
|
1423
1424
|
height: 1080px;
|
|
1425
|
+
transform: translate(-50%, -50%);
|
|
1424
1426
|
transform-origin: center center;
|
|
1425
1427
|
background-color: var(--bg);
|
|
1426
1428
|
overflow: hidden;
|
|
@@ -2239,7 +2241,7 @@ function generateHtmlShell(options) {
|
|
|
2239
2241
|
<!-- WYSIWYG Inline Edit UI (Level 1) -->
|
|
2240
2242
|
<div class="edit-hotzone" id="edit-hotzone"></div>
|
|
2241
2243
|
<button class="edit-toggle" id="btn-edit-toggle" title="Toggle Inline Edit Mode (E)">
|
|
2242
|
-
<
|
|
2244
|
+
<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>
|
|
2243
2245
|
<span id="edit-toggle-label">Edit Mode (E)</span>
|
|
2244
2246
|
</button>
|
|
2245
2247
|
|
|
@@ -2254,7 +2256,9 @@ function generateHtmlShell(options) {
|
|
|
2254
2256
|
<button type="button" class="mode-tab active" id="tab-mode-unified">Unified</button>
|
|
2255
2257
|
<button type="button" class="mode-tab" id="tab-mode-independent">Independent</button>
|
|
2256
2258
|
</div>
|
|
2257
|
-
<button type="button" class="scale-panel-close" id="btn-scale-panel-close" title="Close Panel"
|
|
2259
|
+
<button type="button" class="scale-panel-close" id="btn-scale-panel-close" title="Close Panel" style="display: flex; align-items: center; justify-content: center;">
|
|
2260
|
+
<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>
|
|
2261
|
+
</button>
|
|
2258
2262
|
</div>
|
|
2259
2263
|
|
|
2260
2264
|
<!-- Unified Mode Content -->
|
|
@@ -2304,7 +2308,10 @@ function generateHtmlShell(options) {
|
|
|
2304
2308
|
<input type="range" id="input-scale-spacing" min="70" max="150" value="100" class="scale-range-slider" />
|
|
2305
2309
|
</div>
|
|
2306
2310
|
<div class="scale-independent-footer">
|
|
2307
|
-
<button type="button" class="btn-reset-scales" id="btn-reset-scales"
|
|
2311
|
+
<button type="button" class="btn-reset-scales" id="btn-reset-scales" style="display: flex; align-items: center; gap: 4px;">
|
|
2312
|
+
<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>
|
|
2313
|
+
<span>Reset All</span>
|
|
2314
|
+
</button>
|
|
2308
2315
|
</div>
|
|
2309
2316
|
</div>
|
|
2310
2317
|
</div>
|
|
@@ -2317,13 +2324,22 @@ function generateHtmlShell(options) {
|
|
|
2317
2324
|
<button class="edit-bar-btn" id="btn-format-underline" title="Underline (Cmd+U)"><u>U</u></button>
|
|
2318
2325
|
<div class="edit-bar-divider"></div>
|
|
2319
2326
|
<button class="edit-bar-btn" id="btn-editbar-scale" title="Tune Element Scales (Unified / Independent)">
|
|
2320
|
-
<
|
|
2327
|
+
<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>
|
|
2321
2328
|
<span>Scale</span>
|
|
2322
2329
|
</button>
|
|
2323
2330
|
<div class="edit-bar-divider"></div>
|
|
2324
|
-
<button class="edit-bar-btn" id="btn-reset-edits" title="Restore original content"
|
|
2325
|
-
|
|
2326
|
-
|
|
2331
|
+
<button class="edit-bar-btn" id="btn-reset-edits" title="Restore original content">
|
|
2332
|
+
<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>
|
|
2333
|
+
<span>Reset</span>
|
|
2334
|
+
</button>
|
|
2335
|
+
<button class="edit-bar-btn save-btn" id="btn-save-html" title="Save and download clean HTML file">
|
|
2336
|
+
<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>
|
|
2337
|
+
<span>Save HTML</span>
|
|
2338
|
+
</button>
|
|
2339
|
+
<button class="edit-bar-btn" id="btn-done-edit" title="Done editing (E)">
|
|
2340
|
+
<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>
|
|
2341
|
+
<span>Done</span>
|
|
2342
|
+
</button>
|
|
2327
2343
|
</div>
|
|
2328
2344
|
|
|
2329
2345
|
<!-- Presenter Drawer (Quick In-Page Notes & Timer) -->
|
|
@@ -2332,15 +2348,18 @@ function generateHtmlShell(options) {
|
|
|
2332
2348
|
<div class="presenter-meta-group">
|
|
2333
2349
|
<span style="font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #a1a1aa;">Presenter Console</span>
|
|
2334
2350
|
<div class="presenter-timer-badge">
|
|
2335
|
-
<
|
|
2351
|
+
<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>
|
|
2336
2352
|
<span id="presenter-timer-text">00:00</span>
|
|
2337
2353
|
</div>
|
|
2338
2354
|
</div>
|
|
2339
2355
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
2340
|
-
<button type="button" class="btn-reset-scales" id="btn-open-dual-presenter" title="Open separate synced presenter console window for multi-monitor display">
|
|
2341
|
-
<span>Launch 2nd Window
|
|
2356
|
+
<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;">
|
|
2357
|
+
<span>Launch 2nd Window</span>
|
|
2358
|
+
<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>
|
|
2359
|
+
</button>
|
|
2360
|
+
<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;">
|
|
2361
|
+
<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>
|
|
2342
2362
|
</button>
|
|
2343
|
-
<button type="button" class="scale-panel-close" id="btn-close-presenter-drawer" title="Close Drawer (P)">\u2715</button>
|
|
2344
2363
|
</div>
|
|
2345
2364
|
</div>
|
|
2346
2365
|
<div class="presenter-notes-box" id="presenter-notes-text">
|
|
@@ -2360,11 +2379,14 @@ function generateHtmlShell(options) {
|
|
|
2360
2379
|
<span style="user-select: none;">In k\xE8m ghi ch\xFA gi\u1EA3ng vi\xEAn (Handout / Teacher Notes)</span>
|
|
2361
2380
|
</label>
|
|
2362
2381
|
<p style="font-size: 12px; color: #a1a1aa; line-height: 1.5; margin: 0;">
|
|
2363
|
-
\
|
|
2382
|
+
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%.
|
|
2364
2383
|
</p>
|
|
2365
2384
|
<div class="print-dialog-actions">
|
|
2366
2385
|
<button type="button" class="btn-reset-scales" id="btn-cancel-print">H\u1EE7y</button>
|
|
2367
|
-
<button type="button" class="edit-bar-btn save-btn" id="btn-start-print" style="padding: 6px 16px;
|
|
2386
|
+
<button type="button" class="edit-bar-btn save-btn" id="btn-start-print" style="padding: 6px 16px; display: flex; align-items: center; gap: 6px;">
|
|
2387
|
+
<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>
|
|
2388
|
+
<span>In ngay (Print)</span>
|
|
2389
|
+
</button>
|
|
2368
2390
|
</div>
|
|
2369
2391
|
</div>
|
|
2370
2392
|
</div>
|
|
@@ -2388,7 +2410,7 @@ function generateHtmlShell(options) {
|
|
|
2388
2410
|
<button class="control-btn" id="btn-controls-print" title="Print & Export PDF (Cmd+P)">
|
|
2389
2411
|
<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>
|
|
2390
2412
|
</button>
|
|
2391
|
-
<button class="control-btn" id="btn-controls-scale" title="Tune Scale
|
|
2413
|
+
<button class="control-btn" id="btn-controls-scale" title="Tune Scale">
|
|
2392
2414
|
<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>
|
|
2393
2415
|
</button>
|
|
2394
2416
|
<button class="control-btn" id="btn-fullscreen" title="Toggle Fullscreen (F)">
|
|
@@ -2401,10 +2423,21 @@ function generateHtmlShell(options) {
|
|
|
2401
2423
|
const TOTAL_SLIDES = ${slideCount};
|
|
2402
2424
|
let currentSlide = 0;
|
|
2403
2425
|
let isEditMode = false;
|
|
2404
|
-
const STORAGE_KEY = 'deck_edit_' + encodeURIComponent(document.title.trim() || 'default');
|
|
2405
|
-
const originalCanvasHtml = document.getElementById('canvas').innerHTML;
|
|
2406
|
-
|
|
2407
2426
|
const canvas = document.getElementById('canvas');
|
|
2427
|
+
const originalCanvasHtml = canvas ? canvas.innerHTML : '';
|
|
2428
|
+
|
|
2429
|
+
function computeDeckContentHash(str) {
|
|
2430
|
+
let h = 0;
|
|
2431
|
+
for (let i = 0; i < str.length; i++) {
|
|
2432
|
+
h = (Math.imul(31, h) + str.charCodeAt(i)) | 0;
|
|
2433
|
+
}
|
|
2434
|
+
return Math.abs(h).toString(36);
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
const deckIdAttr = document.documentElement.getAttribute('data-deck-id');
|
|
2438
|
+
const contentHash = computeDeckContentHash(originalCanvasHtml);
|
|
2439
|
+
const deckKeyPrefix = deckIdAttr ? encodeURIComponent(deckIdAttr) : (encodeURIComponent(document.title.trim() || 'deck') + '_' + contentHash);
|
|
2440
|
+
const STORAGE_KEY = 'deck_edit_' + deckKeyPrefix;
|
|
2408
2441
|
const slides = document.querySelectorAll('.slide-page');
|
|
2409
2442
|
const progressBar = document.getElementById('progress-bar');
|
|
2410
2443
|
const counter = document.getElementById('slide-counter');
|
|
@@ -2464,7 +2497,7 @@ function generateHtmlShell(options) {
|
|
|
2464
2497
|
let timerInterval = null;
|
|
2465
2498
|
let isTimerRunning = false;
|
|
2466
2499
|
|
|
2467
|
-
const SCALE_STORAGE_KEY = 'deck_scale_' +
|
|
2500
|
+
const SCALE_STORAGE_KEY = 'deck_scale_' + deckKeyPrefix;
|
|
2468
2501
|
let scaleState = {
|
|
2469
2502
|
mode: 'unified', // 'unified' | 'independent'
|
|
2470
2503
|
factor: 1.0,
|
|
@@ -2488,8 +2521,9 @@ function generateHtmlShell(options) {
|
|
|
2488
2521
|
// Auto-scale 1920x1080 canvas to fit window
|
|
2489
2522
|
function resizeCanvas() {
|
|
2490
2523
|
if (isDeckMode) return;
|
|
2491
|
-
const vw = window.innerWidth;
|
|
2492
|
-
const vh = window.innerHeight;
|
|
2524
|
+
const vw = window.innerWidth || document.documentElement.clientWidth || 1920;
|
|
2525
|
+
const vh = window.innerHeight || document.documentElement.clientHeight || 1080;
|
|
2526
|
+
if (vw <= 0 || vh <= 0) return;
|
|
2493
2527
|
const scaleX = vw / 1920;
|
|
2494
2528
|
const scaleY = vh / 1080;
|
|
2495
2529
|
const scale = Math.min(scaleX, scaleY);
|
|
@@ -2497,7 +2531,10 @@ function generateHtmlShell(options) {
|
|
|
2497
2531
|
}
|
|
2498
2532
|
|
|
2499
2533
|
window.addEventListener('resize', resizeCanvas);
|
|
2534
|
+
window.addEventListener('load', resizeCanvas);
|
|
2535
|
+
document.addEventListener('DOMContentLoaded', resizeCanvas);
|
|
2500
2536
|
resizeCanvas();
|
|
2537
|
+
requestAnimationFrame(resizeCanvas);
|
|
2501
2538
|
|
|
2502
2539
|
function getSlideNotes(slideIndex) {
|
|
2503
2540
|
if (slideIndex < 0 || slideIndex >= slides.length) return '';
|
|
@@ -2670,8 +2707,7 @@ function generateHtmlShell(options) {
|
|
|
2670
2707
|
if (!presenterNotesText) return;
|
|
2671
2708
|
const notes = getSlideNotes(currentSlide);
|
|
2672
2709
|
if (notes && notes.trim()) {
|
|
2673
|
-
presenterNotesText.innerHTML = notes.
|
|
2674
|
-
/g, '<br/>');
|
|
2710
|
+
presenterNotesText.innerHTML = notes.split('\\n').join('<br/>');
|
|
2675
2711
|
} else {
|
|
2676
2712
|
presenterNotesText.innerHTML = '<span style="opacity: 0.5; font-style: italic;">No speaker notes for Slide ' + (currentSlide + 1) + '.</span>';
|
|
2677
2713
|
}
|
|
@@ -2688,7 +2724,7 @@ function generateHtmlShell(options) {
|
|
|
2688
2724
|
|
|
2689
2725
|
function openPresenterConsole() {
|
|
2690
2726
|
startTimer();
|
|
2691
|
-
const popupName = 'PresenterConsole_' + encodeURIComponent(document.title.replace(/
|
|
2727
|
+
const popupName = 'PresenterConsole_' + encodeURIComponent(document.title.replace(/[^a-zA-Z0-9_]/g, ''));
|
|
2692
2728
|
const win = window.open('', popupName, 'width=1100,height=720,menubar=no,toolbar=no,location=no,status=no');
|
|
2693
2729
|
if (!win) {
|
|
2694
2730
|
togglePresenterDrawer();
|
|
@@ -2699,151 +2735,84 @@ function generateHtmlShell(options) {
|
|
|
2699
2735
|
const currentNotes = getSlideNotes(currentSlide);
|
|
2700
2736
|
const curSlideTitle = 'Slide ' + (currentSlide + 1) + ' / ' + TOTAL_SLIDES;
|
|
2701
2737
|
|
|
2702
|
-
const consoleHtml =
|
|
2703
|
-
|
|
2704
|
-
<
|
|
2705
|
-
'
|
|
2706
|
-
'<meta charset="UTF-8"><title>Presenter Console \u2014 ' + (document.title || 'Slides') + '</title>
|
|
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
|
-
'
|
|
2735
|
-
'
|
|
2736
|
-
'
|
|
2737
|
-
</
|
|
2738
|
-
|
|
2739
|
-
'
|
|
2740
|
-
'<div class="
|
|
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
|
-
'
|
|
2775
|
-
'
|
|
2776
|
-
'
|
|
2777
|
-
'
|
|
2778
|
-
'</
|
|
2779
|
-
'
|
|
2780
|
-
'<div class="bottom-nav">
|
|
2781
|
-
' +
|
|
2782
|
-
' <button class="btn btn-nav" id="btn-prev-p">\u2039 Previous (\u2190)</button>
|
|
2783
|
-
' +
|
|
2784
|
-
' <span style="font-size: 14px; color: #a1a1aa;">Use Arrow Keys or Space to advance</span>
|
|
2785
|
-
' +
|
|
2786
|
-
' <button class="btn btn-nav" id="btn-next-p" style="background: #0284c7; border-color: #0284c7;">Next (\u2192 / Space) \u203A</button>
|
|
2787
|
-
' +
|
|
2788
|
-
'</div>
|
|
2789
|
-
' +
|
|
2790
|
-
'<script>
|
|
2791
|
-
' +
|
|
2792
|
-
' const bc = new BroadcastChannel("' + SYNC_CHANNEL_NAME + '");
|
|
2793
|
-
' +
|
|
2794
|
-
' let curSecs = ' + timerSeconds + ';
|
|
2795
|
-
' +
|
|
2796
|
-
' function sendCmd(action, idx) { bc.postMessage({ type: "COMMAND", action: action, index: idx }); }
|
|
2797
|
-
' +
|
|
2798
|
-
' document.getElementById("btn-prev-p").onclick = () => sendCmd("PREV");
|
|
2799
|
-
' +
|
|
2800
|
-
' document.getElementById("btn-next-p").onclick = () => sendCmd("NEXT");
|
|
2801
|
-
' +
|
|
2802
|
-
' document.getElementById("btn-reset-t").onclick = () => sendCmd("RESET_TIMER");
|
|
2803
|
-
' +
|
|
2804
|
-
' document.getElementById("btn-toggle-t").onclick = () => sendCmd("TOGGLE_TIMER");
|
|
2805
|
-
' +
|
|
2806
|
-
' let curFontSize = 19;
|
|
2807
|
-
' +
|
|
2808
|
-
' document.getElementById("font-up").onclick = () => { curFontSize += 2; document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };
|
|
2809
|
-
' +
|
|
2810
|
-
' document.getElementById("font-dn").onclick = () => { curFontSize = Math.max(12, curFontSize - 2); document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };
|
|
2811
|
-
' +
|
|
2812
|
-
' window.onkeydown = (e) => {
|
|
2813
|
-
' +
|
|
2814
|
-
' if (["ArrowRight", "Space", "PageDown"].includes(e.code)) { e.preventDefault(); sendCmd("NEXT"); }
|
|
2815
|
-
' +
|
|
2816
|
-
' else if (["ArrowLeft", "PageUp"].includes(e.code)) { e.preventDefault(); sendCmd("PREV"); }
|
|
2817
|
-
' +
|
|
2818
|
-
' };
|
|
2819
|
-
' +
|
|
2820
|
-
' bc.onmessage = (e) => {
|
|
2821
|
-
' +
|
|
2822
|
-
' if (!e.data || e.data.type !== "STATE_UPDATE") return;
|
|
2823
|
-
' +
|
|
2824
|
-
' document.getElementById("slide-num").textContent = "Slide " + (e.data.currentSlide + 1) + " / " + e.data.totalSlides;
|
|
2825
|
-
' +
|
|
2826
|
-
' document.getElementById("speaker-notes").textContent = e.data.notes || "No speaker notes for this slide.";
|
|
2827
|
-
' +
|
|
2828
|
-
' document.getElementById("next-preview-text").textContent = e.data.nextNotes ? "Next Notes: " + e.data.nextNotes : "Next: Slide " + (e.data.currentSlide + 2);
|
|
2829
|
-
' +
|
|
2830
|
-
' curSecs = e.data.timerSeconds || 0;
|
|
2831
|
-
' +
|
|
2832
|
-
' const m = String(Math.floor(curSecs / 60)).padStart(2, "0");
|
|
2833
|
-
' +
|
|
2834
|
-
' const s = String(curSecs % 60).padStart(2, "0");
|
|
2835
|
-
' +
|
|
2836
|
-
' document.getElementById("timer-val").textContent = m + ":" + s;
|
|
2837
|
-
' +
|
|
2838
|
-
' document.getElementById("btn-toggle-t").textContent = e.data.timerRunning ? "Pause" : "Start";
|
|
2839
|
-
' +
|
|
2840
|
-
' };
|
|
2841
|
-
' +
|
|
2842
|
-
' bc.postMessage({ type: "REQUEST_STATE" });
|
|
2843
|
-
' +
|
|
2844
|
-
'<' + '/script>
|
|
2845
|
-
</body>
|
|
2846
|
-
</html>';
|
|
2738
|
+
const consoleHtml = [
|
|
2739
|
+
'<!DOCTYPE html>',
|
|
2740
|
+
'<html>',
|
|
2741
|
+
'<head>',
|
|
2742
|
+
'<meta charset="UTF-8"><title>Presenter Console \u2014 ' + (document.title || 'Slides') + '</title>',
|
|
2743
|
+
'<style>',
|
|
2744
|
+
'* { box-sizing: border-box; margin: 0; padding: 0; }',
|
|
2745
|
+
'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; }',
|
|
2746
|
+
'.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); }',
|
|
2747
|
+
'.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; }',
|
|
2748
|
+
'.grid-container { flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 20px 24px; overflow: hidden; }',
|
|
2749
|
+
'.panel-card { background: #181926; border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; }',
|
|
2750
|
+
'.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; }',
|
|
2751
|
+
'.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; }',
|
|
2752
|
+
'.preview-box { flex: 1; display: flex; align-items: center; justify-content: center; background: #000; overflow: hidden; padding: 16px; }',
|
|
2753
|
+
'.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; }',
|
|
2754
|
+
'.btn:hover { background: rgba(255,255,255,0.2); }',
|
|
2755
|
+
'.btn-nav { font-size: 16px; padding: 10px 24px; border-radius: 8px; }',
|
|
2756
|
+
'.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); }',
|
|
2757
|
+
'</style>',
|
|
2758
|
+
'</head>',
|
|
2759
|
+
'<body>',
|
|
2760
|
+
'<div class="top-bar">',
|
|
2761
|
+
' <div style="font-weight: 700; font-size: 16px;">' + (document.title || 'Slide Deck') + '</div>',
|
|
2762
|
+
' <div style="display: flex; align-items: center; gap: 12px;">',
|
|
2763
|
+
' <div class="timer-badge">\u23F1 <span id="timer-val">00:00</span></div>',
|
|
2764
|
+
' <button class="btn" id="btn-toggle-t">Pause</button>',
|
|
2765
|
+
' <button class="btn" id="btn-reset-t">Reset</button>',
|
|
2766
|
+
' </div>',
|
|
2767
|
+
'</div>',
|
|
2768
|
+
'<div class="grid-container">',
|
|
2769
|
+
' <div class="panel-card">',
|
|
2770
|
+
' <div class="card-header"><span>CURRENT SLIDE</span><span id="slide-num">' + curSlideTitle + '</span></div>',
|
|
2771
|
+
' <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>',
|
|
2772
|
+
' <div class="card-header" style="border-top: 1px solid rgba(255,255,255,0.08);"><span>NEXT SLIDE PREVIEW</span></div>',
|
|
2773
|
+
' <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>',
|
|
2774
|
+
' </div>',
|
|
2775
|
+
' <div class="panel-card">',
|
|
2776
|
+
' <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>',
|
|
2777
|
+
' <div class="notes-content" id="speaker-notes">' + (currentNotes ? currentNotes : '<span style="opacity: 0.4;">No speaker notes for this slide.</span>') + '</div>',
|
|
2778
|
+
' </div>',
|
|
2779
|
+
'</div>',
|
|
2780
|
+
'<div class="bottom-nav">',
|
|
2781
|
+
' <button class="btn btn-nav" id="btn-prev-p">\u2039 Previous (\u2190)</button>',
|
|
2782
|
+
' <span style="font-size: 14px; color: #a1a1aa;">Use Arrow Keys or Space to advance</span>',
|
|
2783
|
+
' <button class="btn btn-nav" id="btn-next-p" style="background: #0284c7; border-color: #0284c7;">Next (\u2192 / Space) \u203A</button>',
|
|
2784
|
+
'</div>',
|
|
2785
|
+
'<script>',
|
|
2786
|
+
' const bc = new BroadcastChannel("' + SYNC_CHANNEL_NAME + '");',
|
|
2787
|
+
' let curSecs = ' + timerSeconds + ';',
|
|
2788
|
+
' function sendCmd(action, idx) { bc.postMessage({ type: "COMMAND", action: action, index: idx }); }',
|
|
2789
|
+
' document.getElementById("btn-prev-p").onclick = () => sendCmd("PREV");',
|
|
2790
|
+
' document.getElementById("btn-next-p").onclick = () => sendCmd("NEXT");',
|
|
2791
|
+
' document.getElementById("btn-reset-t").onclick = () => sendCmd("RESET_TIMER");',
|
|
2792
|
+
' document.getElementById("btn-toggle-t").onclick = () => sendCmd("TOGGLE_TIMER");',
|
|
2793
|
+
' let curFontSize = 19;',
|
|
2794
|
+
' document.getElementById("font-up").onclick = () => { curFontSize += 2; document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };',
|
|
2795
|
+
' document.getElementById("font-dn").onclick = () => { curFontSize = Math.max(12, curFontSize - 2); document.getElementById("speaker-notes").style.fontSize = curFontSize + "px"; };',
|
|
2796
|
+
' window.onkeydown = (e) => {',
|
|
2797
|
+
' if (["ArrowRight", "Space", "PageDown"].includes(e.code)) { e.preventDefault(); sendCmd("NEXT"); }',
|
|
2798
|
+
' else if (["ArrowLeft", "PageUp"].includes(e.code)) { e.preventDefault(); sendCmd("PREV"); }',
|
|
2799
|
+
' };',
|
|
2800
|
+
' bc.onmessage = (e) => {',
|
|
2801
|
+
' if (!e.data || e.data.type !== "STATE_UPDATE") return;',
|
|
2802
|
+
' document.getElementById("slide-num").textContent = "Slide " + (e.data.currentSlide + 1) + " / " + e.data.totalSlides;',
|
|
2803
|
+
' document.getElementById("speaker-notes").textContent = e.data.notes || "No speaker notes for this slide.";',
|
|
2804
|
+
' document.getElementById("next-preview-text").textContent = e.data.nextNotes ? "Next Notes: " + e.data.nextNotes : "Next: Slide " + (e.data.currentSlide + 2);',
|
|
2805
|
+
' curSecs = e.data.timerSeconds || 0;',
|
|
2806
|
+
' const m = String(Math.floor(curSecs / 60)).padStart(2, "0");',
|
|
2807
|
+
' const s = String(curSecs % 60).padStart(2, "0");',
|
|
2808
|
+
' document.getElementById("timer-val").textContent = m + ":" + s;',
|
|
2809
|
+
' document.getElementById("btn-toggle-t").textContent = e.data.timerRunning ? "Pause" : "Start";',
|
|
2810
|
+
' };',
|
|
2811
|
+
' bc.postMessage({ type: "REQUEST_STATE" });',
|
|
2812
|
+
'<' + '/script>',
|
|
2813
|
+
'</body>',
|
|
2814
|
+
'</html>'
|
|
2815
|
+
].join('\\n');
|
|
2847
2816
|
|
|
2848
2817
|
win.document.open();
|
|
2849
2818
|
win.document.write(consoleHtml);
|
|
@@ -2859,8 +2828,7 @@ function generateHtmlShell(options) {
|
|
|
2859
2828
|
const card = document.createElement('div');
|
|
2860
2829
|
card.className = 'deck-notes-card';
|
|
2861
2830
|
card.setAttribute('data-for-slide', String(idx));
|
|
2862
|
-
card.innerHTML = '<div class="deck-notes-card-header"><span>\u{1F4DD}</span><span>Presenter Notes (Slide ' + (idx + 1) + ')</span></div><div>' + notes.
|
|
2863
|
-
/g, '<br/>') + '</div>';
|
|
2831
|
+
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>';
|
|
2864
2832
|
slide.after(card);
|
|
2865
2833
|
}
|
|
2866
2834
|
});
|
|
@@ -3200,8 +3168,7 @@ function generateHtmlShell(options) {
|
|
|
3200
3168
|
if (scalePanel) scalePanel.style.display = 'none';
|
|
3201
3169
|
|
|
3202
3170
|
// Take snapshot of full HTML
|
|
3203
|
-
let cleanHtml = '<!DOCTYPE html>
|
|
3204
|
-
' + document.documentElement.outerHTML;
|
|
3171
|
+
let cleanHtml = '<!DOCTYPE html>' + '\\n' + document.documentElement.outerHTML;
|
|
3205
3172
|
|
|
3206
3173
|
// Clean any temporary runtime inline styles or attributes
|
|
3207
3174
|
cleanHtml = cleanHtml
|
|
@@ -3211,28 +3178,20 @@ function generateHtmlShell(options) {
|
|
|
3211
3178
|
.replace(/class="edit-toggle[^"]*"/g, 'class="edit-toggle"');
|
|
3212
3179
|
|
|
3213
3180
|
// Embed current scale settings into :root style definition so exported HTML is permanently styled with chosen scales
|
|
3214
|
-
const scaleVarsReplacement =
|
|
3215
|
-
'--scale-mode: ' + scaleState.mode + ';
|
|
3216
|
-
' +
|
|
3217
|
-
' --scale-
|
|
3218
|
-
' +
|
|
3219
|
-
' --scale-
|
|
3220
|
-
' +
|
|
3221
|
-
' --scale-
|
|
3222
|
-
' +
|
|
3223
|
-
' --scale-code: ' + scaleState.code + ';
|
|
3224
|
-
' +
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
' +
|
|
3229
|
-
' --scale-body-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.body) + ';
|
|
3230
|
-
' +
|
|
3231
|
-
' --scale-code-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.code) + ';
|
|
3232
|
-
' +
|
|
3233
|
-
' --scale-spacing-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.spacing) + ';';
|
|
3234
|
-
|
|
3235
|
-
cleanHtml = cleanHtml.replace(/--scale-mode:s*unified;[sS]*?--scale-spacing-eff:s*1.0;/, scaleVarsReplacement);
|
|
3181
|
+
const scaleVarsReplacement = [
|
|
3182
|
+
'--scale-mode: ' + scaleState.mode + ';',
|
|
3183
|
+
' --scale-factor: ' + scaleState.factor + ';',
|
|
3184
|
+
' --scale-headings: ' + scaleState.headings + ';',
|
|
3185
|
+
' --scale-body: ' + scaleState.body + ';',
|
|
3186
|
+
' --scale-code: ' + scaleState.code + ';',
|
|
3187
|
+
' --scale-spacing: ' + scaleState.spacing + ';',
|
|
3188
|
+
' --scale-headings-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.headings) + ';',
|
|
3189
|
+
' --scale-body-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.body) + ';',
|
|
3190
|
+
' --scale-code-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.code) + ';',
|
|
3191
|
+
' --scale-spacing-eff: ' + (scaleState.mode === 'unified' ? scaleState.factor : scaleState.spacing) + ';'
|
|
3192
|
+
].join('\\n');
|
|
3193
|
+
|
|
3194
|
+
cleanHtml = cleanHtml.replace(/--scale-mode:\\s*[^;]+;[\\s\\S]*?--scale-spacing-eff:\\s*[^;]+;/, scaleVarsReplacement);
|
|
3236
3195
|
|
|
3237
3196
|
// Create Blob and trigger download
|
|
3238
3197
|
const blob = new Blob([cleanHtml], { type: 'text/html;charset=utf-8' });
|
|
@@ -3401,6 +3360,8 @@ function generateHtmlShell(options) {
|
|
|
3401
3360
|
applyScales();
|
|
3402
3361
|
} else if (e.data.type === 'TOGGLE_SCALE_PANEL') {
|
|
3403
3362
|
toggleScalePanel();
|
|
3363
|
+
} else if (e.data.type === 'RESIZE') {
|
|
3364
|
+
resizeCanvas();
|
|
3404
3365
|
}
|
|
3405
3366
|
});
|
|
3406
3367
|
|
|
@@ -3437,7 +3398,8 @@ function compileHtmlDeck(deckData, options) {
|
|
|
3437
3398
|
theme,
|
|
3438
3399
|
slidesHtml,
|
|
3439
3400
|
slideCount,
|
|
3440
|
-
customHeadTags: options?.customHeadTags
|
|
3401
|
+
customHeadTags: options?.customHeadTags,
|
|
3402
|
+
deckId: deckData?.id || options?.deckId
|
|
3441
3403
|
});
|
|
3442
3404
|
return {
|
|
3443
3405
|
html: fullHtml,
|
|
@@ -3460,5 +3422,5 @@ exports.serializeLayoutToComment = serializeLayoutToComment;
|
|
|
3460
3422
|
exports.splitMarkdownSlides = splitMarkdownSlides;
|
|
3461
3423
|
exports.updateSlideLayoutInMarkdown = updateSlideLayoutInMarkdown;
|
|
3462
3424
|
exports.updateSlideTextInMarkdown = updateSlideTextInMarkdown;
|
|
3463
|
-
//# sourceMappingURL=chunk-
|
|
3464
|
-
//# sourceMappingURL=chunk-
|
|
3425
|
+
//# sourceMappingURL=chunk-SUGKWGJJ.cjs.map
|
|
3426
|
+
//# sourceMappingURL=chunk-SUGKWGJJ.cjs.map
|