@hyperframes/player 0.7.6 → 0.7.8
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/slideshow/hyperframes-slideshow.cjs +22 -22
- package/dist/slideshow/hyperframes-slideshow.cjs.map +1 -1
- package/dist/slideshow/hyperframes-slideshow.d.cts +42 -0
- package/dist/slideshow/hyperframes-slideshow.d.ts +42 -0
- package/dist/slideshow/hyperframes-slideshow.global.js +22 -22
- package/dist/slideshow/hyperframes-slideshow.global.js.map +1 -1
- package/dist/slideshow/hyperframes-slideshow.js +27 -27
- package/dist/slideshow/hyperframes-slideshow.js.map +1 -1
- package/package.json +2 -2
|
@@ -62,11 +62,13 @@ declare class HyperframesSlideshow extends HTMLElement {
|
|
|
62
62
|
private initGeneration;
|
|
63
63
|
private _muted;
|
|
64
64
|
private mediaWireInterval;
|
|
65
|
+
private playerObserver;
|
|
65
66
|
private applyingRemoteMedia;
|
|
66
67
|
private lastMediaTimeBroadcastMs;
|
|
67
68
|
private audienceMutedPlaybackKeys;
|
|
68
69
|
private blockedAudienceMedia;
|
|
69
70
|
private audienceMediaUnlockButton;
|
|
71
|
+
private autoplayToken;
|
|
70
72
|
/** Whether audio is currently muted. Reflects `data-hf-muted` attribute. */
|
|
71
73
|
get muted(): boolean;
|
|
72
74
|
/** Mode resolves from the `mode` attribute, falling back to the URL query
|
|
@@ -98,6 +100,23 @@ declare class HyperframesSlideshow extends HTMLElement {
|
|
|
98
100
|
private clearPresenterPositionTimers;
|
|
99
101
|
private startMediaSync;
|
|
100
102
|
private mediaPlayerElements;
|
|
103
|
+
/**
|
|
104
|
+
* Inner `<hyperframes-player>` instances inside a slideshow need the
|
|
105
|
+
* `interactive` attribute so clickable controls, links, native media
|
|
106
|
+
* controls, and custom players inside the composition iframe receive
|
|
107
|
+
* pointer events (the player's default is `pointer-events: none`).
|
|
108
|
+
*
|
|
109
|
+
* Set it mechanically so authors / agents don't have to remember.
|
|
110
|
+
* Idempotent: if the host already declared `interactive` (any value,
|
|
111
|
+
* including `interactive="false"`), it is preserved.
|
|
112
|
+
*/
|
|
113
|
+
private ensureInteractivePlayers;
|
|
114
|
+
/**
|
|
115
|
+
* Watch for `<hyperframes-player>` children added after the initial mount
|
|
116
|
+
* (dynamic templating, hydration, drag-drop authoring) and apply the
|
|
117
|
+
* `interactive` attribute to those too.
|
|
118
|
+
*/
|
|
119
|
+
private observeInteractivePlayers;
|
|
101
120
|
private playerFrameDocument;
|
|
102
121
|
private mediaKey;
|
|
103
122
|
private mediaEntries;
|
|
@@ -128,6 +147,29 @@ declare class HyperframesSlideshow extends HTMLElement {
|
|
|
128
147
|
private toggleMute;
|
|
129
148
|
private applyGlobalMute;
|
|
130
149
|
private stopDocumentMedia;
|
|
150
|
+
/**
|
|
151
|
+
* Play the `<video>` inside a given scene from its start — the runtime side of
|
|
152
|
+
* a slide's `autoplay`. Reaches into the same-origin composition iframe (which
|
|
153
|
+
* is pointer-events:none, so its own controls can't be clicked). The play()
|
|
154
|
+
* fires a "play" event that wireSlideshowMedia() mirrors to any audience
|
|
155
|
+
* window, so this runs on the presenter only — the audience drives its copy
|
|
156
|
+
* from those mirrored events, never on its own.
|
|
157
|
+
*
|
|
158
|
+
* Robust against two timing hazards: (1) the clip may not be in the iframe DOM
|
|
159
|
+
* yet at construction (first slide), and (2) the player drives clips during
|
|
160
|
+
* bootstrap and seeks the timeline on enter — both pause the clip (and reject
|
|
161
|
+
* an in-flight play() with AbortError), so a single play() loses the race. So
|
|
162
|
+
* we poll on a short timer: locate the clip, then assert play() until it is
|
|
163
|
+
* actually advancing across two ticks, then stop — leaving a later real user
|
|
164
|
+
* pause (presenter media controls) alone. A user gesture within the window
|
|
165
|
+
* (real browsers gate autoplay on one) lets the next tick's play() take.
|
|
166
|
+
* Token-guarded, so leaving the slide or disconnecting cancels it.
|
|
167
|
+
*/
|
|
168
|
+
private playSceneDocumentMedia;
|
|
169
|
+
/** Locate the scene's clip in the composition iframe(s). */
|
|
170
|
+
private findSceneVideo;
|
|
171
|
+
/** One autoplay poll step. Returns true once the clip is confirmed playing. */
|
|
172
|
+
private stepAutoplay;
|
|
131
173
|
private presenterNotesDeckKey;
|
|
132
174
|
private presenterNotesStorageKey;
|
|
133
175
|
private readPresenterNotes;
|
|
@@ -62,11 +62,13 @@ declare class HyperframesSlideshow extends HTMLElement {
|
|
|
62
62
|
private initGeneration;
|
|
63
63
|
private _muted;
|
|
64
64
|
private mediaWireInterval;
|
|
65
|
+
private playerObserver;
|
|
65
66
|
private applyingRemoteMedia;
|
|
66
67
|
private lastMediaTimeBroadcastMs;
|
|
67
68
|
private audienceMutedPlaybackKeys;
|
|
68
69
|
private blockedAudienceMedia;
|
|
69
70
|
private audienceMediaUnlockButton;
|
|
71
|
+
private autoplayToken;
|
|
70
72
|
/** Whether audio is currently muted. Reflects `data-hf-muted` attribute. */
|
|
71
73
|
get muted(): boolean;
|
|
72
74
|
/** Mode resolves from the `mode` attribute, falling back to the URL query
|
|
@@ -98,6 +100,23 @@ declare class HyperframesSlideshow extends HTMLElement {
|
|
|
98
100
|
private clearPresenterPositionTimers;
|
|
99
101
|
private startMediaSync;
|
|
100
102
|
private mediaPlayerElements;
|
|
103
|
+
/**
|
|
104
|
+
* Inner `<hyperframes-player>` instances inside a slideshow need the
|
|
105
|
+
* `interactive` attribute so clickable controls, links, native media
|
|
106
|
+
* controls, and custom players inside the composition iframe receive
|
|
107
|
+
* pointer events (the player's default is `pointer-events: none`).
|
|
108
|
+
*
|
|
109
|
+
* Set it mechanically so authors / agents don't have to remember.
|
|
110
|
+
* Idempotent: if the host already declared `interactive` (any value,
|
|
111
|
+
* including `interactive="false"`), it is preserved.
|
|
112
|
+
*/
|
|
113
|
+
private ensureInteractivePlayers;
|
|
114
|
+
/**
|
|
115
|
+
* Watch for `<hyperframes-player>` children added after the initial mount
|
|
116
|
+
* (dynamic templating, hydration, drag-drop authoring) and apply the
|
|
117
|
+
* `interactive` attribute to those too.
|
|
118
|
+
*/
|
|
119
|
+
private observeInteractivePlayers;
|
|
101
120
|
private playerFrameDocument;
|
|
102
121
|
private mediaKey;
|
|
103
122
|
private mediaEntries;
|
|
@@ -128,6 +147,29 @@ declare class HyperframesSlideshow extends HTMLElement {
|
|
|
128
147
|
private toggleMute;
|
|
129
148
|
private applyGlobalMute;
|
|
130
149
|
private stopDocumentMedia;
|
|
150
|
+
/**
|
|
151
|
+
* Play the `<video>` inside a given scene from its start — the runtime side of
|
|
152
|
+
* a slide's `autoplay`. Reaches into the same-origin composition iframe (which
|
|
153
|
+
* is pointer-events:none, so its own controls can't be clicked). The play()
|
|
154
|
+
* fires a "play" event that wireSlideshowMedia() mirrors to any audience
|
|
155
|
+
* window, so this runs on the presenter only — the audience drives its copy
|
|
156
|
+
* from those mirrored events, never on its own.
|
|
157
|
+
*
|
|
158
|
+
* Robust against two timing hazards: (1) the clip may not be in the iframe DOM
|
|
159
|
+
* yet at construction (first slide), and (2) the player drives clips during
|
|
160
|
+
* bootstrap and seeks the timeline on enter — both pause the clip (and reject
|
|
161
|
+
* an in-flight play() with AbortError), so a single play() loses the race. So
|
|
162
|
+
* we poll on a short timer: locate the clip, then assert play() until it is
|
|
163
|
+
* actually advancing across two ticks, then stop — leaving a later real user
|
|
164
|
+
* pause (presenter media controls) alone. A user gesture within the window
|
|
165
|
+
* (real browsers gate autoplay on one) lets the next tick's play() take.
|
|
166
|
+
* Token-guarded, so leaving the slide or disconnecting cancels it.
|
|
167
|
+
*/
|
|
168
|
+
private playSceneDocumentMedia;
|
|
169
|
+
/** Locate the scene's clip in the composition iframe(s). */
|
|
170
|
+
private findSceneVideo;
|
|
171
|
+
/** One autoplay poll step. Returns true once the clip is confirmed playing. */
|
|
172
|
+
private stepAutoplay;
|
|
131
173
|
private presenterNotesDeckKey;
|
|
132
174
|
private presenterNotesStorageKey;
|
|
133
175
|
private readPresenterNotes;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var HyperframesPlayer=(()=>{var S=Object.defineProperty;var
|
|
1
|
+
"use strict";var HyperframesPlayer=(()=>{var S=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var Y=(n,e)=>{for(var t in e)S(n,t,{get:e[t],enumerable:!0})},V=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of G(e))!j.call(n,r)&&r!==t&&S(n,r,{get:()=>e[r],enumerable:!(i=z(e,r))||i.enumerable});return n};var W=n=>V(S({},"__esModule",{value:!0}),n);var Ee={};Y(Ee,{HyperframesSlideshow:()=>y,dropInvalidSlides:()=>F});var X="application/hyperframes-slideshow+json";function J(n="i"){let e=X.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`<script[^>]*type=["']${e}["'][^>]*>([\\s\\S]*?)<\\/script>`,n)}function I(n){let t=J("i").exec(n);if(!t||t[1]===void 0)return null;let i=t[1].trim();if(i.length===0)return null;let r=JSON.parse(i);if(!te(r))throw new Error("slideshow island is not a valid SlideshowManifest");return r}function Q(n){return n===void 0||Array.isArray(n)&&n.every(e=>typeof e=="number")}function Z(n){return n===void 0||typeof n=="boolean"}function P(n){if(typeof n!="object"||n===null)return!1;let e=n;return!(typeof e.sceneId!="string"||!Q(e.fragments)||e.hotspots!==void 0&&!Array.isArray(e.hotspots)||!Z(e.autoplay))}function ee(n){if(typeof n!="object"||n===null)return!1;let e=n;return typeof e.id=="string"&&typeof e.label=="string"&&Array.isArray(e.slides)&&e.slides.every(P)}function te(n){if(typeof n!="object"||n===null||Array.isArray(n))return!1;let e=n;return!(!Array.isArray(e.slides)||!e.slides.every(P)||e.slideSequences!==void 0&&(!Array.isArray(e.slideSequences)||!e.slideSequences.every(ee)))}function ne(n,e){return`slide "${n}" sets ${e==="startTime"?"endTime":"startTime"} but ${e} cannot be resolved (no scene "${n}")`}function ie(n,e,t){let{startTime:i,endTime:r,sceneId:s}=n;if(i!==void 0&&r!==void 0)return{start:i,end:r};if(i===void 0&&r===void 0)return e?{start:e.start,end:e.start+e.duration}:(t.push(`slide references unresolved sceneId "${s}"`),{start:0,end:0});if(!e){let o=i===void 0?"startTime":"endTime";t.push(ne(s,o));let d=i??r??0;return{start:d,end:d}}return{start:i??e.start,end:r??e.start+e.duration}}function re(n,e,t,i,r){for(let s of e)(s<t||s>i)&&r.push(`slide "${n}" fragment ${s} is outside range [${t}, ${i}]`)}function E(n,e,t){let i=e.get(n.sceneId),{start:r,end:s}=ie(n,i,t);n.startTime!==void 0&&n.endTime!==void 0&&s<=r&&t.push(`slide "${n.sceneId}" has endTime (${s}) <= startTime (${r})`);let o=[...new Set(n.fragments??[])].sort((d,a)=>d-a);return re(n.sceneId,o,r,s,t),{...n,start:r,end:s,fragments:o,hotspots:n.hotspots??[]}}function A(n,e){let t=[],i=new Map(e.map(a=>[a.id,a])),r={};for(let a of n.slideSequences??[])Object.prototype.hasOwnProperty.call(r,a.id)&&t.push(`duplicate slideSequence id "${a.id}" \u2014 only the last definition is kept`),r[a.id]={id:a.id,label:a.label,slides:a.slides.map(l=>E(l,i,t))};let s=n.slides.map(a=>E(a,i,t)),o=[...s,...Object.values(r).flatMap(a=>a.slides)];for(let a of o)for(let l of a.hotspots){let u=r[l.target];u?u.slides.length===0&&t.push(`hotspot "${l.id}" targets empty sequence "${l.target}"`):t.push(`hotspot "${l.id}" targets unknown sequence "${l.target}"`)}let d=[...s].sort((a,l)=>a.start-l.start);for(let a=1;a<d.length;a++){let l=d[a-1],u=d[a];l!==void 0&&u!==void 0&&u.start<l.end&&t.push(`main-line slides "${l.sceneId}" and "${u.sceneId}" overlap`)}return{resolved:{slides:s,sequences:r},errors:t}}var f="main",g=class{constructor(e,t){this.player=e;this.show=t;this.enterSlide(0)}player;show;stack=[{sequenceId:f,slideIndex:0,fragmentIndex:-1}];changeCbs=new Set;dispose(){}slidesOf(e){return e===f?this.show.slides:this.show.sequences[e]?.slides??[]}get frame(){return this.stack[this.stack.length-1]}get currentSlide(){return this.slidesOf(this.frame.sequenceId)[this.frame.slideIndex]}get nextSlide(){return this.slidesOf(this.frame.sequenceId)[this.frame.slideIndex+1]??null}get position(){return{...this.frame}}get counter(){return{index:this.frame.slideIndex+1,total:this.slidesOf(this.frame.sequenceId).length}}get canPrev(){return this.frame.slideIndex>0||this.stack.length>1}get canNext(){let e=this.slidesOf(this.frame.sequenceId);return this.frame.slideIndex+1<e.length||this.stack.length>1}get breadcrumb(){return this.stack.map(e=>e.sequenceId===f?{id:f,label:"Main deck"}:{id:e.sequenceId,label:this.show.sequences[e.sequenceId]?.label??e.sequenceId})}onChange(e){return this.changeCbs.add(e),()=>this.changeCbs.delete(e)}emitChange(){for(let e of this.changeCbs)e()}stopSlideMedia(){this.player.stopMedia?.()}enterSlide(e){e!==this.frame.slideIndex&&this.stopSlideMedia(),this.frame.slideIndex=e;let t=this.currentSlide;if(!t){this.frame.fragmentIndex=-1;return}t.fragments.length>0?(this.frame.fragmentIndex=0,this.playTo(t.fragments[0]??t.end)):(this.frame.fragmentIndex=-1,this.playTo(this.restFrame(t))),t.autoplay&&this.player.playSceneMedia?.(t.sceneId),this.emitChange()}restFrame(e){return e.start+(e.end-e.start)*.5}resumeSlide(e,t){this.frame.slideIndex=e,this.frame.fragmentIndex=t;let i=this.currentSlide;if(!i)return;let r=t>=0&&t<i.fragments.length?i.fragments[t]??i.start:i.fragments.length>0?i.start:this.restFrame(i);this.playTo(r),this.emitChange()}playTo(e){this.player.seek(e)}next(){let e=this.currentSlide;if(!e)return;if(this.frame.fragmentIndex+1<e.fragments.length){this.frame.fragmentIndex+=1;let r=e.fragments[this.frame.fragmentIndex]??e.end;this.playTo(r),this.emitChange();return}let i=this.slidesOf(this.frame.sequenceId);this.frame.slideIndex+1<i.length?this.enterSlide(this.frame.slideIndex+1):this.stack.length>1&&this.back()}prev(){if(this.frame.slideIndex>0){this.enterSlide(this.frame.slideIndex-1);return}this.stack.length>1&&this.back()}goToSlide(e){let t=this.slidesOf(this.frame.sequenceId);e>=0&&e<t.length&&this.enterSlide(e)}enterBranch(e){let t=this.show.sequences[e];!t||t.slides.length===0||(this.stopSlideMedia(),this.stack.push({sequenceId:e,slideIndex:0,fragmentIndex:-1}),this.enterSlide(0))}back(){this.stack.length<=1||(this.stopSlideMedia(),this.stack.pop(),this.resumeSlide(this.frame.slideIndex,this.frame.fragmentIndex))}backToMain(){this.stack.length<=1||(this.stopSlideMedia(),this.stack=[this.stack[0]],this.resumeSlide(this.frame.slideIndex,this.frame.fragmentIndex))}syncTo(e,t,i){this.isValidSyncTarget(e,t)&&(this.isCrossSlide(e,t)&&this.stopSlideMedia(),this.rerootStackTo(e)&&this.resumeSlide(t,i))}isValidSyncTarget(e,t){if(!this.stack[0])return!1;let i=e===f?this.show.slides:this.show.sequences[e]?.slides??null;return i?t>=0&&t<i.length:!1}isCrossSlide(e,t){return this.frame.sequenceId!==e||this.frame.slideIndex!==t}rerootStackTo(e){if(this.frame.sequenceId===e)return!0;let t=this.stack[0];if(!t)return!1;if(this.stack=[t],e===f)return!0;let i=this.show.sequences[e];return!i||i.slides.length===0?!1:(this.stack.push({sequenceId:e,slideIndex:0,fragmentIndex:-1}),!0)}};var $="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",se=new Set(["play","pause","seeking","seeked","ratechange","volumechange","ended","timeupdate"]),oe=["currentTime","volume","playbackRate"],ae=["paused","ended","muted"];function C(n){return!(typeof n!="object"||n===null)}function le(n){if(!C(n))return!1;let e=n;return e.type==="goto"&&typeof e.sequenceId=="string"&&typeof e.slideIndex=="number"&&typeof e.fragmentIndex=="number"}function de(n){return se.has(n)}function ue(n){return n==="presenter"||n==="audience"}function ce(n){return oe.every(e=>typeof n[e]=="number")}function he(n){return ae.every(e=>typeof n[e]=="boolean")}function pe(n){if(!C(n))return!1;let e=n;return e.type==="media"&&ue(e.sender)&&typeof e.key=="string"&&de(e.action)&&ce(e)&&he(e)}function fe(){return`hf-slideshow:${typeof location<"u"?location.pathname:""}`}var m=class{constructor(e,t,i=()=>{}){this.mode=e;this.onGoto=t;this.onMedia=i;try{this.channel=new BroadcastChannel(fe())}catch{return}this.channel.onmessage=r=>{if(le(r.data)){e==="audience"&&this.onGoto(r.data);return}pe(r.data)&&r.data.sender!==e&&this.onMedia(r.data)}}mode;onGoto;onMedia;channel=null;postPosition(e){if(this.mode!=="presenter"||!this.channel)return;let t={type:"goto",...e};this.channel.postMessage(t)}postMedia(e){this.channel&&this.channel.postMessage({type:"media",sender:this.mode,...e})}destroy(){this.channel&&(this.channel.onmessage=null,this.channel.close(),this.channel=null)}};function R(n){let e=s=>s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),t=s=>e(s).replace(/"/g,"""),i=e(n.notes),r=n.hotspots.length?`<div style="display:flex;flex-direction:column;gap:6px;">
|
|
2
2
|
<div style="font-size:12px;text-transform:uppercase;letter-spacing:.12em;opacity:.55;">Branches</div>
|
|
3
3
|
${n.hotspots.map(s=>`<button data-hotspot-id="${t(s.id)}" data-hotspot-target="${t(s.target)}" type="button" title="${t(s.label)}" style="text-align:left;background:rgba(244,183,64,0.14);color:#f4b740;border:1px solid rgba(244,183,64,0.4);border-radius:8px;padding:8px 12px;font-size:15px;cursor:pointer;pointer-events:auto;font-family:inherit;">↳ ${e(s.label)}</button>`).join("")}
|
|
4
4
|
</div>`:"";return`
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
<div data-hf-presenter-next style="font-size:17px;opacity:.9;line-height:1.4;">${e(n.nextText)}</div>
|
|
10
10
|
${r}
|
|
11
11
|
<div style="display:flex;gap:34px;margin-top:auto;">
|
|
12
|
-
<div><div style="font-size:11px;text-transform:uppercase;letter-spacing:.1em;opacity:.5;margin-bottom:3px;">Slide</div><div data-hf-presenter-counter style="font-family:${
|
|
13
|
-
<div><div style="font-size:11px;text-transform:uppercase;letter-spacing:.1em;opacity:.5;margin-bottom:3px;">Elapsed</div><div data-hf-presenter-elapsed style="font-family:${
|
|
12
|
+
<div><div style="font-size:11px;text-transform:uppercase;letter-spacing:.1em;opacity:.5;margin-bottom:3px;">Slide</div><div data-hf-presenter-counter style="font-family:${$};font-size:23px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:0;">${e(n.counterText)}</div></div>
|
|
13
|
+
<div><div style="font-size:11px;text-transform:uppercase;letter-spacing:.1em;opacity:.5;margin-bottom:3px;">Elapsed</div><div data-hf-presenter-elapsed style="font-family:${$};font-size:23px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:0;">${e(n.elapsedText)}</div></div>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
|
-
</div>`.trim()}function w(n){let e=Math.floor(n/60),t=Math.floor(n%60);return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}`}function
|
|
16
|
+
</div>`.trim()}function w(n){let e=Math.floor(n/60),t=Math.floor(n%60);return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}`}var L=150,me=6e3;function ve(n){return typeof n.seek=="function"&&typeof n.play=="function"&&typeof n.pause=="function"}var ge="hf-slideshow:presenter-notes:v1:",q=!1;function ye(){if(q)return;q=!0;let n=document.createElement("style");n.textContent=`
|
|
17
17
|
@keyframes hf-hotspot-pulse {
|
|
18
18
|
0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0.35), 0 4px 16px rgba(0,0,0,0.35); }
|
|
19
19
|
50% { box-shadow: 0 0 0 8px rgba(255,255,255,0), 0 4px 20px rgba(0,0,0,0.45); }
|
|
@@ -77,14 +77,14 @@
|
|
|
77
77
|
[data-hf-muted] [data-hf-mute]:hover {
|
|
78
78
|
color: rgba(255,255,255,0.6) !important;
|
|
79
79
|
}
|
|
80
|
-
`,document.head.appendChild(n)}var q='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3H5a2 2 0 0 0-2 2v3M21 8V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3M16 21h3a2 2 0 0 0 2-2v-3"/></svg>',N='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v3a2 2 0 0 1-2 2H3M21 8h-3a2 2 0 0 1-2-2V3M3 16h3a2 2 0 0 1 2 2v3M16 21v-3a2 2 0 0 1 2-2h3"/></svg>',me='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="13" rx="2"/><path d="M8 21h8"/><path d="M12 17v4"/><path d="M10 8.5v4l4-2-4-2z"/></svg>',ge="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",b=class extends HTMLElement{controller=null;offChange=null;chrome=null;touchStartX=0;touchStartY=0;channel=null;presenterStartMs=null;presenterInterval=null;presenterPositionTimers=[];disconnected=!1;initTimer=null;initInFlight=!1;initGeneration=0;_muted=!1;mediaWireInterval=null;applyingRemoteMedia=!1;lastMediaTimeBroadcastMs=0;audienceMutedPlaybackKeys=new Set;blockedAudienceMedia=new Map;audienceMediaUnlockButton=null;get muted(){return this._muted}resolveMode(){let e=this.getAttribute("mode");if(e)return e;try{return new URLSearchParams(location.search).get("mode")}catch{return null}}static get observedAttributes(){return["sound","mode"]}attributeChangedCallback(){this.controller&&this.render()}connectedCallback(){this.disconnected=!1,this.initInFlight=!1,this.initGeneration+=1,this.tabIndex=0,window.addEventListener("keydown",this.onKey),this.addEventListener("touchstart",this.onTouchStart,{passive:!0}),this.addEventListener("touchend",this.onTouchEnd),window.addEventListener("message",this.onMessage),document.addEventListener("fullscreenchange",this.onFsChange),this.initChannel(),this.initTimer=setTimeout(()=>{this.initTimer=null,this.isConnected&&!this.disconnected&&this.init()},0)}disconnectedCallback(){this.disconnected=!0,this.initGeneration+=1,this.initTimer!==null&&(clearTimeout(this.initTimer),this.initTimer=null),window.removeEventListener("keydown",this.onKey),this.removeEventListener("touchstart",this.onTouchStart),this.removeEventListener("touchend",this.onTouchEnd),window.removeEventListener("message",this.onMessage),document.removeEventListener("fullscreenchange",this.onFsChange),this.offChange?.(),this.offChange=null,this.controller?.dispose?.(),this.controller=null,this.chrome=null,this.channel?.destroy(),this.channel=null,this.mediaWireInterval!==null&&(clearInterval(this.mediaWireInterval),this.mediaWireInterval=null),this.audienceMediaUnlockButton?.remove(),this.audienceMediaUnlockButton=null,this.audienceMutedPlaybackKeys.clear(),this.blockedAudienceMedia.clear(),this.presenterInterval!==null&&(clearInterval(this.presenterInterval),this.presenterInterval=null),this.clearPresenterPositionTimers()}__setControllerForTest(e){this.bindController(e)}present(){if(this.resolveMode()==="audience"||this.getAttribute("data-hf-presenting")==="true")return;let e=location.search?"&":"?";window.open(location.href+e+"mode=audience","_blank","noopener,noreferrer"),this.setAttribute("data-hf-presenting","true"),this.postCurrentPresenterPositionBurst(),this.presenterStartMs=Date.now(),this.presenterInterval===null&&(this.presenterInterval=setInterval(()=>this.updateElapsed(),1e3)),this.render()}updateElapsed(){if(this.presenterStartMs===null)return;let e=this.chrome?.querySelector("[data-hf-presenter-elapsed]");e&&(e.textContent=w(Math.floor((Date.now()-this.presenterStartMs)/1e3)))}initChannel(){this.resolveMode()==="audience"?this.channel=new m("audience",t=>{this.controller&&this.controller.syncTo?.(t.sequenceId,t.slideIndex,t.fragmentIndex)},this.onRemoteMedia):this.channel=new m("presenter",()=>{},this.onRemoteMedia)}async init(){if(this.initInFlight)return;this.initInFlight=!0;let e=this.initGeneration;try{let t=this.querySelector("hyperframes-player");if(!t||!(t instanceof HTMLElement))return;let i=this.innerHTML,r;try{r=I(i)}catch{return}if(!r||(this.renderInitialChrome(r),!he(t))||(await xe(t),e!==this.initGeneration))return;let s=await Me(t,2500,()=>e!==this.initGeneration);if(e!==this.initGeneration)return;let{resolved:a,errors:d}=$(r,s);d.length>0&&console.warn("[hyperframes-slideshow] manifest errors:",d);let o=H(a);o.slides.length===0&&r.slides.length>0&&console.error("[hyperframes-slideshow] no main-line slides resolved \u2014 the scene timeline may not have loaded in time, or sceneIds/timing are invalid:",d);let l={seek:u=>t.seek(u),play:()=>t.play(),pause:()=>t.pause(),stopMedia:()=>{t.stopMedia?.(),this.stopDocumentMedia()},get currentTime(){return t.currentTime},onTimeUpdate:u=>{let p=c=>{let y=c.detail;u(y.currentTime)};return t.addEventListener("timeupdate",p),()=>t.removeEventListener("timeupdate",p)}};this.bindController(new v(l,o)),s.length===0&&r.slides.length>0&&t.addEventListener("scenes",()=>{e===this.initGeneration&&this.init()},{once:!0})}finally{this.initInFlight=!1}}renderInitialChrome(e){if(this.controller||e.slides.length===0)return;let t={index:1,total:e.slides.length};if(this.resolveMode()==="audience"){this.paintChrome(this.buildNavCluster(t,"28px","fs-only"));return}this.paintChrome(this.buildNavCluster(t,"28px","full",{canPrev:!1,canNext:e.slides.length>1,loading:e.slides.length>1}))}bindController(e){this.offChange?.(),this.controller?.dispose?.(),this.controller=e,this.startMediaSync(),this.offChange=e.onChange(()=>{this.resolveMode()!=="audience"&&this.channel&&this.channel.postPosition(e.position),this.render()}),this.resolveMode()!=="audience"&&this.channel&&this.channel.postPosition(e.position),this.render()}postCurrentPresenterPosition(){this.resolveMode()==="audience"||!this.channel||!this.controller||this.channel.postPosition(this.controller.position)}postCurrentPresenterPositionBurst(){this.clearPresenterPositionTimers(),this.postCurrentPresenterPosition();for(let e of[250,750,1500,3e3,5e3]){let t=setTimeout(()=>{this.presenterPositionTimers=this.presenterPositionTimers.filter(i=>i!==t),this.postCurrentPresenterPosition()},e);this.presenterPositionTimers.push(t)}}clearPresenterPositionTimers(){for(let e of this.presenterPositionTimers)clearTimeout(e);this.presenterPositionTimers=[]}startMediaSync(){this.wireSlideshowMedia(),this.mediaWireInterval===null&&(this.mediaWireInterval=setInterval(()=>this.wireSlideshowMedia(),1e3))}mediaPlayerElements(){return Array.from(this.querySelectorAll("hyperframes-player")).filter(e=>e instanceof HTMLElement)}playerFrameDocument(e){let t=e.iframeElement;if(!(t instanceof HTMLIFrameElement))return null;try{return t.contentDocument}catch{return null}}mediaKey(e,t,i,r){let s=e.id?`player-id:${e.id}`:`player:${t}`,a=i.id?`id:${i.id}`:`${i.tagName.toLowerCase()}:${r}`;return`${s}|${a}`}mediaEntries(){let e=[];return this.mediaPlayerElements().forEach((t,i)=>{let r=this.playerFrameDocument(t);r&&Array.from(r.querySelectorAll("video,audio")).filter(be).forEach((s,a)=>{e.push({key:this.mediaKey(t,i,s,a),el:s})})}),e}wireSlideshowMedia(){let e=["play","pause","seeking","seeked","ratechange","volumechange","ended","timeupdate"];for(let{key:t,el:i}of this.mediaEntries())if(i.dataset.hfSlideshowMediaSync!=="1"){i.dataset.hfSlideshowMediaSync="1";for(let r of e)i.addEventListener(r,()=>this.publishMediaState(i,t,r))}}publishMediaState(e,t,i){if(!(this.applyingRemoteMedia||this.resolveMode()==="audience"||!this.channel)){if(i==="timeupdate"){let r=performance.now();if(r-this.lastMediaTimeBroadcastMs<450&&!e.paused)return;this.lastMediaTimeBroadcastMs=r}this.channel.postMedia({key:t,action:i,currentTime:g(e.currentTime,0),paused:e.paused,ended:e.ended,muted:e.muted,volume:g(e.volume,1),playbackRate:g(e.playbackRate,1)})}}onRemoteMedia=e=>{if(this.resolveMode()!=="audience")return;if(this.blockedAudienceMedia.has(e.key)&&e.action==="timeupdate"){this.blockedAudienceMedia.set(e.key,e),this.showAudienceMediaUnlock();return}this.wireSlideshowMedia();let t=this.mediaEntries().find(i=>i.key===e.key);if(t){this.applyingRemoteMedia=!0;try{this.applyRemoteMedia(t.el,e)}finally{setTimeout(()=>{this.applyingRemoteMedia=!1},300)}}};applyRemoteMedia(e,t){if(t.action==="pause"||t.action==="ended"){this.audienceMutedPlaybackKeys.delete(t.key),this.blockedAudienceMedia.delete(t.key),this.syncRemoteMediaState(e,t,!0),e.pause(),this.hideAudienceMediaUnlockIfClear();return}if(t.action==="play"||t.action==="timeupdate"&&t.paused===!1&&e.paused){this.playAudienceMediaMuted(e,t);return}this.syncRemoteMediaState(e,t,!0)}syncRemoteMediaState(e,t,i){e.playbackRate=g(t.playbackRate,1),e.volume=Math.max(0,Math.min(1,g(t.volume,1))),e.muted=this.audienceMutedPlaybackKeys.has(t.key)?!0:t.muted,i&&Number.isFinite(t.currentTime)&&Math.abs((e.currentTime||0)-t.currentTime)>.35&&(e.currentTime=Math.max(0,t.currentTime))}playAudienceMediaMuted(e,t){this.audienceMutedPlaybackKeys.add(t.key),this.syncRemoteMediaState(e,t,!0),e.muted=!0;try{e.play().then(()=>{this.blockedAudienceMedia.delete(t.key),this.hideAudienceMediaUnlockIfClear()}).catch(()=>{this.blockedAudienceMedia.set(t.key,t),this.showAudienceMediaUnlock()})}catch{this.blockedAudienceMedia.set(t.key,t),this.showAudienceMediaUnlock()}}retryBlockedAudienceMedia=()=>{this.wireSlideshowMedia();let e=new Map(this.mediaEntries().map(t=>[t.key,t.el]));for(let[t,i]of this.blockedAudienceMedia){let r=e.get(t);r&&this.playAudienceMediaMuted(r,i)}};showAudienceMediaUnlock(){if(this.resolveMode()!=="audience"||this.audienceMediaUnlockButton)return;let e=document.createElement("button");e.type="button",e.textContent="Play audience media muted",e.style.cssText="position:fixed;left:50%;bottom:96px;transform:translateX(-50%);z-index:100000;border:0;border-radius:999px;padding:12px 18px;background:#fff;color:#111827;box-shadow:0 10px 32px rgba(0,0,0,.28);font:700 14px/1 system-ui,sans-serif;cursor:pointer;pointer-events:auto;",e.addEventListener("click",this.retryBlockedAudienceMedia),this.appendChild(e),this.audienceMediaUnlockButton=e}hideAudienceMediaUnlockIfClear(){this.blockedAudienceMedia.size>0||!this.audienceMediaUnlockButton||(this.audienceMediaUnlockButton.remove(),this.audienceMediaUnlockButton=null)}onKey=e=>{if(!this.controller)return;let t=e.target;if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement||t instanceof HTMLElement&&t.isContentEditable)return;let i=document.activeElement,r=i===this||this.contains(i),s=document.querySelectorAll("hyperframes-slideshow").length>1,a=r||!s&&(i===document.body||i===null);if(e.key==="ArrowRight"){if(!a)return;this.controller.next(),e.preventDefault()}else if(e.key==="ArrowLeft"){if(!a)return;this.controller.prev(),e.preventDefault()}else if(e.key===" "){if(!r)return;this.controller.next(),e.preventDefault()}else if(e.key==="Backspace"){if(!r)return;this.controller.prev(),e.preventDefault()}else if((e.key==="f"||e.key==="F")&&!e.metaKey&&!e.ctrlKey&&!e.altKey){if(!r)return;this.toggleFullscreen(),e.preventDefault()}else if((e.key==="p"||e.key==="P")&&!e.metaKey&&!e.ctrlKey&&!e.altKey){if(!a||!this.shouldShowPresentControl())return;this.present(),e.preventDefault()}};onMessage=e=>{if(this.resolveMode()==="audience")return;let t=e.data;!t||!this.controller||(t.type==="next"?this.controller.next():t.type==="prev"?this.controller.prev():t.type==="goto"&&typeof t.slideIndex=="number"?this.controller.goToSlide?.(t.slideIndex):t.type==="back"&&this.controller.back?.())};onTouchStart=e=>{let t=e.touches[0];t&&(this.touchStartX=t.clientX,this.touchStartY=t.clientY)};onTouchEnd=e=>{if(!this.controller)return;let t=e.changedTouches[0];if(!t)return;let i=t.clientX-this.touchStartX,r=t.clientY-this.touchStartY;Math.abs(i)<=40||Math.abs(i)<=Math.abs(r)||(i<0?this.controller.next():this.controller.prev())};render(){if(!this.controller)return;if(this.resolveMode()==="audience"){let{counter:r}=this.controller;this.paintChrome(this.buildNavCluster(r,"28px","fs-only"));return}if(this.getAttribute("data-hf-presenting")==="true"){this.renderPresenter();return}let{counter:e,currentSlide:t}=this.controller;if(!t)return;let i=t.hotspots.map(r=>{let s=r.region?`left:${r.region.x}%;top:${r.region.y}%;`:"right:5%;bottom:18%;";return`<button
|
|
80
|
+
`,document.head.appendChild(n)}var N='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3H5a2 2 0 0 0-2 2v3M21 8V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3M16 21h3a2 2 0 0 0 2-2v-3"/></svg>',H='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v3a2 2 0 0 1-2 2H3M21 8h-3a2 2 0 0 1-2-2V3M3 16h3a2 2 0 0 1 2 2v3M16 21v-3a2 2 0 0 1 2-2h3"/></svg>',be='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="13" rx="2"/><path d="M8 21h8"/><path d="M12 17v4"/><path d="M10 8.5v4l4-2-4-2z"/></svg>',Me="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",y=class extends HTMLElement{controller=null;offChange=null;chrome=null;touchStartX=0;touchStartY=0;channel=null;presenterStartMs=null;presenterInterval=null;presenterPositionTimers=[];disconnected=!1;initTimer=null;initInFlight=!1;initGeneration=0;_muted=!1;mediaWireInterval=null;playerObserver=null;applyingRemoteMedia=!1;lastMediaTimeBroadcastMs=0;audienceMutedPlaybackKeys=new Set;blockedAudienceMedia=new Map;audienceMediaUnlockButton=null;autoplayToken=0;get muted(){return this._muted}resolveMode(){let e=this.getAttribute("mode");if(e)return e;try{return new URLSearchParams(location.search).get("mode")}catch{return null}}static get observedAttributes(){return["sound","mode"]}attributeChangedCallback(){this.controller&&this.render()}connectedCallback(){this.disconnected=!1,this.initInFlight=!1,this.initGeneration+=1,this.tabIndex=0,window.addEventListener("keydown",this.onKey),this.addEventListener("touchstart",this.onTouchStart,{passive:!0}),this.addEventListener("touchend",this.onTouchEnd),window.addEventListener("message",this.onMessage),document.addEventListener("fullscreenchange",this.onFsChange),this.initChannel(),this.observeInteractivePlayers(),this.initTimer=setTimeout(()=>{this.initTimer=null,this.isConnected&&!this.disconnected&&(this.ensureInteractivePlayers(),this.init())},0)}disconnectedCallback(){this.disconnected=!0,this.initGeneration+=1,this.autoplayToken++,this.initTimer!==null&&(clearTimeout(this.initTimer),this.initTimer=null),window.removeEventListener("keydown",this.onKey),this.removeEventListener("touchstart",this.onTouchStart),this.removeEventListener("touchend",this.onTouchEnd),window.removeEventListener("message",this.onMessage),document.removeEventListener("fullscreenchange",this.onFsChange),this.offChange?.(),this.offChange=null,this.controller?.dispose?.(),this.controller=null,this.chrome=null,this.channel?.destroy(),this.channel=null,this.mediaWireInterval!==null&&(clearInterval(this.mediaWireInterval),this.mediaWireInterval=null),this.playerObserver!==null&&(this.playerObserver.disconnect(),this.playerObserver=null),this.audienceMediaUnlockButton?.remove(),this.audienceMediaUnlockButton=null,this.audienceMutedPlaybackKeys.clear(),this.blockedAudienceMedia.clear(),this.presenterInterval!==null&&(clearInterval(this.presenterInterval),this.presenterInterval=null),this.clearPresenterPositionTimers()}__setControllerForTest(e){this.bindController(e)}present(){if(this.resolveMode()==="audience"||this.getAttribute("data-hf-presenting")==="true")return;let e=location.search?"&":"?";window.open(location.href+e+"mode=audience","_blank","noopener,noreferrer"),this.setAttribute("data-hf-presenting","true"),this.postCurrentPresenterPositionBurst(),this.presenterStartMs=Date.now(),this.presenterInterval===null&&(this.presenterInterval=setInterval(()=>this.updateElapsed(),1e3)),this.render()}updateElapsed(){if(this.presenterStartMs===null)return;let e=this.chrome?.querySelector("[data-hf-presenter-elapsed]");e&&(e.textContent=w(Math.floor((Date.now()-this.presenterStartMs)/1e3)))}initChannel(){this.resolveMode()==="audience"?this.channel=new m("audience",t=>{this.controller&&this.controller.syncTo?.(t.sequenceId,t.slideIndex,t.fragmentIndex)},this.onRemoteMedia):this.channel=new m("presenter",()=>{},this.onRemoteMedia)}async init(){if(this.initInFlight)return;this.initInFlight=!0;let e=this.initGeneration;try{let t=this.querySelector("hyperframes-player");if(!t||!(t instanceof HTMLElement))return;let i=this.innerHTML,r;try{r=I(i)}catch{return}if(!r||(this.renderInitialChrome(r),!ve(t))||(await ke(t),e!==this.initGeneration))return;let s=await Te(t,2500,()=>e!==this.initGeneration);if(e!==this.initGeneration)return;let{resolved:o,errors:d}=A(r,s);d.length>0&&console.warn("[hyperframes-slideshow] manifest errors:",d);let a=F(o);a.slides.length===0&&r.slides.length>0&&console.error("[hyperframes-slideshow] no main-line slides resolved \u2014 the scene timeline may not have loaded in time, or sceneIds/timing are invalid:",d);let l={seek:u=>t.seek(u),play:()=>t.play(),pause:()=>t.pause(),stopMedia:()=>{t.stopMedia?.(),this.stopDocumentMedia()},playSceneMedia:u=>this.playSceneDocumentMedia(u),get currentTime(){return t.currentTime},onTimeUpdate:u=>{let p=c=>{let b=c.detail;u(b.currentTime)};return t.addEventListener("timeupdate",p),()=>t.removeEventListener("timeupdate",p)}};this.bindController(new g(l,a)),s.length===0&&r.slides.length>0&&t.addEventListener("scenes",()=>{e===this.initGeneration&&this.init()},{once:!0})}finally{this.initInFlight=!1}}renderInitialChrome(e){if(this.controller||e.slides.length===0)return;let t={index:1,total:e.slides.length};if(this.resolveMode()==="audience"){this.paintChrome(this.buildNavCluster(t,"28px","fs-only"));return}this.paintChrome(this.buildNavCluster(t,"28px","full",{canPrev:!1,canNext:e.slides.length>1,loading:e.slides.length>1}))}bindController(e){this.offChange?.(),this.controller?.dispose?.(),this.controller=e,this.startMediaSync(),this.offChange=e.onChange(()=>{this.resolveMode()!=="audience"&&this.channel&&this.channel.postPosition(e.position),this.render()}),this.resolveMode()!=="audience"&&this.channel&&this.channel.postPosition(e.position),this.render()}postCurrentPresenterPosition(){this.resolveMode()==="audience"||!this.channel||!this.controller||this.channel.postPosition(this.controller.position)}postCurrentPresenterPositionBurst(){this.clearPresenterPositionTimers(),this.postCurrentPresenterPosition();for(let e of[250,750,1500,3e3,5e3]){let t=setTimeout(()=>{this.presenterPositionTimers=this.presenterPositionTimers.filter(i=>i!==t),this.postCurrentPresenterPosition()},e);this.presenterPositionTimers.push(t)}}clearPresenterPositionTimers(){for(let e of this.presenterPositionTimers)clearTimeout(e);this.presenterPositionTimers=[]}startMediaSync(){this.wireSlideshowMedia(),this.mediaWireInterval===null&&(this.mediaWireInterval=setInterval(()=>this.wireSlideshowMedia(),1e3))}mediaPlayerElements(){return Array.from(this.querySelectorAll("hyperframes-player")).filter(e=>e instanceof HTMLElement)}ensureInteractivePlayers(){for(let e of this.querySelectorAll("hyperframes-player"))e.hasAttribute("interactive")||e.setAttribute("interactive","")}observeInteractivePlayers(){typeof MutationObserver>"u"||this.playerObserver===null&&(this.playerObserver=new MutationObserver(()=>this.ensureInteractivePlayers()),this.playerObserver.observe(this,{childList:!0,subtree:!0}))}playerFrameDocument(e){let t=e.iframeElement;if(!(t instanceof HTMLIFrameElement))return null;try{return t.contentDocument}catch{return null}}mediaKey(e,t,i,r){let s=e.id?`player-id:${e.id}`:`player:${t}`,o=i.id?`id:${i.id}`:`${i.tagName.toLowerCase()}:${r}`;return`${s}|${o}`}mediaEntries(){let e=[];return this.mediaPlayerElements().forEach((t,i)=>{let r=this.playerFrameDocument(t);r&&Array.from(r.querySelectorAll("video,audio")).filter(Se).forEach((s,o)=>{e.push({key:this.mediaKey(t,i,s,o),el:s})})}),e}wireSlideshowMedia(){let e=["play","pause","seeking","seeked","ratechange","volumechange","ended","timeupdate"];for(let{key:t,el:i}of this.mediaEntries())if(i.dataset.hfSlideshowMediaSync!=="1"){i.dataset.hfSlideshowMediaSync="1";for(let r of e)i.addEventListener(r,()=>this.publishMediaState(i,t,r))}}publishMediaState(e,t,i){if(!(this.applyingRemoteMedia||this.resolveMode()==="audience"||!this.channel)){if(i==="timeupdate"){let r=performance.now();if(r-this.lastMediaTimeBroadcastMs<450&&!e.paused)return;this.lastMediaTimeBroadcastMs=r}this.channel.postMedia({key:t,action:i,currentTime:v(e.currentTime,0),paused:e.paused,ended:e.ended,muted:e.muted,volume:v(e.volume,1),playbackRate:v(e.playbackRate,1)})}}onRemoteMedia=e=>{if(this.resolveMode()!=="audience")return;if(this.blockedAudienceMedia.has(e.key)&&e.action==="timeupdate"){this.blockedAudienceMedia.set(e.key,e),this.showAudienceMediaUnlock();return}this.wireSlideshowMedia();let t=this.mediaEntries().find(i=>i.key===e.key);if(t){this.applyingRemoteMedia=!0;try{this.applyRemoteMedia(t.el,e)}finally{setTimeout(()=>{this.applyingRemoteMedia=!1},300)}}};applyRemoteMedia(e,t){if(t.action==="pause"||t.action==="ended"){this.audienceMutedPlaybackKeys.delete(t.key),this.blockedAudienceMedia.delete(t.key),this.syncRemoteMediaState(e,t,!0),e.pause(),this.hideAudienceMediaUnlockIfClear();return}if(t.action==="play"||t.action==="timeupdate"&&t.paused===!1&&e.paused){this.playAudienceMediaMuted(e,t);return}this.syncRemoteMediaState(e,t,!0)}syncRemoteMediaState(e,t,i){e.playbackRate=v(t.playbackRate,1),e.volume=Math.max(0,Math.min(1,v(t.volume,1))),e.muted=this.audienceMutedPlaybackKeys.has(t.key)?!0:t.muted,i&&Number.isFinite(t.currentTime)&&Math.abs((e.currentTime||0)-t.currentTime)>.35&&(e.currentTime=Math.max(0,t.currentTime))}playAudienceMediaMuted(e,t){this.audienceMutedPlaybackKeys.add(t.key),this.syncRemoteMediaState(e,t,!0),e.muted=!0;try{e.play().then(()=>{this.blockedAudienceMedia.delete(t.key),this.hideAudienceMediaUnlockIfClear()}).catch(()=>{this.blockedAudienceMedia.set(t.key,t),this.showAudienceMediaUnlock()})}catch{this.blockedAudienceMedia.set(t.key,t),this.showAudienceMediaUnlock()}}retryBlockedAudienceMedia=()=>{this.wireSlideshowMedia();let e=new Map(this.mediaEntries().map(t=>[t.key,t.el]));for(let[t,i]of this.blockedAudienceMedia){let r=e.get(t);r&&this.playAudienceMediaMuted(r,i)}};showAudienceMediaUnlock(){if(this.resolveMode()!=="audience"||this.audienceMediaUnlockButton)return;let e=document.createElement("button");e.type="button",e.textContent="Play audience media muted",e.style.cssText="position:fixed;left:50%;bottom:96px;transform:translateX(-50%);z-index:100000;border:0;border-radius:999px;padding:12px 18px;background:#fff;color:#111827;box-shadow:0 10px 32px rgba(0,0,0,.28);font:700 14px/1 system-ui,sans-serif;cursor:pointer;pointer-events:auto;",e.addEventListener("click",this.retryBlockedAudienceMedia),this.appendChild(e),this.audienceMediaUnlockButton=e}hideAudienceMediaUnlockIfClear(){this.blockedAudienceMedia.size>0||!this.audienceMediaUnlockButton||(this.audienceMediaUnlockButton.remove(),this.audienceMediaUnlockButton=null)}onKey=e=>{if(!this.controller)return;let t=e.target;if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement||t instanceof HTMLElement&&t.isContentEditable)return;let i=document.activeElement,r=i===this||this.contains(i),s=document.querySelectorAll("hyperframes-slideshow").length>1,o=r||!s&&(i===document.body||i===null);if(e.key==="ArrowRight"){if(!o)return;this.controller.next(),e.preventDefault()}else if(e.key==="ArrowLeft"){if(!o)return;this.controller.prev(),e.preventDefault()}else if(e.key===" "){if(!r)return;this.controller.next(),e.preventDefault()}else if(e.key==="Backspace"){if(!r)return;this.controller.prev(),e.preventDefault()}else if((e.key==="f"||e.key==="F")&&!e.metaKey&&!e.ctrlKey&&!e.altKey){if(!r)return;this.toggleFullscreen(),e.preventDefault()}else if((e.key==="p"||e.key==="P")&&!e.metaKey&&!e.ctrlKey&&!e.altKey){if(!o||!this.shouldShowPresentControl())return;this.present(),e.preventDefault()}};onMessage=e=>{if(this.resolveMode()==="audience")return;let t=e.data;!t||!this.controller||(t.type==="next"?this.controller.next():t.type==="prev"?this.controller.prev():t.type==="goto"&&typeof t.slideIndex=="number"?this.controller.goToSlide?.(t.slideIndex):t.type==="back"&&this.controller.back?.())};onTouchStart=e=>{let t=e.touches[0];t&&(this.touchStartX=t.clientX,this.touchStartY=t.clientY)};onTouchEnd=e=>{if(!this.controller)return;let t=e.changedTouches[0];if(!t)return;let i=t.clientX-this.touchStartX,r=t.clientY-this.touchStartY;Math.abs(i)<=40||Math.abs(i)<=Math.abs(r)||(i<0?this.controller.next():this.controller.prev())};render(){if(!this.controller)return;if(this.resolveMode()==="audience"){let{counter:r}=this.controller;this.paintChrome(this.buildNavCluster(r,"28px","fs-only"));return}if(this.getAttribute("data-hf-presenting")==="true"){this.renderPresenter();return}let{counter:e,currentSlide:t}=this.controller;if(!t)return;let i=t.hotspots.map(r=>{let s=r.region?`left:${r.region.x}%;top:${r.region.y}%;`:"right:5%;bottom:18%;";return`<button
|
|
81
81
|
class="hf-hotspot-pill"
|
|
82
82
|
data-hotspot-id="${h(r.id)}"
|
|
83
83
|
data-hotspot-target="${h(r.target)}"
|
|
84
84
|
type="button"
|
|
85
85
|
style="position:absolute;${s}display:inline-flex;align-items:center;gap:6px;padding:8px 14px;background:var(--hf-slideshow-accent,rgba(255,255,255,0.92));color:#111;border:none;border-radius:999px;font-size:13px;font-weight:600;letter-spacing:0.01em;cursor:pointer;pointer-events:auto;box-shadow:0 4px 16px rgba(0,0,0,0.35);animation:hf-hotspot-pulse 1.8s ease-in-out infinite;white-space:nowrap;"
|
|
86
86
|
aria-label="${h(r.label)}"
|
|
87
|
-
><span aria-hidden="true" style="font-size:14px;line-height:1;">\u2295</span>${h(r.label)}</button>`}).join("");this.paintChrome(i+this.buildNavCluster(e,"28px"))}paintChrome(e){
|
|
87
|
+
><span aria-hidden="true" style="font-size:14px;line-height:1;">\u2295</span>${h(r.label)}</button>`}).join("");this.paintChrome(i+this.buildNavCluster(e,"28px"))}paintChrome(e){ye(),this.chrome||(this.chrome=document.createElement("div"),this.chrome.setAttribute("data-hf-chrome",""),this.appendChild(this.chrome)),this.chrome.style.cssText="position:absolute;inset:0;pointer-events:none;z-index:10;",this.chrome.innerHTML=e,this.wireChromeButtons()}buildNavCluster(e,t,i="full",r={}){let s=this.controller,o=r.canPrev??s?.canPrev??!0,d=r.canNext??s?.canNext??!0,a=r.loading===!0&&d,l=this.hasAttribute("sound"),u="display:flex;align-items:center;justify-content:center;width:34px;height:34px;background:transparent;border:none;border-radius:999px;color:rgba(255,255,255,0.85);font-size:16px;cursor:pointer;transition:background 0.15s,color 0.15s;padding:0;",b=l?`<button
|
|
88
88
|
data-hf-mute
|
|
89
89
|
type="button"
|
|
90
90
|
aria-label="${this._muted?"Unmute":"Mute"}"
|
|
@@ -92,19 +92,19 @@
|
|
|
92
92
|
data-hf-tooltip="${this._muted?"Unmute":"Mute"}"
|
|
93
93
|
aria-pressed="${this._muted?"true":"false"}"
|
|
94
94
|
style="${u}${this._muted?"color:rgba(255,255,255,0.45);":""}"
|
|
95
|
-
>${this._muted?'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/></svg>':'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/></svg>'}</button>`:"",
|
|
95
|
+
>${this._muted?'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/></svg>':'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/></svg>'}</button>`:"",_=o?`<button
|
|
96
96
|
data-hf-prev
|
|
97
97
|
type="button"
|
|
98
98
|
aria-label="Previous slide"
|
|
99
99
|
title="Previous slide"
|
|
100
100
|
data-hf-tooltip="Previous slide"
|
|
101
|
-
style="${u}" >‹</button>`:"",
|
|
101
|
+
style="${u}" >‹</button>`:"",O=a?`<span
|
|
102
102
|
data-hf-nav-loading
|
|
103
103
|
role="status"
|
|
104
104
|
aria-label="Loading slides"
|
|
105
105
|
title="Loading slides"
|
|
106
106
|
style="${u}cursor:progress;color:rgba(255,255,255,0.72);"
|
|
107
|
-
><span class="hf-nav-spinner" aria-hidden="true" style="width:14px;height:14px;border:2px solid rgba(255,255,255,0.32);border-top-color:rgba(255,255,255,0.92);border-radius:999px;animation:hf-nav-spin 0.8s linear infinite;"></span></span>`:"",
|
|
107
|
+
><span class="hf-nav-spinner" aria-hidden="true" style="width:14px;height:14px;border:2px solid rgba(255,255,255,0.32);border-top-color:rgba(255,255,255,0.92);border-radius:999px;animation:hf-nav-spin 0.8s linear infinite;"></span></span>`:"",B=a?O:d?`<button
|
|
108
108
|
data-hf-next
|
|
109
109
|
type="button"
|
|
110
110
|
aria-label="Next slide"
|
|
@@ -116,34 +116,34 @@
|
|
|
116
116
|
aria-label="Present"
|
|
117
117
|
title="Present"
|
|
118
118
|
data-hf-tooltip="Present"
|
|
119
|
-
style="${u}" >${
|
|
119
|
+
style="${u}" >${be}</button>`:"",M=document.fullscreenElement===this,x=M?"Exit full screen":"Full screen",T=`<button
|
|
120
120
|
data-hf-fullscreen
|
|
121
121
|
type="button"
|
|
122
|
-
aria-label="${
|
|
123
|
-
title="${
|
|
124
|
-
data-hf-tooltip="${
|
|
125
|
-
aria-pressed="${
|
|
126
|
-
style="${u}" >${
|
|
122
|
+
aria-label="${x}"
|
|
123
|
+
title="${x}"
|
|
124
|
+
data-hf-tooltip="${x}"
|
|
125
|
+
aria-pressed="${M?"true":"false"}"
|
|
126
|
+
style="${u}" >${M?H:N}</button>`;if(i==="fs-only")return`
|
|
127
127
|
<div
|
|
128
128
|
data-hf-nav-cluster
|
|
129
129
|
style="position:absolute;bottom:${t};right:32px;display:inline-flex;align-items:center;background:rgba(20,20,22,0.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,0.12);border-radius:999px;box-shadow:0 4px 24px rgba(0,0,0,0.45);padding:4px;pointer-events:auto;"
|
|
130
|
-
>${T}</div>`;let U=
|
|
130
|
+
>${T}</div>`;let U=o?"4px":"10px",K=d?"4px":"10px";return`
|
|
131
131
|
<div
|
|
132
132
|
data-hf-nav-cluster
|
|
133
133
|
style="position:absolute;bottom:${t};right:32px;display:inline-flex;align-items:center;gap:2px;background:rgba(20,20,22,0.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,0.12);border-radius:999px;box-shadow:0 4px 24px rgba(0,0,0,0.45);padding:4px;pointer-events:auto;"
|
|
134
134
|
>
|
|
135
|
-
${
|
|
135
|
+
${b}
|
|
136
136
|
${l?'<span aria-hidden="true" style="width:1px;height:20px;background:rgba(255,255,255,0.12);margin:0 2px;flex-shrink:0;"></span>':""}
|
|
137
|
-
${
|
|
137
|
+
${_}
|
|
138
138
|
<span
|
|
139
139
|
data-hf-counter
|
|
140
140
|
aria-label="Slide ${e.index} of ${e.total}"
|
|
141
|
-
style="min-width:46px;text-align:center;color:rgba(255,255,255,0.9);font-family:${
|
|
141
|
+
style="min-width:46px;text-align:center;color:rgba(255,255,255,0.9);font-family:${Me};font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:0;padding:0 ${K} 0 ${U};user-select:none;"
|
|
142
142
|
>${e.index} / ${e.total}</span>
|
|
143
|
-
${
|
|
143
|
+
${B}
|
|
144
144
|
<span aria-hidden="true" style="width:1px;height:20px;background:rgba(255,255,255,0.12);margin:0 2px;flex-shrink:0;"></span>
|
|
145
145
|
${D}
|
|
146
146
|
${T}
|
|
147
|
-
</div>`}wireChromeButtons(){let e=this.chrome;e&&(this.wireChromeClick(e,"[data-hf-mute]",()=>this.toggleMute()),this.wireChromeClick(e,"[data-hf-prev]",()=>this.controller?.prev()),this.wireChromeClick(e,"[data-hf-next]",()=>this.controller?.next()),this.wireChromeClick(e,"[data-hf-present]",()=>this.present()),this.wireChromeClick(e,"[data-hf-fullscreen]",()=>this.toggleFullscreen()),this.wirePresenterNotes(e),this.wireHotspots(e))}wireChromeClick(e,t,i){let r=e.querySelector(t);r&&r.addEventListener("click",i)}wirePresenterNotes(e){let t=e.querySelector("[data-hf-presenter-notes]");if(t instanceof HTMLTextAreaElement){let i=t.getAttribute("data-hf-presenter-notes-key");t.addEventListener("input",()=>this.writePresenterNotes(i,t.value))}}wireHotspots(e){for(let t of e.querySelectorAll("[data-hotspot-id]")){let i=t.getAttribute("data-hotspot-target")??"";t.addEventListener("click",()=>this.controller?.enterBranch?.(i))}}onFsChange=()=>{let e=this.chrome?.querySelector("[data-hf-fullscreen]");if(!e)return;let t=document.fullscreenElement===this;e.innerHTML=t?N
|
|
148
|
-
`)[0]??"":"";return e.length>0?`${h(n.sceneId)}: ${h(e)}`:h(n.sceneId)}function
|
|
147
|
+
</div>`}wireChromeButtons(){let e=this.chrome;e&&(this.wireChromeClick(e,"[data-hf-mute]",()=>this.toggleMute()),this.wireChromeClick(e,"[data-hf-prev]",()=>this.controller?.prev()),this.wireChromeClick(e,"[data-hf-next]",()=>this.controller?.next()),this.wireChromeClick(e,"[data-hf-present]",()=>this.present()),this.wireChromeClick(e,"[data-hf-fullscreen]",()=>this.toggleFullscreen()),this.wirePresenterNotes(e),this.wireHotspots(e))}wireChromeClick(e,t,i){let r=e.querySelector(t);r&&r.addEventListener("click",i)}wirePresenterNotes(e){let t=e.querySelector("[data-hf-presenter-notes]");if(t instanceof HTMLTextAreaElement){let i=t.getAttribute("data-hf-presenter-notes-key");t.addEventListener("input",()=>this.writePresenterNotes(i,t.value))}}wireHotspots(e){for(let t of e.querySelectorAll("[data-hotspot-id]")){let i=t.getAttribute("data-hotspot-target")??"";t.addEventListener("click",()=>this.controller?.enterBranch?.(i))}}onFsChange=()=>{let e=this.chrome?.querySelector("[data-hf-fullscreen]");if(!e)return;let t=document.fullscreenElement===this;e.innerHTML=t?H:N;let i=t?"Exit full screen":"Full screen";e.setAttribute("aria-label",i),e.setAttribute("title",i),e.setAttribute("data-hf-tooltip",i),e.setAttribute("aria-pressed",t?"true":"false")};toggleFullscreen(){document.fullscreenElement===this?document.exitFullscreen().catch(()=>{}):this.requestFullscreen().catch(()=>{})}shouldShowPresentControl(){return this.resolveMode()!=="audience"&&this.getAttribute("data-hf-presenting")!=="true"}toggleMute(){this._muted=!this._muted,this._muted?this.setAttribute("data-hf-muted",""):this.removeAttribute("data-hf-muted"),this.applyGlobalMute(this._muted),this.dispatchEvent(new CustomEvent("hf-sound",{detail:{muted:this._muted},bubbles:!0,composed:!0})),this.render()}applyGlobalMute(e){for(let i of this.querySelectorAll("hyperframes-player")){if(!(i instanceof HTMLElement))continue;let r=i;"muted"in r?r.muted=e:e?r.setAttribute("muted",""):r.removeAttribute("muted")}let t=this.ownerDocument;for(let i of t.querySelectorAll("video, audio"))i instanceof HTMLMediaElement&&(i.muted=e||i.defaultMuted)}stopDocumentMedia(){this.autoplayToken++;let e=this.ownerDocument;for(let t of e.querySelectorAll("video, audio"))t instanceof HTMLMediaElement&&t.pause()}playSceneDocumentMedia(e){if(this.resolveMode()==="audience")return;let t=e.replace(/["\\]/g,"\\$&"),i=++this.autoplayToken,r={started:!1,lastTime:-1,advancingTicks:0,waited:0,warned:!1},s=()=>{if(i!==this.autoplayToken)return;let o=this.stepAutoplay(t,r);r.waited+=L,!o&&r.waited<=me&&window.setTimeout(s,L)};s()}findSceneVideo(e){for(let t of this.mediaPlayerElements()){let r=this.playerFrameDocument(t)?.querySelector(`[data-composition-id="${e}"] video`)??null;if(r instanceof HTMLVideoElement)return r}return null}stepAutoplay(e,t){let i=this.findSceneVideo(e);if(!i)return!1;if(!t.started){t.started=!0,i.muted=this._muted||i.defaultMuted;try{i.currentTime=0}catch{}}let r=!i.paused&&i.currentTime>t.lastTime;return t.lastTime=i.currentTime,r?++t.advancingTicks>=2:(t.advancingTicks=0,i.play().catch(s=>{let o=s instanceof DOMException?s.name:"";o!=="AbortError"&&o!=="NotAllowedError"&&!t.warned&&(t.warned=!0,console.warn("[hyperframes-slideshow] autoplay play() failed:",s))}),!1)}presenterNotesDeckKey(){let e=this.getAttribute("notes-storage-key")?.trim();if(e)return e;let t=this.querySelector("hyperframes-player")?.getAttribute("src")??"",i=t;try{let o=typeof location<"u"?location.href:"http://localhost/";i=new URL(t,o).href}catch{}let r=typeof location<"u"?`${location.origin}${location.pathname}`:"",s=this.ownerDocument.title;return`${r}|${s}|${i}`}presenterNotesStorageKey(e){let t=this.controller?.position;return t?`${ge}${JSON.stringify([this.presenterNotesDeckKey(),t.sequenceId,t.slideIndex,e.sceneId??""])}`:null}readPresenterNotes(e){if(!e||typeof window>"u")return null;try{return window.localStorage.getItem(e)}catch{return null}}writePresenterNotes(e,t){if(e&&!(typeof window>"u"))try{window.localStorage.setItem(e,t)}catch{}}renderPresenter(){if(!this.controller)return;let{counter:e,currentSlide:t,nextSlide:i}=this.controller;if(!t)return;let r=this.presenterStartMs!==null?Math.floor((Date.now()-this.presenterStartMs)/1e3):0,s=this.querySelector("hyperframes-player");s instanceof HTMLElement&&(s.style.top="0",s.style.bottom="32%",s.style.height="auto");let o=this.presenterNotesStorageKey(t),d=this.readPresenterNotes(o)??t.notes??"";this.paintChrome(R({notes:d,notesStorageKey:o,nextText:xe(i),counterText:`${e.index} / ${e.total}`,elapsedText:w(r),hotspots:t.hotspots})+this.buildNavCluster(e,"calc(32% + 18px)"))}};function xe(n){if(n===null)return"End of sequence";let e=n.notes!=null?n.notes.split(`
|
|
148
|
+
`)[0]??"":"";return e.length>0?`${h(n.sceneId)}: ${h(e)}`:h(n.sceneId)}function Se(n){let e=n.ownerDocument.defaultView;return!e||typeof e.HTMLMediaElement!="function"?!1:n instanceof e.HTMLMediaElement}function v(n,e){return Number.isFinite(n)?n:e}function k(n){return"scenes"in n&&Array.isArray(n.scenes)?n.scenes:[]}var we=5e3;function ke(n){return n.ready===!0?Promise.resolve():new Promise(e=>{let t=null,i=()=>{t!==null&&(clearTimeout(t),t=null),e()};n.addEventListener("ready",i,{once:!0}),t=setTimeout(()=>{n.removeEventListener("ready",i),e()},we)})}function Te(n,e,t=()=>!1){let i=k(n);if(i.length>0)return Promise.resolve(i);let r=Math.ceil(e/100);return new Promise(s=>{let o=!1,d=null,a=0,l=c=>{o||(o=!0,d!==null&&clearTimeout(d),n.removeEventListener("scenes",u),s(c))},u=()=>{if(t())return l([]);let c=k(n);c.length>0&&l(c)},p=()=>{if(o)return;if(t())return l([]);let c=k(n);if(c.length>0)return l(c);if(a+=1,a>=r)return l([]);d=setTimeout(p,100)};n.addEventListener("scenes",u),d=setTimeout(p,100)})}function F(n){let e=r=>r.end>r.start,t=n.slides.filter(e),i={};for(let[r,s]of Object.entries(n.sequences))i[r]={...s,slides:s.slides.filter(e)};return{slides:t,sequences:i}}function h(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}customElements.get("hyperframes-slideshow")||customElements.define("hyperframes-slideshow",y);return W(Ee);})();
|
|
149
149
|
//# sourceMappingURL=hyperframes-slideshow.global.js.map
|