rikiki-deck 0.4.0 → 0.6.0

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.
@@ -1,5 +1,5 @@
1
- var c="rik-presenter",g=new URL("./index.js",import.meta.url).href,t=null,l=null,o=null;function p(e){let r=Array.from(e.children).filter(i=>i.tagName.toLowerCase().startsWith("deck-")),s=r.findIndex(i=>i.hasAttribute("active")),a=r[s]??null,n=r[s+1]??null,m=(a?.querySelector("deck-notes")?.textContent??"").trim(),u=document.querySelector('link[rel="stylesheet"][href*="rikiki"], link[rel="stylesheet"][href*="tokens"], link[rel="stylesheet"][href*="theme"]')?.href??"",f=Array.from(document.querySelectorAll("style")).map(i=>i.textContent??"").join(`
2
- `),h=document.querySelector('script[type="module"][data-rikiki-bundle]')?.textContent??"";return{current:s+1,total:r.length,slideHtml:a?.outerHTML??"",nextHtml:n?.outerHTML??null,notes:m,themeHref:u,inlineStyles:f,bundleHref:g,bundleInline:h}}function d(e){l&&l.postMessage({type:"state",state:p(e)})}var y=e=>`<!doctype html>
1
+ var H="rik-presenter",R=new URL("./index.js",import.meta.url).href,l=null,p=null,u=null,f=null,h=!1;async function I(){if(f)return f;let e=window.getScreenDetails;if(!e)return null;try{return f=await e.call(window),f}catch{return null}}var g=1280,y=720;function C(e){return{left:Math.round(e.availLeft+(e.availWidth-g)/2),top:Math.round(e.availTop+(e.availHeight-y)/2)}}function M(e){let{left:n,top:r}=C(e);return`popup=yes,width=${g},height=${y},left=${n},top=${r}`}function T(e,n){let{left:r,top:t}=C(n);e.resizeTo(g,y),e.moveTo(r,t)}function S(e,n){e.requestFullscreen?.({screen:n}).then(()=>{if(!u?.has(e)){document.exitFullscreen?.().catch(()=>{});return}h=!0}).catch(()=>{})}function P(){document.fullscreenElement||(h=!1)}function B(){document.removeEventListener("fullscreenchange",P),h&&document.fullscreenElement&&document.exitFullscreen?.().catch(()=>{}),h=!1}function v(e){l?.close(),l=null,p?.close(),p=null,u?.delete(e),e.presenterActive=!1,B()}function D(e){let n=Array.from(e.children).filter(i=>i.tagName.toLowerCase().startsWith("deck-")),r=n.findIndex(i=>i.hasAttribute("active")),t=n[r]??null,d=n[r+1]??null,b=(t?.querySelector("deck-notes")?.textContent??"").trim(),o=document.querySelector('link[rel="stylesheet"][href*="rikiki"], link[rel="stylesheet"][href*="tokens"], link[rel="stylesheet"][href*="theme"]')?.href??"",a=Array.from(document.querySelectorAll("style")).map(i=>i.textContent??"").join(`
2
+ `),m=document.querySelector('script[type="module"][data-rikiki-bundle]')?.textContent??"";return{current:r+1,total:n.length,slideHtml:t?.outerHTML??"",nextHtml:d?.outerHTML??null,notes:b,themeHref:o,inlineStyles:a,bundleHref:R,bundleInline:m}}function E(e){p&&p.postMessage({type:"state",state:D(e)})}var W=e=>`<!doctype html>
3
3
  <html lang="en">
4
4
  <head>
5
5
  <meta charset="utf-8">
@@ -36,7 +36,17 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
36
36
  background: #161c2e;
37
37
  }
38
38
  .panel .body { flex: 1; min-height: 0; padding: 16px; overflow: hidden; border-radius: 8px; }
39
- .panel iframe { width: 100%; height: 100%; border: 0; background: #0f1422; display: block; }
39
+ /* Preview panes center a 16:9 box so the thumbnail matches the projection
40
+ geometry regardless of the pane/window shape (issue #5) \xB7 the size
41
+ container lets the iframe size against the pane in cq units. */
42
+ #current .body, #next .body { display: grid; place-items: center; container-type: size; }
43
+ .panel iframe { border: 0; background: #0f1422; display: block; }
44
+ #current-frame, #next-frame {
45
+ aspect-ratio: 16 / 9;
46
+ width: min(100cqw, calc(100cqh * 16 / 9));
47
+ height: auto;
48
+ max-width: 100%;
49
+ }
40
50
  #notes { font-size: 17px; line-height: 1.6; white-space: pre-wrap; padding: 20px; overflow: auto; color: #e8e4f0; }
41
51
  #notes:empty::before { content: 'No notes for this slide.'; color: rgba(232,228,240,0.4); font-style: italic; }
42
52
  #footer {
@@ -60,6 +70,8 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
60
70
  }
61
71
  button:hover { background: rgba(255,255,255,0.06); }
62
72
  .ghost { color: rgba(232,228,240,0.4); }
73
+ .opt { display: inline-flex; align-items: center; gap: 6px; font: 600 13px/1 var(--rik-font-mono, monospace); color: rgba(232,228,240,0.7); cursor: pointer; user-select: none; }
74
+ .opt input { accent-color: var(--rik-accent, #8fd14f); cursor: pointer; }
63
75
  </style>
64
76
  </head>
65
77
  <body>
@@ -79,11 +91,14 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
79
91
  <div id="footer">
80
92
  <div><span id="timer">00:00</span> <button id="timer-toggle">Pause</button> <button id="timer-reset">Reset</button></div>
81
93
  <div id="counter">${e.current} / ${e.total}</div>
82
- <div><span class="ghost">P to close</span></div>
94
+ <div>
95
+ <label class="opt"><input type="checkbox" id="opt-advance" checked> Advance on click</label>
96
+ <span class="ghost">\xB7 P to close</span>
97
+ </div>
83
98
  </div>
84
99
  </div>
85
100
  <script>
86
- const channel = new BroadcastChannel('${c}');
101
+ const channel = new BroadcastChannel('${H}');
87
102
  const current = document.getElementById('current-frame');
88
103
  const next = document.getElementById('next-frame');
89
104
  const notes = document.getElementById('notes');
@@ -113,7 +128,12 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
113
128
  };
114
129
  resetBtn.onclick = () => { startedAt = Date.now(); elapsed = 0; running = true; toggleBtn.textContent = 'Pause'; };
115
130
 
116
- function wrapFrame(slideHtml) {
131
+ // Presentation options \xB7 push each change to the live deck over the channel.
132
+ document.getElementById('opt-advance').addEventListener('change', (e) => {
133
+ channel.postMessage({ type: 'config', advanceOnClick: e.target.checked });
134
+ });
135
+
136
+ function wrapFrame(slideHtml, forward) {
117
137
  const themeHref = ${JSON.stringify(e.themeHref)};
118
138
  const inlineStyles = ${JSON.stringify(e.inlineStyles)};
119
139
  const bundleHref = ${JSON.stringify(e.bundleHref)};
@@ -143,14 +163,25 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
143
163
  // Mark the cloned slide [active] so its real component CSS applies
144
164
  // (:host([active]){display:flex}) instead of forcing display via !important.
145
165
  const activeSlide = slideHtml.replace(/^(\\s*<deck-[a-z-]+)/i, '$1 active');
146
- // Render the preview in fixed-viewport mode so the slide keeps its 16:9
147
- // proportions (letterboxed) regardless of the pane's shape, and drop the
148
- // hint / nav-arrow chrome \xB7 a clean, correctly-shaped thumbnail.
166
+ // Only the "Current" pane is a control surface \xB7 it captures key/click/wheel
167
+ // and posts them to this popup window, which relays them onto the channel so
168
+ // the live deck acts on them. Coords are normalised 0..1 over the iframe.
169
+ const forwarder = forward
170
+ ? '<scr' + 'ipt>(function(){' +
171
+ 'var post=function(o){o.source="rikiki-presenter-input";parent.postMessage(o,"*");};' +
172
+ 'addEventListener("keydown",function(e){var t=e.target;if(t&&t.matches&&t.matches("input,textarea,button"))return;post({type:"key",key:e.key,shift:!!e.shiftKey});});' +
173
+ 'addEventListener("click",function(e){post({type:"click",x:e.clientX/innerWidth,y:e.clientY/innerHeight,shift:!!e.shiftKey});});' +
174
+ 'addEventListener("wheel",function(e){if(e.ctrlKey||e.metaKey)return;post({type:"wheel",x:e.clientX/innerWidth,y:e.clientY/innerHeight,dx:e.deltaX,dy:e.deltaY});},{passive:true});' +
175
+ '})();<' + '/scr' + 'ipt>'
176
+ : '';
177
+ // The deck always letterboxes into its logical canvas, so the slide keeps
178
+ // its 16:9 proportions regardless of the pane's shape \xB7 just drop the
179
+ // hint / nav-arrow chrome for a clean, correctly-shaped thumbnail.
149
180
  return '<!doctype html><html><head><meta charset="UTF-8">' + themeLink + themeStyle +
150
181
  bundleTag +
151
182
  '<style>html,body{margin:0;padding:0;height:100%;overflow:hidden;background:#0f1422}' +
152
183
  'deck-root{position:absolute;inset:0}</style>' +
153
- '</head><body><deck-root fixed no-hint no-arrows>' + activeSlide + '</deck-root></body></html>';
184
+ '</head><body><deck-root no-hint no-arrows no-counter preview>' + activeSlide + '</deck-root>' + forwarder + '</body></html>';
154
185
  }
155
186
 
156
187
  channel.onmessage = (e) => {
@@ -158,8 +189,8 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
158
189
  const s = e.data.state;
159
190
  counter.textContent = s.current + ' / ' + s.total;
160
191
  notes.textContent = s.notes;
161
- if (s.slideHtml) current.srcdoc = wrapFrame(s.slideHtml);
162
- if (s.nextHtml) next.srcdoc = wrapFrame(s.nextHtml);
192
+ if (s.slideHtml) current.srcdoc = wrapFrame(s.slideHtml, true);
193
+ if (s.nextHtml) next.srcdoc = wrapFrame(s.nextHtml, false);
163
194
  else next.srcdoc = '<!doctype html><html><body style="background:#0f1422;color:rgba(232,228,240,0.4);display:flex;align-items:center;justify-content:center;font-family:system-ui">End of deck</body></html>';
164
195
  };
165
196
 
@@ -173,8 +204,17 @@ ${e.themeHref?`<link rel="stylesheet" href="${e.themeHref}">`:""}
173
204
  channel.postMessage({ type: 'key', key: e.key, shift: e.shiftKey });
174
205
  });
175
206
 
207
+ // Relay input captured inside the "Current" preview iframe (key/click/wheel)
208
+ // onto the channel \xB7 the iframe is a separate browsing context so its events
209
+ // never reach this window directly \xB7 it postMessages them here instead.
210
+ window.addEventListener('message', (e) => {
211
+ const d = e.data;
212
+ if (!d || d.source !== 'rikiki-presenter-input') return;
213
+ channel.postMessage({ type: d.type, key: d.key, shift: d.shift, x: d.x, y: d.y, dx: d.dx, dy: d.dy });
214
+ });
215
+
176
216
  // Tell main window we're alive
177
217
  channel.postMessage({ type: 'hello' });
178
218
  <\/script>
179
219
  </body>
180
- </html>`;function x(e){if(o=o??new WeakSet,o.has(e)){t?.close(),t=null;return}o.add(e),l=new BroadcastChannel(c),e.addEventListener("slide-change",()=>d(e)),l.addEventListener("message",a=>{let n=a.data;n?.type==="key"&&n.key&&window.dispatchEvent(new KeyboardEvent("keydown",{key:n.key,shiftKey:!!n.shift,bubbles:!0})),n?.type==="hello"&&d(e)});let r=p(e);if(t=window.open("","rikiki-presenter","width=1280,height=800,popup=yes"),!t){console.warn("[rikiki/presenter] popup was blocked \xB7 allow popups for this site"),o.delete(e);return}t.document.open(),t.document.write(y(r)),t.document.close();let s=setInterval(()=>{t&&t.closed&&(clearInterval(s),o?.delete(e),t=null)},1e3)}export{x as installPresenter};
220
+ </html>`;function F(e,n){let r=document.elementFromPoint(e,n);for(;r?.shadowRoot;){let t=r.shadowRoot.elementFromPoint(e,n);if(!t||t===r)break;r=t}return r}function $(e,n,r){for(let t=e;t;t=t.parentElement){let d=getComputedStyle(t);if(r!==0&&t.scrollHeight>t.clientHeight&&/auto|scroll/.test(d.overflowY)||n!==0&&t.scrollWidth>t.clientWidth&&/auto|scroll/.test(d.overflowX))return t}return null}function N(e,n,r){let t=e.getBoundingClientRect();return{x:t.left+n*t.width,y:t.top+r*t.height}}function L(e,n){let{x:r,y:t}=N(e,n.x??.5,n.y??.5);return{x:r,y:t,target:F(r,t)??e}}function A(e){let n=(e??"all").trim();return n==="none"?"none":n===""||n==="all"?"wheel arrows aux":n.split(/\s+/).filter(r=>r!=="click").join(" ")||"none"}function O(e){if(u=u??new WeakSet,u.has(e)){v(e);return}u.add(e);let n=e.mouseNav;p=new BroadcastChannel(H),e.addEventListener("slide-change",()=>E(e)),p.addEventListener("message",s=>{let o=s.data;if(o?.type==="key"&&o.key)window.dispatchEvent(new KeyboardEvent("keydown",{key:o.key,shiftKey:!!o.shift,bubbles:!0}));else if(o?.type==="click"){let{x:a,y:m,target:i}=L(e,o),c={bubbles:!0,composed:!0,cancelable:!0,clientX:a,clientY:m,view:window,shiftKey:!!o.shift};i.dispatchEvent(new PointerEvent("pointerdown",{...c,pointerId:1,isPrimary:!0})),i.dispatchEvent(new PointerEvent("pointerup",{...c,pointerId:1,isPrimary:!0})),i.dispatchEvent(new MouseEvent("click",c))}else if(o?.type==="wheel"){let{x:a,y:m,target:i}=L(e,o),c=o.dx??0,k=o.dy??0,x=$(i,c,k);x?x.scrollBy({left:c,top:k}):i.dispatchEvent(new WheelEvent("wheel",{bubbles:!0,composed:!0,cancelable:!0,clientX:a,clientY:m,deltaX:c,deltaY:k,view:window}))}else o?.type==="config"&&typeof o.advanceOnClick=="boolean"?e.mouseNav=o.advanceOnClick?n:A(n):o?.type==="hello"&&E(e)});let r=f,t=r?.screens.find(s=>s!==r.currentScreen)??null;t?S(e,t):I().then(s=>{if(!s)return;let o=s.screens.find(a=>a!==s.currentScreen);o&&S(e,o),l&&s.currentScreen&&T(l,s.currentScreen)});let d=D(e),w=r?.currentScreen?M(r.currentScreen):`popup=yes,width=${g},height=${y}`;if(l=window.open("","rikiki-presenter",w),!l){console.warn("[rikiki/presenter] popup was blocked \xB7 allow popups for this site"),v(e);return}l.document.open(),l.document.write(W(d)),l.document.close(),e.presenterActive=!0,document.addEventListener("fullscreenchange",P);let b=setInterval(()=>{l?.closed&&(clearInterval(b),v(e))},1e3)}export{O as installPresenter};
package/dist/deck-root.js CHANGED
@@ -1,10 +1,10 @@
1
- var _=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var o=(p,c,t,e)=>{for(var r=e>1?void 0:e?m(c,t):c,i=p.length-1,s;i>=0;i--)(s=p[i])&&(r=(e?s(c,t,r):s(r))||r);return e&&r&&_(c,t,r),r};import{LitElement as b,html as d,css as k}from"./vendor/lit.js";import{customElement as y,property as l,state as u}from"./vendor/lit.js";var n=class extends b{constructor(){super(...arguments);this.current=0;this.step=0;this.blank=null;this.overview=!1;this.fixed=!1;this.width=1920;this.height=1080;this.noHint=!1;this.noArrows=!1;this.transition=null;this.autoplay=0;this.loop=!1;this.swipe=!1;this.mouseNav=null;this.nav=null;this.slides=[];this.chapters=[];this._overviewTeardown=null;this._transitionLoaded=!1;this._autoplayTimer=null;this._autoplayPaused=!1;this._swipeStartX=0;this._swipeStartY=0;this._swipePointerId=null;this._navDownX=0;this._navDownY=0;this._wheelAccum=0;this._wheelLockUntil=0;this._onHoverEnter=()=>{this._autoplayPaused=!0,this._stopAutoplay()};this._onHoverLeave=()=>{this._autoplayPaused=!1,this.autoplay>0&&this._startAutoplay()};this._onPointerDown=t=>{!this.swipe||t.pointerType==="mouse"&&t.button!==0||t.target?.closest("a, button, input, textarea, [contenteditable]")||(this._swipePointerId=t.pointerId,this._swipeStartX=t.clientX,this._swipeStartY=t.clientY)};this._onPointerUp=t=>{if(this._swipePointerId===null||t.pointerId!==this._swipePointerId)return;let e=t.clientX-this._swipeStartX,r=t.clientY-this._swipeStartY;this._swipePointerId=null,!(Math.abs(e)<60||Math.abs(e)<Math.abs(r)*2)&&(this._stopAutoplay(),e<0?this._advance():this._back(),this._restartAutoplay())};this._onNavPointerDown=t=>{this._navDownX=t.clientX,this._navDownY=t.clientY};this._onClickNav=t=>{if(!this._mouseEnabled("click")||this.overview||this.blank||this.shadowRoot?.querySelector("#kb-overlay.open")||Math.hypot(t.clientX-this._navDownX,t.clientY-this._navDownY)>5)return;let e=window.getSelection();e&&!e.isCollapsed||t.composedPath().some(i=>i instanceof HTMLElement?i.matches?.("a, button, input, textarea, select, [contenteditable], [data-no-advance]")?!0:i.id==="blank"||i.id==="kb-overlay"||i.id==="overview-grid"||i.id==="nav-arrows"||i.id==="kb-hint":!1)||(this._restartAutoplay(),t.shiftKey?this._back():this._advance())};this._onWheel=t=>{if(!this._mouseEnabled("wheel")||this.overview||this.blank||this._wheelTargetScrolls(t))return;t.preventDefault();let e=performance.now();if(e<this._wheelLockUntil||(this._wheelAccum+=t.deltaY,Math.abs(this._wheelAccum)<50))return;let r=this._wheelAccum>0;this._wheelAccum=0,this._wheelLockUntil=e+400,this._restartAutoplay(),r?this._advance():this._back()};this._onAuxUp=t=>{this._mouseEnabled("aux")&&(t.button!==3&&t.button!==4||(t.preventDefault(),this._restartAutoplay(),t.button===3?this._back():this._advance()))};this._onAuxClick=t=>{this._mouseEnabled("aux")&&(t.button===3||t.button===4)&&t.preventDefault()};this._onHash=()=>{this._readHash(!1)};this._onKey=t=>{if(!(t.target&&t.target.matches?.("input,textarea,[contenteditable]"))){if(this._restartAutoplay(),this.overview){(t.key==="Escape"||t.key==="o"||t.key==="O"||t.key==="Enter")&&(t.preventDefault(),this.overview=!1);return}if(this.blank){t.preventDefault(),this.blank=null;return}if(t.key==="."||t.key==="b"||t.key==="B"){t.preventDefault(),this.blank="black";return}if(t.key===","||t.key==="w"||t.key==="W"){t.preventDefault(),this.blank="white";return}if(t.key==="?"||t.key==="h"||t.key==="H"){this._toggleHelp();return}if(t.key==="Escape"){this._closeHelp();return}if(t.key==="o"||t.key==="O"){t.preventDefault(),this.overview=!0;return}if(t.key==="p"||t.key==="P"){t.preventDefault(),this._togglePresenter();return}if(t.key==="Home"){this._goTo(0);return}if(t.key==="End"){this._goTo(this.slides.length-1);return}if(t.key===" "||t.key==="PageDown"){t.preventDefault(),this._advance();return}if(t.key==="PageUp"){t.preventDefault(),this._back();return}if(this._has2DNav()){let{c:e,i:r}=this._coords(this.current);if(t.key==="ArrowRight"){t.preventDefault(),e+1<this.chapters.length?this._goToCoords(e+1,0):this._advance();return}if(t.key==="ArrowLeft"){t.preventDefault(),e-1>=0?this._goToCoords(e-1,0):this._back();return}if(t.key==="ArrowDown"){t.preventDefault();let i=this.chapters[e];i&&r+1<i.slides.length?this._goToCoords(e,r+1):this._advance();return}if(t.key==="ArrowUp"){t.preventDefault(),r-1>=0?this._goToCoords(e,r-1):this._back();return}}else{if(t.key==="ArrowRight"||t.key==="ArrowDown"){t.preventDefault(),this._advance();return}if(t.key==="ArrowLeft"||t.key==="ArrowUp"){t.preventDefault(),this._back();return}}}}}firstUpdated(){this.fixed&&this._applyCanvasVars(),this._scopeSlideStyles(),this.slides=Array.from(this.querySelectorAll(":scope > *")).filter(t=>t.tagName?.toLowerCase().startsWith("deck-")&&t.tagName?.toLowerCase()!=="deck-root"),this._buildChapters(),this._readHash(!0),this._applyActive(),this._applyStep(),this._updateUI(),this.requestUpdate(),window.addEventListener("keydown",this._onKey),window.addEventListener("hashchange",this._onHash),this.addEventListener("pointerdown",this._onNavPointerDown),this.addEventListener("click",this._onClickNav),this.addEventListener("wheel",this._onWheel,{passive:!1}),window.addEventListener("mouseup",this._onAuxUp),window.addEventListener("auxclick",this._onAuxClick),this.autoplay>0&&this._startAutoplay(),this.swipe?(this.addEventListener("pointerdown",this._onPointerDown),this.addEventListener("pointerup",this._onPointerUp),this.addEventListener("pointercancel",this._onPointerUp),this.addEventListener("mouseenter",this._onHoverEnter),this.addEventListener("mouseleave",this._onHoverLeave)):this.autoplay>0&&(this.addEventListener("mouseenter",this._onHoverEnter),this.addEventListener("mouseleave",this._onHoverLeave))}_scopeSlideStyles(){this.querySelectorAll("style[scoped]").forEach(t=>{t.dataset.rikScoped||(t.dataset.rikScoped="1",t.textContent=`@scope {
1
+ var m=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var o=(d,h,t,e)=>{for(var i=e>1?void 0:e?b(h,t):h,s=d.length-1,n;s>=0;s--)(n=d[s])&&(i=(e?n(h,t,i):n(i))||i);return e&&i&&m(h,t,i),i};import{LitElement as y,html as c,css as g}from"./vendor/lit.js";import{customElement as w,property as l,state as _}from"./vendor/lit.js";function f(d){if(!d||d==="transparent")return!1;let h=d.match(/^(?:rgb|hsl)a?\(([^)]*)\)$/i);if(h){let e=h[1].split(",");return e.length<4||parseFloat(e[3])>=1}let t=d.match(/\/\s*([\d.]+%?)\s*\)$/);if(t){let e=t[1];return(e.endsWith("%")?parseFloat(e)/100:parseFloat(e))>=1}return!0}var r=class extends y{constructor(){super(...arguments);this.current=0;this.step=0;this.blank=null;this.presenterActive=!1;this.overview=!1;this.fluid=!1;this.width=1920;this.height=1080;this.noHint=!1;this.noArrows=!1;this.noCounter=!1;this.preview=!1;this.noZoom=!1;this.transition=null;this.autoplay=0;this.loop=!1;this.swipe=!1;this.mouseNav=null;this.nav=null;this.slides=[];this.chapters=[];this._overviewTeardown=null;this._transitionLoaded=!1;this._autoplayTimer=null;this._autoplayPaused=!1;this._swipeStartX=0;this._swipeStartY=0;this._swipePointerId=null;this._navDownX=0;this._navDownY=0;this._wheelAccum=0;this._wheelLockUntil=0;this._zoom=1;this._panX=0;this._panY=0;this._plugins=[];this._ctx=null;this._applyScale=()=>{if(this._effectiveFluid()){this.style.removeProperty("--deck-scale");return}let t=Math.min(this.clientWidth/this.width,this.clientHeight/this.height);t>0&&this.style.setProperty("--deck-scale",String(t)),this._zoom>1&&(this._clampPan(),this._applyZoom())};this._resizeObserver=null;this._panning=!1;this._panLastX=0;this._panLastY=0;this._onPanDown=t=>{this._zoom<=1||!this._zoomEnabled()||t.pointerType==="mouse"&&t.button!==0||t.target?.closest("a, button, input, textarea, select, [contenteditable]")||(this._panning=!0,this._panLastX=t.clientX,this._panLastY=t.clientY,this.toggleAttribute("data-panning",!0),this.setPointerCapture?.(t.pointerId))};this._onPanMove=t=>{this._panning&&(this._panBy(t.clientX-this._panLastX,t.clientY-this._panLastY),this._panLastX=t.clientX,this._panLastY=t.clientY)};this._onPanUp=t=>{this._panning&&(this._panning=!1,this.toggleAttribute("data-panning",!1),this.releasePointerCapture?.(t.pointerId))};this._onHoverEnter=()=>{this._autoplayPaused=!0,this._stopAutoplay()};this._onHoverLeave=()=>{this._autoplayPaused=!1,this.autoplay>0&&this._startAutoplay()};this._onPointerDown=t=>{!this.swipe||t.pointerType==="mouse"&&t.button!==0||t.target?.closest("a, button, input, textarea, [contenteditable]")||(this._swipePointerId=t.pointerId,this._swipeStartX=t.clientX,this._swipeStartY=t.clientY)};this._onPointerUp=t=>{if(this._swipePointerId===null||t.pointerId!==this._swipePointerId)return;if(this._zoom>1){this._swipePointerId=null;return}let e=t.clientX-this._swipeStartX,i=t.clientY-this._swipeStartY;this._swipePointerId=null,!(Math.abs(e)<60||Math.abs(e)<Math.abs(i)*2)&&(this._stopAutoplay(),e<0?this._advance():this._back(),this._restartAutoplay())};this._onNavPointerDown=t=>{this._navDownX=t.clientX,this._navDownY=t.clientY};this._onClickNav=t=>{if(!this._mouseEnabled("click")||this.overview||this.blank||this._zoom>1||this.shadowRoot?.querySelector("#kb-overlay.open")||Math.hypot(t.clientX-this._navDownX,t.clientY-this._navDownY)>5)return;let e=window.getSelection();e&&!e.isCollapsed||t.composedPath().some(s=>s instanceof HTMLElement?s.matches?.("a, button, input, textarea, select, [contenteditable], [data-no-advance]")?!0:s.id==="blank"||s.id==="kb-overlay"||s.id==="overview-grid"||s.id==="nav-arrows"||s.id==="kb-hint":!1)||(this._restartAutoplay(),t.shiftKey?this._back():this._advance())};this._onWheel=t=>{if(t.ctrlKey||t.metaKey){if(!this._zoomEnabled())return;t.preventDefault(),this._zoomAt(Math.exp(-t.deltaY*r.ZOOM_WHEEL_SENSITIVITY),t.clientX,t.clientY);return}if(this._zoom>1&&this._zoomEnabled()){t.preventDefault(),this._panBy(-t.deltaX,-t.deltaY);return}if(!this._mouseEnabled("wheel")||this.overview||this.blank||this._wheelTargetScrolls(t))return;t.preventDefault();let e=performance.now();if(e<this._wheelLockUntil||(this._wheelAccum+=t.deltaY,Math.abs(this._wheelAccum)<50))return;let i=this._wheelAccum>0;this._wheelAccum=0,this._wheelLockUntil=e+400,this._restartAutoplay(),i?this._advance():this._back()};this._onAuxUp=t=>{this._mouseEnabled("aux")&&(t.button!==3&&t.button!==4||(t.preventDefault(),this._restartAutoplay(),t.button===3?this._back():this._advance()))};this._onAuxClick=t=>{this._mouseEnabled("aux")&&(t.button===3||t.button===4)&&t.preventDefault()};this._onHash=()=>{this._readHash(!1)};this._onKey=t=>{if(!(t.target&&t.target.matches?.("input,textarea,[contenteditable]"))){if(this._restartAutoplay(),this.overview){(t.key==="Escape"||t.key==="o"||t.key==="O"||t.key==="Enter")&&(t.preventDefault(),this.overview=!1);return}if(this.blank){t.preventDefault(),this.blank=null;return}if(t.key==="."||t.key==="b"||t.key==="B"){t.preventDefault(),this.blank="black";return}if(t.key===","||t.key==="w"||t.key==="W"){t.preventDefault(),this.blank="white";return}if(this._zoomEnabled()&&(t.key==="+"||t.key==="="||t.key==="-")){t.preventDefault();let e=this.getBoundingClientRect(),i=e.left+e.width/2,s=e.top+e.height/2,n=t.key==="-"?1/r.ZOOM_STEP:r.ZOOM_STEP;this._zoomAt(n,i,s);return}if(t.key==="0"&&this._zoom>1){t.preventDefault(),this._resetZoom();return}if(t.key==="?"||t.key==="h"||t.key==="H"){this._toggleHelp();return}if(t.key==="Escape"){this._closeHelp();return}if(t.key==="o"||t.key==="O"){t.preventDefault(),this.overview=!0;return}if(t.key==="p"||t.key==="P"){t.preventDefault(),this._togglePresenter();return}if(t.key==="Home"){this._goTo(0);return}if(t.key==="End"){this._goTo(this.slides.length-1);return}if(t.key===" "||t.key==="PageDown"){t.preventDefault(),this._advance();return}if(t.key==="PageUp"){t.preventDefault(),this._back();return}if(this._has2DNav()){let{c:e,i}=this._coords(this.current);if(t.key==="ArrowRight"){t.preventDefault(),e+1<this.chapters.length?this._goToCoords(e+1,0):this._advance();return}if(t.key==="ArrowLeft"){t.preventDefault(),e-1>=0?this._goToCoords(e-1,0):this._back();return}if(t.key==="ArrowDown"){t.preventDefault();let s=this.chapters[e];s&&i+1<s.slides.length?this._goToCoords(e,i+1):this._advance();return}if(t.key==="ArrowUp"){t.preventDefault(),i-1>=0?this._goToCoords(e,i-1):this._back();return}}else{if(t.key==="ArrowRight"||t.key==="ArrowDown"){t.preventDefault(),this._advance();return}if(t.key==="ArrowLeft"||t.key==="ArrowUp"){t.preventDefault(),this._back();return}}}}}_context(){if(this._ctx)return this._ctx;let t=this;return this._ctx={host:t,get current(){return t.current},get step(){return t.step},get slides(){return t.slides},requestUpdate:()=>t.requestUpdate()},this._ctx}use(t){if(this._plugins.some(i=>i.name===t.name))return()=>{};t.navigate&&this._plugins.some(i=>i.navigate)&&console.warn(`[rikiki] plugin "${t.name}" has a navigate hook but another plugin already owns navigation \xB7 it will be ignored`),this._plugins.push(t);let e=t.setup?.(this._context());return this._applyStep(),this._updateUI(),()=>{let i=this._plugins.indexOf(t);i>=0&&this._plugins.splice(i,1),typeof e=="function"&&e()}}firstUpdated(){this._installRuntime(),this._scopeSlideStyles(),this.slides=Array.from(this.querySelectorAll(":scope > *")).filter(t=>t.tagName?.toLowerCase().startsWith("deck-")&&t.tagName?.toLowerCase()!=="deck-root"),this._buildChapters(),this._readHash(!0),this._applyActive(),this._applyStep(),this._updateUI(),this.requestUpdate()}_installRuntime(){this._applyCanvasVars(),this._applyScale(),this._resizeObserver=new ResizeObserver(this._applyScale),this._resizeObserver.observe(this),!this.preview&&(window.addEventListener("keydown",this._onKey),window.addEventListener("hashchange",this._onHash),this.addEventListener("pointerdown",this._onNavPointerDown),this.addEventListener("click",this._onClickNav),this.addEventListener("wheel",this._onWheel,{passive:!1}),this.addEventListener("pointerdown",this._onPanDown),this.addEventListener("pointermove",this._onPanMove),this.addEventListener("pointerup",this._onPanUp),this.addEventListener("pointercancel",this._onPanUp),window.addEventListener("mouseup",this._onAuxUp),window.addEventListener("auxclick",this._onAuxClick),this.autoplay>0&&this._startAutoplay(),this.swipe?(this.addEventListener("pointerdown",this._onPointerDown),this.addEventListener("pointerup",this._onPointerUp),this.addEventListener("pointercancel",this._onPointerUp),this.addEventListener("mouseenter",this._onHoverEnter),this.addEventListener("mouseleave",this._onHoverLeave)):this.autoplay>0&&(this.addEventListener("mouseenter",this._onHoverEnter),this.addEventListener("mouseleave",this._onHoverLeave)))}_scopeSlideStyles(){this.querySelectorAll("style[scoped]").forEach(t=>{t.dataset.rikScoped||(t.dataset.rikScoped="1",t.textContent=`@scope {
2
2
  ${t.textContent??""}
3
- }`)})}_applyCanvasVars(){let t=document.documentElement;t.style.setProperty("--deck-canvas-w",String(this.width)),t.style.setProperty("--deck-canvas-h",String(this.height))}disconnectedCallback(){super.disconnectedCallback(),this.fixed&&(document.documentElement.style.removeProperty("--deck-canvas-w"),document.documentElement.style.removeProperty("--deck-canvas-h")),window.removeEventListener("keydown",this._onKey),window.removeEventListener("hashchange",this._onHash),this.removeEventListener("pointerdown",this._onNavPointerDown),this.removeEventListener("click",this._onClickNav),this.removeEventListener("wheel",this._onWheel),window.removeEventListener("mouseup",this._onAuxUp),window.removeEventListener("auxclick",this._onAuxClick),this._stopAutoplay(),this.removeEventListener("pointerdown",this._onPointerDown),this.removeEventListener("pointerup",this._onPointerUp),this.removeEventListener("pointercancel",this._onPointerUp),this.removeEventListener("mouseenter",this._onHoverEnter),this.removeEventListener("mouseleave",this._onHoverLeave)}_startAutoplay(){this._stopAutoplay(),!(this.autoplay<=0||this._autoplayPaused)&&(this._autoplayTimer=window.setInterval(()=>this._autoTick(),this.autoplay))}_stopAutoplay(){this._autoplayTimer!==null&&(window.clearInterval(this._autoplayTimer),this._autoplayTimer=null)}_autoTick(){if(this.overview)return;this.current>=this.slides.length-1&&this.step>=this._maxSteps()&&this.loop?this._goTo(0):this._advance()}_restartAutoplay(){this.autoplay>0&&!this._autoplayPaused&&this._startAutoplay()}_wheelTargetScrolls(t){let e=t.deltaY>0,r=t.deltaX>0;for(let i of t.composedPath()){if(i===this)return!1;if(!(i instanceof Element))continue;let s=i.scrollHeight>i.clientHeight,a=i.scrollWidth>i.clientWidth;if(!s&&!a)continue;let h=getComputedStyle(i);if(s&&/auto|scroll/.test(h.overflowY)&&(e?i.scrollTop+i.clientHeight<i.scrollHeight-1:i.scrollTop>0)||a&&/auto|scroll/.test(h.overflowX)&&(r?i.scrollLeft+i.clientWidth<i.scrollWidth-1:i.scrollLeft>0))return!0}return!1}_buildChapters(){this.chapters=[];let t=null;this.slides.forEach((e,r)=>{e.tagName?.toLowerCase()==="deck-section"||!t?(t={startIdx:r,slides:[e]},this.chapters.push(t)):t.slides.push(e)})}_has2DNav(){return this.nav==="2d"&&this.chapters.length>1&&this.chapters.some(t=>t.slides.length>1)}_mouseEnabled(t){let e=(this.mouseNav??"all").trim();return e==="none"?!1:e===""||e==="all"?!0:e.split(/\s+/).includes(t)}_coords(t){for(let e=0;e<this.chapters.length;e++){let r=this.chapters[e],i=t-r.startIdx;if(i>=0&&i<r.slides.length)return{c:e,i}}return{c:0,i:0}}_flatFromCoords(t,e){let r=this.chapters[Math.max(0,Math.min(this.chapters.length-1,t))];return r?r.startIdx+Math.max(0,Math.min(r.slides.length-1,e)):0}_readHash(t){let e=location.hash,r=e.match(/^#(\d+)\.(\d+)(?:s(\d+))?$/),i=e.match(/^#(\d+)(?:\.(\d+))?$/),s=this.current,a=this.step;if(this._has2DNav()&&r){let v=parseInt(r[1],10)-1,f=parseInt(r[2],10)-1;s=this._flatFromCoords(Math.max(0,v),Math.max(0,f)),a=r[3]?parseInt(r[3],10):0}else if(i)s=parseInt(i[1],10)-1,a=i[2]?parseInt(i[2],10):0;else return;if(s===this.current&&a===this.step&&!t)return;this.current=Math.max(0,Math.min(this.slides.length-1,s));let h=this._maxSteps();this.step=h>0?Math.max(0,Math.min(h,a)):Math.max(0,a),t||(this._applyActive(),this._applyStep(),this._updateUI())}_writeHash(){let t=`#${this.current+1}`+(this.step>0?`.${this.step}`:"");if(location.hash!==t)try{history.replaceState(null,"",t)}catch{}}async _toggleHelp(){(await import("./deck-help.js")).toggleHelp(this)}async _togglePresenter(){(await import("./deck-presenter.js")).installPresenter(this)}async _closeHelp(){(await import("./deck-help.js")).closeHelp(this)}async _renderOverviewIfActive(){if(!this.overview){this._overviewTeardown?.(),this._overviewTeardown=null;return}let{mountOverview:t}=await import("./deck-overview.js");this._overviewTeardown=t(this,{slides:this.slides,chapters:this.chapters,currentIdx:this.current,onPick:e=>{this.overview=!1,this._goTo(e)}})}_maxSteps(){let t=this.slides[this.current];if(!t)return 0;let e=parseInt(t.getAttribute("steps")||t.dataset?.steps||"0",10);if(e>0)return e;let r=t.querySelector("deck-code[step-groups]");if(r)try{return JSON.parse(r.getAttribute("step-groups")).length}catch{}return 0}_advance(){let t=this._maxSteps();this.step<t?(this.step++,this._applyStep(),this._updateUI(),this._writeHash()):this.current<this.slides.length-1?this._goTo(this.current+1):this.loop&&this._goTo(0)}_back(){this.step>0?(this.step--,this._applyStep(),this._updateUI(),this._writeHash()):this.current>0?(this._goTo(this.current-1),this.step=this._maxSteps(),this._applyStep(),this._updateUI(),this._writeHash()):this.loop&&(this._goTo(this.slides.length-1),this.step=this._maxSteps(),this._applyStep(),this._updateUI(),this._writeHash())}_goTo(t){this.current=Math.max(0,Math.min(this.slides.length-1,t)),this.step=0,this._applyActive(),this._applyStep(),this._updateUI(),this._writeHash()}_goToCoords(t,e){let r=Math.max(0,Math.min(this.chapters.length-1,t)),i=this.chapters[r];if(!i)return;let s=Math.max(0,Math.min(i.slides.length-1,e));this._goTo(this._flatFromCoords(r,s))}_applyActive(){let t=this.slides.find(r=>r.hasAttribute("active"))??null,e=this.slides[this.current]??null;this.slides.forEach((r,i)=>{let s=i===this.current;r.toggleAttribute("active",s),s&&r.querySelectorAll("deck-mermaid").forEach(a=>a.render?.())}),this.transition&&!this._transitionLoaded&&(this._transitionLoaded=!0,import("./deck-transition.js").then(r=>r.installTransitions(this))),t!==e&&this.dispatchEvent(new CustomEvent("slide-change",{detail:{current:e,previous:t},bubbles:!1}))}_applyStep(){let t=this.slides[this.current];t&&(t.applyStep?.(this.step),t.querySelectorAll("*").forEach(e=>e.applyStep?.(this.step)),t.querySelectorAll("[data-step-block]").forEach(e=>{let r=parseInt(e.dataset.stepBlock,10);e.style.transition="opacity 0.25s ease",e.style.opacity=this.step===0||r<=this.step?"1":"0.15"}))}_updateUI(){let t=this.slides.length,e=this.current+1,r=this.renderRoot.querySelector("#progress"),i=this.renderRoot.querySelector("#counter"),s=this.renderRoot.querySelector("#step-dots");r&&(r.style.width=e/t*100+"%"),i&&(i.textContent=`${e} / ${t}`);let a=this._maxSteps();s&&(s.innerHTML=a===0?"":Array.from({length:a},(h,v)=>`<div class="dot${v<this.step?" active":""}"></div>`).join(""))}updated(){this._updateUI(),this._renderOverviewIfActive()}_navArrows(){if(this.noArrows||!this._mouseEnabled("arrows")||this.overview)return"";let t=this.slides.length;if(t===0)return"";let e=this.current===0&&this.step===0,r=this.current>=t-1&&this.step>=this._maxSteps();if(this._has2DNav()){let{c:i,i:s}=this._coords(this.current),a=this.chapters[i];return d`<div id="nav-arrows"> <button class="nav-btn" title="Previous chapter" ?disabled=${!this.loop&&this.current===0} @click=${()=>i>0?this._goToCoords(i-1,0):this._back()}>&lsaquo;</button> <button class="nav-btn" title="Up" ?disabled=${s===0} @click=${()=>this._goToCoords(i,s-1)}>&uarr;</button> <button class="nav-btn" title="Down" ?disabled=${!a||s+1>=a.slides.length} @click=${()=>this._goToCoords(i,s+1)}>&darr;</button> <button class="nav-btn" title="Next chapter" ?disabled=${!this.loop&&r} @click=${()=>i+1<this.chapters.length?this._goToCoords(i+1,0):this._advance()}>&rsaquo;</button> </div>`}return d`<div id="nav-arrows"> <button class="nav-btn" title="Previous" ?disabled=${!this.loop&&e} @click=${()=>this._back()}>&lsaquo;</button> <button class="nav-btn" title="Next" ?disabled=${!this.loop&&r} @click=${()=>this._advance()}>&rsaquo;</button> </div>`}render(){return d`<div id="progress"></div> <div id="counter"></div> <div id="step-dots"></div> ${this.noHint?"":d`
3
+ }`)})}_effectiveFluid(){return this.fluid||(this.slides[this.current]?.hasAttribute("fluid")??!1)}_applySlideFluid(){let t=!this.fluid&&(this.slides[this.current]?.hasAttribute("fluid")??!1);this.toggleAttribute("unfixed",t),this._applyCanvasVars(),this._applyScale()}_applyCanvasVars(){let t=document.documentElement;if(this._effectiveFluid()){t.style.removeProperty("--deck-canvas-w"),t.style.removeProperty("--deck-canvas-h");return}t.style.setProperty("--deck-canvas-w",String(this.width)),t.style.setProperty("--deck-canvas-h",String(this.height))}_zoomEnabled(){return!this.noZoom&&!this._effectiveFluid()&&!this.overview&&!this.blank}_applyZoom(){this.style.setProperty("--deck-zoom",String(this._zoom)),this.style.setProperty("--deck-pan-x",`${this._panX}px`),this.style.setProperty("--deck-pan-y",`${this._panY}px`),this.toggleAttribute("data-zoomed",this._zoom>1)}_clampPan(){let e=(this.clientWidth&&this.clientHeight?Math.min(this.clientWidth/this.width,this.clientHeight/this.height):1)*this._zoom,i=Math.max(0,(this.width*e-this.clientWidth)/2),s=Math.max(0,(this.height*e-this.clientHeight)/2);this._panX=Math.max(-i,Math.min(i,this._panX)),this._panY=Math.max(-s,Math.min(s,this._panY))}_zoomAt(t,e,i){if(!this._zoomEnabled())return;let s=this._zoom,n=Math.max(1,Math.min(r.ZOOM_MAX,s*t));if(n===s)return;let a=this.getBoundingClientRect(),p=a.left+a.width/2,u=a.top+a.height/2,v=n/s;this._panX+=(e-p-this._panX)*(1-v),this._panY+=(i-u-this._panY)*(1-v),this._zoom=n,this._clampPan(),this._applyZoom()}_resetZoom(){this._zoom===1&&this._panX===0&&this._panY===0||(this._zoom=1,this._panX=0,this._panY=0,this._applyZoom())}_panBy(t,e){this._panX+=t,this._panY+=e,this._clampPan(),this._applyZoom()}_applyLetterbox(t){if(this._effectiveFluid()){this.style.removeProperty("--deck-letterbox-bg");return}let e=t?getComputedStyle(t).backgroundColor:"";e&&f(e)?this.style.setProperty("--deck-letterbox-bg",e):this.style.removeProperty("--deck-letterbox-bg")}static _injectGlobals(){if(typeof document>"u"||document.getElementById("rik-deck-globals"))return;let t=document.createElement("style");t.id="rik-deck-globals",t.textContent="html:has(> body > deck-root){overflow:hidden;height:100%}html:has(> body > deck-root) body{margin:0;overflow:hidden;height:100%}html:has(> body > deck-root:not([fluid])){font-size:calc(var(--deck-canvas-h,1080)*0.0235px)}html:has(> body > deck-root[fluid]){font-size:clamp(14px,2.35vh,42px)}html:has(> body > deck-root[unfixed]){font-size:clamp(14px,2.35vh,42px)}",document.head.appendChild(t)}connectedCallback(){super.connectedCallback(),r._injectGlobals(),this.hasUpdated&&this._installRuntime()}disconnectedCallback(){super.disconnectedCallback(),document.documentElement.style.removeProperty("--deck-canvas-w"),document.documentElement.style.removeProperty("--deck-canvas-h"),document.querySelector("deck-root")||document.getElementById("rik-deck-globals")?.remove(),this._resizeObserver?.disconnect(),this._resizeObserver=null,window.removeEventListener("keydown",this._onKey),window.removeEventListener("hashchange",this._onHash),this.removeEventListener("pointerdown",this._onNavPointerDown),this.removeEventListener("click",this._onClickNav),this.removeEventListener("wheel",this._onWheel),this.removeEventListener("pointerdown",this._onPanDown),this.removeEventListener("pointermove",this._onPanMove),this.removeEventListener("pointerup",this._onPanUp),this.removeEventListener("pointercancel",this._onPanUp),window.removeEventListener("mouseup",this._onAuxUp),window.removeEventListener("auxclick",this._onAuxClick),this._stopAutoplay(),this.removeEventListener("pointerdown",this._onPointerDown),this.removeEventListener("pointerup",this._onPointerUp),this.removeEventListener("pointercancel",this._onPointerUp),this.removeEventListener("mouseenter",this._onHoverEnter),this.removeEventListener("mouseleave",this._onHoverLeave),this._panning=!1,this.toggleAttribute("data-panning",!1)}_startAutoplay(){this._stopAutoplay(),!(this.autoplay<=0||this._autoplayPaused)&&(this._autoplayTimer=window.setInterval(()=>this._autoTick(),this.autoplay))}_stopAutoplay(){this._autoplayTimer!==null&&(window.clearInterval(this._autoplayTimer),this._autoplayTimer=null)}_autoTick(){if(this.overview)return;this.current>=this.slides.length-1&&this.step>=this._maxSteps()&&this.loop?this._goTo(0):this._advance()}_restartAutoplay(){this.autoplay>0&&!this._autoplayPaused&&this._startAutoplay()}_wheelTargetScrolls(t){let e=t.deltaY>0,i=t.deltaX>0;for(let s of t.composedPath()){if(s===this)return!1;if(!(s instanceof Element))continue;let n=s.scrollHeight>s.clientHeight,a=s.scrollWidth>s.clientWidth;if(!n&&!a)continue;let p=getComputedStyle(s);if(n&&/auto|scroll/.test(p.overflowY)&&(e?s.scrollTop+s.clientHeight<s.scrollHeight-1:s.scrollTop>0)||a&&/auto|scroll/.test(p.overflowX)&&(i?s.scrollLeft+s.clientWidth<s.scrollWidth-1:s.scrollLeft>0))return!0}return!1}_buildChapters(){this.chapters=[];let t=null;this.slides.forEach((e,i)=>{e.tagName?.toLowerCase()==="deck-section"||!t?(t={startIdx:i,slides:[e]},this.chapters.push(t)):t.slides.push(e)})}_has2DNav(){return this.nav==="2d"&&this.chapters.length>1&&this.chapters.some(t=>t.slides.length>1)}_mouseEnabled(t){let e=(this.mouseNav??"all").trim();return e==="none"?!1:e===""||e==="all"?!0:e.split(/\s+/).includes(t)}_coords(t){for(let e=0;e<this.chapters.length;e++){let i=this.chapters[e],s=t-i.startIdx;if(s>=0&&s<i.slides.length)return{c:e,i:s}}return{c:0,i:0}}_flatFromCoords(t,e){let i=this.chapters[Math.max(0,Math.min(this.chapters.length-1,t))];return i?i.startIdx+Math.max(0,Math.min(i.slides.length-1,e)):0}_readHash(t){let e=location.hash,i=e.match(/^#(\d+)\.(\d+)(?:s(\d+))?$/),s=e.match(/^#(\d+)(?:\.(\d+))?$/),n=this.current,a=this.step;if(this._has2DNav()&&i){let u=parseInt(i[1],10)-1,v=parseInt(i[2],10)-1;n=this._flatFromCoords(Math.max(0,u),Math.max(0,v)),a=i[3]?parseInt(i[3],10):0}else if(s)n=parseInt(s[1],10)-1,a=s[2]?parseInt(s[2],10):0;else return;if(n===this.current&&a===this.step&&!t)return;this.current=Math.max(0,Math.min(this.slides.length-1,n));let p=this._maxSteps();this.step=p>0?Math.max(0,Math.min(p,a)):Math.max(0,a),t||(this._resetZoom(),this._applyActive(),this._applyStep(),this._updateUI())}_writeHash(){let t=`#${this.current+1}${this.step>0?`.${this.step}`:""}`;if(location.hash!==t)try{history.replaceState(null,"",t)}catch{}}async _toggleHelp(){(await import("./deck-help.js")).toggleHelp(this)}async _togglePresenter(){(await import("./deck-presenter.js")).installPresenter(this)}async _closeHelp(){(await import("./deck-help.js")).closeHelp(this)}async _renderOverviewIfActive(){if(!this.overview){this._overviewTeardown?.(),this._overviewTeardown=null;return}let{mountOverview:t}=await import("./deck-overview.js");this._overviewTeardown=t(this,{slides:this.slides,chapters:this.chapters,currentIdx:this.current,onPick:e=>{this.overview=!1,this._goTo(e)}})}_maxSteps(){let t=this._baseMaxSteps(),e=this.slides[this.current];if(e)for(let i of this._plugins)i.steps&&(t=Math.max(t,i.steps(e,this._context())));return t}_baseMaxSteps(){let t=this.slides[this.current];if(!t)return 0;let e=parseInt(t.getAttribute("steps")||t.dataset?.steps||"0",10);if(e>0)return e;let i=t.querySelector("deck-code[step-groups]");if(i)try{return JSON.parse(i.getAttribute("step-groups")).length}catch{}return 0}_advance(){let t=this._maxSteps();this.step<t?(this.step++,this._applyStep(),this._updateUI(),this._writeHash()):this.current<this.slides.length-1?this._goTo(this.current+1):this.loop&&this._goTo(0)}_back(){this.step>0?(this.step--,this._applyStep(),this._updateUI(),this._writeHash()):this.current>0?(this._goTo(this.current-1),this.step=this._maxSteps(),this._applyStep(),this._updateUI(),this._writeHash()):this.loop&&(this._goTo(this.slides.length-1),this.step=this._maxSteps(),this._applyStep(),this._updateUI(),this._writeHash())}_goTo(t){this._plugins.find(i=>i.navigate)?.navigate?.(t,this._context(),()=>this._goToNow(t))||this._goToNow(t)}_goToNow(t){this._resetZoom(),this.current=Math.max(0,Math.min(this.slides.length-1,t)),this.step=0,this._applyActive(),this._applyStep(),this._updateUI(),this._writeHash()}_goToCoords(t,e){let i=Math.max(0,Math.min(this.chapters.length-1,t)),s=this.chapters[i];if(!s)return;let n=Math.max(0,Math.min(s.slides.length-1,e));this._goTo(this._flatFromCoords(i,n))}_applyActive(){let t=this.slides.find(i=>i.hasAttribute("active"))??null,e=this.slides[this.current]??null;this.slides.forEach((i,s)=>{let n=s===this.current;i.toggleAttribute("active",n),n&&i.querySelectorAll("deck-mermaid").forEach(a=>{a.render?.()})}),this._applySlideFluid(),this._applyLetterbox(e),this.transition&&!this._transitionLoaded&&(this._transitionLoaded=!0,import("./deck-transition.js").then(i=>i.installTransitions(this))),t!==e&&this.dispatchEvent(new CustomEvent("slide-change",{detail:{current:e,previous:t},bubbles:!1}))}_applyStep(){let t=this.slides[this.current];if(t){t.applyStep?.(this.step),t.querySelectorAll("*").forEach(e=>{e.applyStep?.(this.step)}),t.querySelectorAll("[data-step-block]").forEach(e=>{let i=parseInt(e.dataset.stepBlock,10);e.style.transition="opacity 0.25s ease",e.style.opacity=this.step===0||i<=this.step?"1":"0.15"});for(let e of this._plugins)e.applyStep?.(this.step,t,this._context())}}_counterHidden(){let t=this.slides[this.current];return this.overview||this.blank!==null||t?.tagName.toLowerCase()==="deck-cover"}_updateUI(){let t=this.slides.length,e=this.current+1,i=this.renderRoot.querySelector("#progress"),s=this.renderRoot.querySelector("#counter"),n=this.renderRoot.querySelector("#step-dots");i&&(i.style.width=`${t>0?e/t*100:0}%`),s&&(s.textContent=`${e} / ${t}`);let a=this._maxSteps();n&&(n.innerHTML=a===0?"":Array.from({length:a},(p,u)=>`<div class="dot${u<this.step?" active":""}"></div>`).join(""))}updated(t){(t.has("width")||t.has("height")||t.has("fluid"))&&(this._applyCanvasVars(),this._applyScale()),t.has("fluid")&&this._applyLetterbox(this.slides[this.current]??null),(t.has("overview")&&this.overview||t.has("blank")&&this.blank||t.has("noZoom")&&this.noZoom||t.has("fluid")&&this.fluid)&&this._resetZoom(),this._updateUI(),this._renderOverviewIfActive()}_navArrows(){if(this.noArrows||this.presenterActive||!this._mouseEnabled("arrows")||this.overview)return"";let t=this.slides.length;if(t===0)return"";let e=this.current===0&&this.step===0,i=this.current>=t-1&&this.step>=this._maxSteps();if(this._has2DNav()){let{c:s,i:n}=this._coords(this.current),a=this.chapters[s];return c`<div id="nav-arrows"> <button class="nav-btn" title="Previous chapter" ?disabled=${!this.loop&&this.current===0} @click=${()=>s>0?this._goToCoords(s-1,0):this._back()}>&lsaquo;</button> <button class="nav-btn" title="Up" ?disabled=${n===0} @click=${()=>this._goToCoords(s,n-1)}>&uarr;</button> <button class="nav-btn" title="Down" ?disabled=${!a||n+1>=a.slides.length} @click=${()=>this._goToCoords(s,n+1)}>&darr;</button> <button class="nav-btn" title="Next chapter" ?disabled=${!this.loop&&i} @click=${()=>s+1<this.chapters.length?this._goToCoords(s+1,0):this._advance()}>&rsaquo;</button> </div>`}return c`<div id="nav-arrows"> <button class="nav-btn" title="Previous" ?disabled=${!this.loop&&e} @click=${()=>this._back()}>&lsaquo;</button> <button class="nav-btn" title="Next" ?disabled=${!this.loop&&i} @click=${()=>this._advance()}>&rsaquo;</button> </div>`}render(){return c`<div id="progress"></div> <div id="counter" class=${this._counterHidden()?"hidden":""}></div> <div id="step-dots"></div> ${this.noHint||this.presenterActive?"":c`
4
4
  <div id="kb-hint">
5
5
  <kbd title="Previous" @click=${()=>this._back()}>←</kbd
6
6
  ><kbd title="Next" @click=${()=>this._advance()}>→</kbd>
7
- ${this._has2DNav()?d`<kbd title="Previous" @click=${()=>this._back()}>↑</kbd ><kbd title="Next" @click=${()=>this._advance()}>↓</kbd>`:""}
7
+ ${this._has2DNav()?c`<kbd title="Previous" @click=${()=>this._back()}>↑</kbd ><kbd title="Next" @click=${()=>this._advance()}>↓</kbd>`:""}
8
8
  <span>·</span>
9
9
  <kbd title="Overview" @click=${()=>{this.overview=!this.overview}}>O</kbd>
10
10
  <span>·</span>
@@ -14,5 +14,5 @@ ${t.textContent??""}
14
14
  </div>`}
15
15
  ${this._navArrows()}
16
16
  <div id="stage"><slot></slot></div>
17
- ${this.blank?d`<div id="blank" data-tone="${this.blank}" @click=${()=>{this.blank=null}}></div>`:""}
18
- `}};n.styles=k`:host{display:block;width:100vw;height:100vh;position:relative;background:var(--deck-root-bg,var(--rik-surface-page))}#stage{position:absolute;inset:0}:host([fixed]){display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--deck-letterbox-bg,var(--deck-root-bg,var(--rik-surface-page)))}:host([fixed]) #stage{position:relative;inset:auto;width:min(100vw,calc(100vh * var(--deck-canvas-w,1920) / var(--deck-canvas-h,1080)));height:min(100vh,calc(100vw * var(--deck-canvas-h,1080) / var(--deck-canvas-w,1920)));container-type:size}#progress{position:fixed;bottom:0;left:0;height:var(--deck-root-progress-height,3px);background:var(--deck-root-progress-color,linear-gradient(90deg,var(--rik-accent),var(--rik-accent--soft)));transition:width 0.25s ease;z-index:100}#counter{position:fixed;bottom:1rem;right:1.5rem;font-size:var(--rik-font-size-xs);color:var(--deck-root-counter-color,var(--rik-text-default--faint));font-family:var(--rik-font-mono);z-index:100}#step-dots{position:fixed;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:6px;z-index:100}.dot{width:6px;height:6px;border-radius:50%;background:var(--deck-root-dot-bg,#d4d4d0);transition:background 0.2s}.dot.active{background:var(--deck-root-dot-active-bg,var(--rik-accent))}#kb-hint{position:fixed;bottom:1rem;left:1.5rem;display:inline-flex;align-items:center;gap:6px;font:600 0.62rem/1 var(--rik-font-mono);color:var(--deck-root-kb-hint-color,var(--rik-text-default--faint));z-index:100;opacity:0.5;transition:opacity 0.2s ease;cursor:help}#kb-hint:hover{opacity:1}#kb-hint kbd{background:var(--rik-surface-raised);border:1px solid var(--rik-border-default);border-bottom:2px solid var(--rik-border-default);border-radius:4px;padding:2px 6px;color:var(--rik-text-default);font:inherit;min-width:16px;text-align:center;cursor:pointer}#kb-hint kbd:hover{border-color:var(--rik-accent)}#kb-hint .sep{opacity:0.4}#nav-arrows{position:fixed;bottom:2.4rem;right:1.5rem;display:flex;gap:4px;z-index:100;opacity:var(--deck-root-nav-opacity,0.35);transition:opacity 0.2s ease}#nav-arrows:hover{opacity:1}.nav-btn{appearance:none;cursor:pointer;width:30px;height:30px;display:grid;place-items:center;font:700 1rem/1 var(--rik-font-mono);color:var(--deck-root-nav-color,var(--rik-text-default));background:var(--deck-root-nav-bg,var(--rik-surface-raised));border:1px solid var(--rik-border-default);border-radius:6px;padding:0}.nav-btn:hover:not(:disabled){border-color:var(--rik-accent)}.nav-btn:disabled{opacity:0.3;cursor:default}#blank{position:fixed;inset:0;z-index:9999;cursor:pointer}#blank[data-tone="black"]{background:#000}#blank[data-tone="white"]{background:#fff}`,o([u()],n.prototype,"current",2),o([u()],n.prototype,"step",2),o([u()],n.prototype,"blank",2),o([l({type:Boolean,reflect:!0})],n.prototype,"overview",2),o([l({type:Boolean,reflect:!0})],n.prototype,"fixed",2),o([l({type:Number})],n.prototype,"width",2),o([l({type:Number})],n.prototype,"height",2),o([l({type:Boolean,reflect:!0,attribute:"no-hint"})],n.prototype,"noHint",2),o([l({type:Boolean,reflect:!0,attribute:"no-arrows"})],n.prototype,"noArrows",2),o([l({type:String,reflect:!0})],n.prototype,"transition",2),o([l({type:Number,reflect:!0})],n.prototype,"autoplay",2),o([l({type:Boolean,reflect:!0})],n.prototype,"loop",2),o([l({type:Boolean,reflect:!0})],n.prototype,"swipe",2),o([l({type:String,reflect:!0,attribute:"mouse-nav"})],n.prototype,"mouseNav",2),o([l({type:String,reflect:!0})],n.prototype,"nav",2),n=o([y("deck-root")],n);export{n as DeckRoot};
17
+ ${this.blank?c`<div id="blank" data-tone="${this.blank}" @click=${()=>{this.blank=null}}></div>`:""}
18
+ `}};r.styles=g`:host{display:flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:hidden;background:var(--deck-letterbox-bg,var(--deck-root-bg,var(--rik-surface-page)))}#stage{flex:none;width:calc(var(--deck-canvas-w,1920) * 1px);height:calc(var(--deck-canvas-h,1080) * 1px);transform:translate(var(--deck-pan-x,0px),var(--deck-pan-y,0px)) scale(calc(var(--deck-scale,1) * var(--deck-zoom,1)));transform-origin:center center;container-type:size}:host([fluid]) #stage,:host([unfixed]) #stage{width:100%;height:100%;transform:none}:host([data-zoomed]){cursor:grab}:host([data-zoomed][data-panning]){cursor:grabbing}#progress{position:fixed;bottom:0;left:0;height:var(--deck-root-progress-height,3px);background:var(--deck-root-progress-color,linear-gradient(90deg,var(--rik-accent),var(--rik-accent--soft)));transition:width 0.25s ease;z-index:100}#counter{position:fixed;bottom:1rem;right:1.5rem;font-size:var(--rik-font-size-xs);color:var(--deck-root-counter-color,var(--rik-text-default--faint));font-family:var(--rik-font-mono);z-index:100}:host([no-counter]) #counter{display:none}#counter.hidden{display:none}#step-dots{position:fixed;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:6px;z-index:100}.dot{width:6px;height:6px;border-radius:50%;background:var(--deck-root-dot-bg,#d4d4d0);transition:background 0.2s}.dot.active{background:var(--deck-root-dot-active-bg,var(--rik-accent))}#kb-hint{position:fixed;bottom:1rem;left:1.5rem;display:inline-flex;align-items:center;gap:6px;font:600 0.62rem/1 var(--rik-font-mono);color:var(--deck-root-kb-hint-color,var(--rik-text-default--faint));z-index:100;opacity:0.5;transition:opacity 0.2s ease;cursor:help}#kb-hint:hover{opacity:1}#kb-hint kbd{background:var(--rik-surface-raised);border:1px solid var(--rik-border-default);border-bottom:2px solid var(--rik-border-default);border-radius:4px;padding:2px 6px;color:var(--rik-text-default);font:inherit;min-width:16px;text-align:center;cursor:pointer}#kb-hint kbd:hover{border-color:var(--rik-accent)}#kb-hint .sep{opacity:0.4}#nav-arrows{position:fixed;bottom:2.4rem;right:1.5rem;display:flex;gap:4px;z-index:100;opacity:var(--deck-root-nav-opacity,0.35);transition:opacity 0.2s ease}#nav-arrows:hover{opacity:1}.nav-btn{appearance:none;cursor:pointer;width:30px;height:30px;display:grid;place-items:center;font:700 1rem/1 var(--rik-font-mono);color:var(--deck-root-nav-color,var(--rik-text-default));background:var(--deck-root-nav-bg,var(--rik-surface-raised));border:1px solid var(--rik-border-default);border-radius:6px;padding:0}.nav-btn:hover:not(:disabled){border-color:var(--rik-accent)}.nav-btn:disabled{opacity:0.3;cursor:default}#blank{position:fixed;inset:0;z-index:9999;cursor:pointer}#blank[data-tone="black"]{background:#000}#blank[data-tone="white"]{background:#fff}`,r.ZOOM_MAX=4,r.ZOOM_STEP=1.25,r.ZOOM_WHEEL_SENSITIVITY=.002,o([_()],r.prototype,"current",2),o([_()],r.prototype,"step",2),o([_()],r.prototype,"blank",2),o([_()],r.prototype,"presenterActive",2),o([l({type:Boolean,reflect:!0})],r.prototype,"overview",2),o([l({type:Boolean,reflect:!0})],r.prototype,"fluid",2),o([l({type:Number})],r.prototype,"width",2),o([l({type:Number})],r.prototype,"height",2),o([l({type:Boolean,reflect:!0,attribute:"no-hint"})],r.prototype,"noHint",2),o([l({type:Boolean,reflect:!0,attribute:"no-arrows"})],r.prototype,"noArrows",2),o([l({type:Boolean,reflect:!0,attribute:"no-counter"})],r.prototype,"noCounter",2),o([l({type:Boolean,reflect:!0})],r.prototype,"preview",2),o([l({type:Boolean,reflect:!0,attribute:"no-zoom"})],r.prototype,"noZoom",2),o([l({type:String,reflect:!0})],r.prototype,"transition",2),o([l({type:Number,reflect:!0})],r.prototype,"autoplay",2),o([l({type:Boolean,reflect:!0})],r.prototype,"loop",2),o([l({type:Boolean,reflect:!0})],r.prototype,"swipe",2),o([l({type:String,reflect:!0,attribute:"mouse-nav"})],r.prototype,"mouseNav",2),o([l({type:String,reflect:!0})],r.prototype,"nav",2),r=o([w("deck-root")],r);export{r as DeckRoot};
@@ -1,4 +1,4 @@
1
- var e={slide:560,"slide-up":520,"slide-down":520,"slide-right":560,fade:480,zoom:520,flip:560},r="var(--rik-motion__ease-out, cubic-bezier(0.16, 1, 0.3, 1))",y="var(--rik-motion__ease-spring, cubic-bezier(0.5, 1.8, 0.3, 1))",w=`
1
+ var e={slide:560,"slide-up":520,"slide-down":520,"slide-right":560,fade:480,zoom:520,flip:560},r="var(--rik-motion__ease-out, cubic-bezier(0.16, 1, 0.3, 1))",y="var(--rik-motion__ease-spring, cubic-bezier(0.5, 1.8, 0.3, 1))",$=`
2
2
  /* Incoming \xB7 from right (forward) */
3
3
  @keyframes rk-slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
4
4
  /* Outgoing \xB7 pushed off to the left (forward) */
@@ -48,4 +48,4 @@ var e={slide:560,"slide-up":520,"slide-down":520,"slide-right":560,fade:480,zoom
48
48
  ::slotted([active][class*='rk-enter-']),
49
49
  ::slotted(.rk-leaving) { animation: none; }
50
50
  }
51
- `,g=["rk-enter-slide","rk-enter-slide-up","rk-enter-slide-down","rk-enter-slide-right","rk-enter-fade","rk-enter-zoom","rk-enter-flip"],$=["rk-exit-slide","rk-exit-slide-up","rk-exit-slide-down","rk-exit-slide-right","rk-exit-fade","rk-exit-zoom","rk-exit-flip"];function x(s){if(s.__rkTransitions)return s.__rkTransitions;let f=s.shadowRoot;if(!f)return()=>{};let a=document.createElement("style");a.textContent=w,a.setAttribute("data-rik-transitions",""),f.appendChild(a);function h(m,n){if(!n)return 0;let t=m.compareDocumentPosition(n);return t&Node.DOCUMENT_POSITION_PRECEDING?1:t&Node.DOCUMENT_POSITION_FOLLOWING?-1:0}let d=m=>{if(s.__rkMorphActive)return;let n=m,t=n.detail.current,o=n.detail.previous;if(!t)return;let i=t.dataset.transition||s.transition||"fade",l=h(t,o);i==="slide"&&l<0?i="slide-right":i==="slide-right"&&l>0?i="slide":i==="slide-up"&&l<0?i="slide-down":i==="slide-down"&&l>0&&(i="slide-up");let u=`rk-enter-${i}`,p=`rk-exit-${i}`,v=e[i]??480;o&&o!==t&&(o.classList.remove(...g,...$,"rk-leaving"),o.style.display="flex",o.style.zIndex="1",o.offsetWidth,o.classList.add("rk-leaving",p),window.setTimeout(()=>{o.classList.remove("rk-leaving",p),o.style.display="",o.style.zIndex=""},v+40)),t.classList.remove(...g),t.style.zIndex="2",t.offsetWidth,t.classList.add(u),window.setTimeout(()=>{t.classList.remove(u),t.style.zIndex=""},v+40)};s.addEventListener("slide-change",d);let k=s.querySelector(":scope > [active]");k&&d(new CustomEvent("slide-change",{detail:{current:k,previous:null}}));let c=()=>{s.removeEventListener("slide-change",d),a.remove(),delete s.__rkTransitions};return s.__rkTransitions=c,c}export{x as installTransitions};
51
+ `,h=["rk-enter-slide","rk-enter-slide-up","rk-enter-slide-down","rk-enter-slide-right","rk-enter-fade","rk-enter-zoom","rk-enter-flip"],x=["rk-exit-slide","rk-exit-slide-up","rk-exit-slide-down","rk-exit-slide-right","rk-exit-fade","rk-exit-zoom","rk-exit-flip"];function E(s){let a=s;if(a.__rkTransitions)return a.__rkTransitions;let k=s.shadowRoot;if(!k)return()=>{};let l=document.createElement("style");l.textContent=$,l.setAttribute("data-rik-transitions",""),k.appendChild(l);function w(f,n){if(!n)return 0;let t=f.compareDocumentPosition(n);return t&Node.DOCUMENT_POSITION_PRECEDING?1:t&Node.DOCUMENT_POSITION_FOLLOWING?-1:0}let m=f=>{if(s.__rkMorphActive)return;let n=f,t=n.detail.current,o=n.detail.previous;if(!t)return;let i=t.dataset.transition||s.transition||"fade",d=w(t,o);i==="slide"&&d<0?i="slide-right":i==="slide-right"&&d>0?i="slide":i==="slide-up"&&d<0?i="slide-down":i==="slide-down"&&d>0&&(i="slide-up");let p=`rk-enter-${i}`,v=`rk-exit-${i}`,g=e[i]??480;o&&o!==t&&(o.classList.remove(...h,...x,"rk-leaving"),o.style.display="flex",o.style.zIndex="1",o.offsetWidth,o.classList.add("rk-leaving",v),window.setTimeout(()=>{o.classList.remove("rk-leaving",v),o.style.display="",o.style.zIndex=""},g+40)),t.classList.remove(...h),t.style.zIndex="2",t.offsetWidth,t.classList.add(p),window.setTimeout(()=>{t.classList.remove(p),t.style.zIndex=""},g+40)};s.addEventListener("slide-change",m);let c=s.querySelector(":scope > [active]");c&&m(new CustomEvent("slide-change",{detail:{current:c,previous:null}}));let u=()=>{s.removeEventListener("slide-change",m),l.remove(),delete a.__rkTransitions};return a.__rkTransitions=u,u}export{E as installTransitions};
package/dist/index.d.ts CHANGED
@@ -26,3 +26,6 @@ import './atoms/deck-badge.js';
26
26
  import './atoms/deck-kicker.js';
27
27
  import './atoms/deck-punch.js';
28
28
  import './atoms/deck-code.js';
29
+ export type { DeckPlugin, DeckContext } from './runtime/deck-root.js';
30
+ export type { DeckCodeHighlighter } from './atoms/deck-code.js';
31
+ export { setDeckCodeHighlighter } from './atoms/deck-code-highlighter.js';