hyperframes 0.6.9 → 0.6.11

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/cli.js CHANGED
@@ -54,7 +54,7 @@ var VERSION;
54
54
  var init_version = __esm({
55
55
  "src/version.ts"() {
56
56
  "use strict";
57
- VERSION = true ? "0.6.9" : "0.0.0-dev";
57
+ VERSION = true ? "0.6.11" : "0.0.0-dev";
58
58
  }
59
59
  });
60
60
 
@@ -26298,35 +26298,80 @@ var init_htmlDocument = __esm({
26298
26298
  // ../core/src/studio-api/helpers/subComposition.ts
26299
26299
  import { existsSync as existsSync11, readFileSync as readFileSync11 } from "fs";
26300
26300
  import { join as join14 } from "path";
26301
- function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
26302
- const compFile = join14(projectDir, compPath);
26303
- if (!existsSync11(compFile)) return null;
26304
- const rawComp = readFileSync11(compFile, "utf-8");
26305
- const templateMatch = rawComp.match(/<template[^>]*>([\s\S]*)<\/template>/i);
26306
- const content = templateMatch?.[1] ?? rawComp;
26307
- const { document: contentDoc } = parseHTML(
26308
- `<!DOCTYPE html><html><head></head><body>${content}</body></html>`
26309
- );
26301
+ function isFullHtmlDocument(html) {
26302
+ return /^\s*(?:<!doctype\s|<html[\s>])/i.test(html);
26303
+ }
26304
+ function rewriteRelativePaths(root, compPath) {
26310
26305
  rewriteAssetPaths(
26311
- contentDoc.querySelectorAll("[src], [href]"),
26306
+ root.querySelectorAll("[src], [href]"),
26312
26307
  compPath,
26313
26308
  (el, attr) => el.getAttribute(attr),
26314
- (el, attr, value) => {
26315
- el.setAttribute(attr, value);
26316
- }
26309
+ (el, attr, value) => el.setAttribute(attr, value)
26317
26310
  );
26318
26311
  rewriteInlineStyleAssetUrls(
26319
- contentDoc.querySelectorAll("[style]"),
26312
+ root.querySelectorAll("[style]"),
26320
26313
  compPath,
26321
26314
  (el) => el.getAttribute("style"),
26322
- (el, value) => {
26323
- el.setAttribute("style", value);
26324
- }
26315
+ (el, value) => el.setAttribute("style", value)
26325
26316
  );
26326
- for (const styleEl of contentDoc.querySelectorAll("style")) {
26317
+ for (const styleEl of root.querySelectorAll("style")) {
26327
26318
  styleEl.textContent = rewriteCssAssetUrls(styleEl.textContent || "", compPath);
26328
26319
  }
26329
- const rewrittenContent = contentDoc.body.innerHTML || content;
26320
+ }
26321
+ function extractFullDocumentParts(rawHtml, compPath) {
26322
+ const { document: doc } = parseHTML(rawHtml);
26323
+ const rewriteTargets = [doc.head, doc.body].filter(Boolean);
26324
+ for (const target of rewriteTargets) {
26325
+ rewriteRelativePaths(target, compPath);
26326
+ }
26327
+ const headContent = doc.head?.innerHTML ?? "";
26328
+ const bodyContent = doc.body?.innerHTML ?? "";
26329
+ const htmlEl = doc.documentElement;
26330
+ const htmlAttrs = extractElementAttrs(htmlEl);
26331
+ const bodyAttrs = doc.body ? extractElementAttrs(doc.body) : "";
26332
+ return { headContent, bodyContent, htmlAttrs, bodyAttrs };
26333
+ }
26334
+ function extractElementAttrs(el) {
26335
+ const parts = [];
26336
+ for (let i2 = 0; i2 < el.attributes.length; i2++) {
26337
+ const attr = el.attributes[i2];
26338
+ if (attr.value === "") {
26339
+ parts.push(attr.name);
26340
+ } else {
26341
+ parts.push(`${attr.name}="${attr.value}"`);
26342
+ }
26343
+ }
26344
+ return parts.join(" ");
26345
+ }
26346
+ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
26347
+ const compFile = join14(projectDir, compPath);
26348
+ if (!existsSync11(compFile)) return null;
26349
+ const rawComp = readFileSync11(compFile, "utf-8");
26350
+ let compHeadContent = "";
26351
+ let rewrittenContent;
26352
+ let htmlAttrs = "";
26353
+ let bodyAttrs = "";
26354
+ const templateMatch = rawComp.match(/<template[^>]*>([\s\S]*)<\/template>/i);
26355
+ if (templateMatch) {
26356
+ const content = templateMatch[1];
26357
+ const { document: contentDoc } = parseHTML(
26358
+ `<!DOCTYPE html><html><head></head><body>${content}</body></html>`
26359
+ );
26360
+ rewriteRelativePaths(contentDoc, compPath);
26361
+ rewrittenContent = contentDoc.body.innerHTML || content;
26362
+ } else if (isFullHtmlDocument(rawComp)) {
26363
+ const parts = extractFullDocumentParts(rawComp, compPath);
26364
+ compHeadContent = parts.headContent;
26365
+ rewrittenContent = parts.bodyContent;
26366
+ htmlAttrs = parts.htmlAttrs;
26367
+ bodyAttrs = parts.bodyAttrs;
26368
+ } else {
26369
+ const { document: contentDoc } = parseHTML(
26370
+ `<!DOCTYPE html><html><head></head><body>${rawComp}</body></html>`
26371
+ );
26372
+ rewriteRelativePaths(contentDoc, compPath);
26373
+ rewrittenContent = contentDoc.body.innerHTML || rawComp;
26374
+ }
26330
26375
  const indexPath = join14(projectDir, "index.html");
26331
26376
  let headContent = "";
26332
26377
  if (existsSync11(indexPath)) {
@@ -26338,6 +26383,8 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
26338
26383
  headContent = `<base href="${baseHref}">
26339
26384
  ${headContent}`;
26340
26385
  }
26386
+ if (compHeadContent) headContent += `
26387
+ ${compHeadContent}`;
26341
26388
  if (!headContent.includes("hyperframe.runtime") && !headContent.includes("hyperframes-preview-runtime")) {
26342
26389
  headContent += `
26343
26390
  <script data-hyperframes-preview-runtime="1" src="${runtimeUrl}"></script>`;
@@ -26346,12 +26393,14 @@ ${headContent}`;
26346
26393
  headContent += `
26347
26394
  <script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>`;
26348
26395
  }
26396
+ const htmlOpen = htmlAttrs ? `<html ${htmlAttrs}>` : "<html>";
26397
+ const bodyOpen = bodyAttrs ? `<body ${bodyAttrs}>` : "<body>";
26349
26398
  return `<!DOCTYPE html>
26350
- <html>
26399
+ ${htmlOpen}
26351
26400
  <head>
26352
26401
  ${headContent}
26353
26402
  </head>
26354
- <body>
26403
+ ${bodyOpen}
26355
26404
  <script>window.__timelines=window.__timelines||{};</script>
26356
26405
  ${rewrittenContent}
26357
26406
  </body>
@@ -28580,7 +28629,7 @@ var init_config2 = __esm({
28580
28629
  largeRenderThreshold: 1e3,
28581
28630
  disableGpu: false,
28582
28631
  browserGpuMode: "software",
28583
- enableBrowserPool: false,
28632
+ enableBrowserPool: true,
28584
28633
  browserTimeout: 12e4,
28585
28634
  protocolTimeout: 3e5,
28586
28635
  forceScreenshot: false,
@@ -28733,12 +28782,52 @@ function resolveBrowserGpuMode(mode, options = {}) {
28733
28782
  function logResolvedBrowserGpuMode(resolved, reason) {
28734
28783
  console.error(`[hyperframes] browserGpuMode auto \u2192 ${resolved} (${reason})`);
28735
28784
  }
28785
+ function resolveRequestedCaptureMode(config) {
28786
+ const headlessShell = resolveHeadlessShellPath(config);
28787
+ const isLinux = process.platform === "linux";
28788
+ const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
28789
+ if (headlessShell && isLinux && !forceScreenshot) return "beginframe";
28790
+ return "screenshot";
28791
+ }
28736
28792
  async function acquireBrowser(chromeArgs, config) {
28737
28793
  const enablePool = config?.enableBrowserPool ?? DEFAULT_CONFIG2.enableBrowserPool;
28738
28794
  if (enablePool && pooledBrowser) {
28739
- pooledBrowserRefCount += 1;
28740
- return { browser: pooledBrowser, captureMode: pooledCaptureMode };
28795
+ if (!pooledBrowser.connected) {
28796
+ pooledBrowser = null;
28797
+ pooledBrowserRefCount = 0;
28798
+ _pooledBrowserLaunchPromise = null;
28799
+ } else {
28800
+ const requestedMode = resolveRequestedCaptureMode(config);
28801
+ if (pooledCaptureMode === requestedMode) {
28802
+ pooledBrowserRefCount += 1;
28803
+ return { browser: pooledBrowser, captureMode: pooledCaptureMode };
28804
+ }
28805
+ }
28806
+ }
28807
+ if (enablePool && _pooledBrowserLaunchPromise) {
28808
+ const result = await _pooledBrowserLaunchPromise;
28809
+ const requestedMode = resolveRequestedCaptureMode(config);
28810
+ if (result.captureMode === requestedMode) {
28811
+ pooledBrowserRefCount += 1;
28812
+ return result;
28813
+ }
28814
+ }
28815
+ const launchPromise = launchBrowser(chromeArgs, config);
28816
+ if (enablePool && !pooledBrowser && !_pooledBrowserLaunchPromise) {
28817
+ _pooledBrowserLaunchPromise = launchPromise;
28818
+ try {
28819
+ const result = await launchPromise;
28820
+ pooledBrowser = result.browser;
28821
+ pooledBrowserRefCount = 1;
28822
+ pooledCaptureMode = result.captureMode;
28823
+ return result;
28824
+ } finally {
28825
+ _pooledBrowserLaunchPromise = null;
28826
+ }
28741
28827
  }
28828
+ return launchPromise;
28829
+ }
28830
+ async function launchBrowser(chromeArgs, config) {
28742
28831
  const headlessShell = resolveHeadlessShellPath(config);
28743
28832
  const isLinux = process.platform === "linux";
28744
28833
  const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
@@ -28781,11 +28870,6 @@ async function acquireBrowser(chromeArgs, config) {
28781
28870
  });
28782
28871
  }
28783
28872
  }
28784
- if (enablePool) {
28785
- pooledBrowser = browser;
28786
- pooledBrowserRefCount = 1;
28787
- pooledCaptureMode = captureMode;
28788
- }
28789
28873
  return { browser, captureMode };
28790
28874
  }
28791
28875
  async function releaseBrowser(browser, config) {
@@ -28801,6 +28885,7 @@ async function releaseBrowser(browser, config) {
28801
28885
  await browser.close().catch(() => {
28802
28886
  });
28803
28887
  pooledBrowser = null;
28888
+ _pooledBrowserLaunchPromise = null;
28804
28889
  }
28805
28890
  return;
28806
28891
  }
@@ -28809,8 +28894,13 @@ async function releaseBrowser(browser, config) {
28809
28894
  }
28810
28895
  function forceReleaseBrowser(browser) {
28811
28896
  if (pooledBrowser && pooledBrowser === browser) {
28897
+ if (pooledBrowserRefCount > 1) {
28898
+ pooledBrowserRefCount -= 1;
28899
+ return;
28900
+ }
28812
28901
  pooledBrowserRefCount = 0;
28813
28902
  pooledBrowser = null;
28903
+ _pooledBrowserLaunchPromise = null;
28814
28904
  }
28815
28905
  const proc = browser.process?.();
28816
28906
  if (proc && !proc.killed) {
@@ -28824,6 +28914,21 @@ function forceReleaseBrowser(browser) {
28824
28914
  } catch {
28825
28915
  }
28826
28916
  }
28917
+ async function drainBrowserPool() {
28918
+ const pending = _pooledBrowserLaunchPromise;
28919
+ _pooledBrowserLaunchPromise = null;
28920
+ if (pending) {
28921
+ await pending.then((r2) => r2.browser.close()).catch(() => {
28922
+ });
28923
+ }
28924
+ if (pooledBrowser) {
28925
+ const browser = pooledBrowser;
28926
+ pooledBrowser = null;
28927
+ pooledBrowserRefCount = 0;
28928
+ await browser.close().catch(() => {
28929
+ });
28930
+ }
28931
+ }
28827
28932
  function buildChromeArgs(options, config) {
28828
28933
  const platform7 = options.platform ?? process.platform;
28829
28934
  const gpuDisabled = config?.disableGpu ?? DEFAULT_CONFIG2.disableGpu;
@@ -28901,7 +29006,7 @@ function getBrowserGpuArgs(mode, platform7) {
28901
29006
  return ["--enable-gpu-rasterization"];
28902
29007
  }
28903
29008
  }
28904
- var _puppeteer, pooledBrowser, pooledBrowserRefCount, pooledCaptureMode, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, _autoBrowserGpuModeCache, CANVAS_DRAW_ELEMENT_FEATURE_FLAG;
29009
+ var _puppeteer, pooledBrowser, pooledBrowserRefCount, pooledCaptureMode, _pooledBrowserLaunchPromise, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, _autoBrowserGpuModeCache, CANVAS_DRAW_ELEMENT_FEATURE_FLAG;
28905
29010
  var init_browserManager = __esm({
28906
29011
  "../engine/src/services/browserManager.ts"() {
28907
29012
  "use strict";
@@ -28909,6 +29014,7 @@ var init_browserManager = __esm({
28909
29014
  pooledBrowser = null;
28910
29015
  pooledBrowserRefCount = 0;
28911
29016
  pooledCaptureMode = "screenshot";
29017
+ _pooledBrowserLaunchPromise = null;
28912
29018
  ENABLE_BROWSER_POOL = DEFAULT_CONFIG2.enableBrowserPool;
28913
29019
  BEGINFRAME_ONLY_FLAGS = /* @__PURE__ */ new Set([
28914
29020
  "--deterministic-mode",
@@ -35364,6 +35470,7 @@ __export(src_exports2, {
35364
35470
  discardWarmupCapture: () => discardWarmupCapture,
35365
35471
  distributeFrames: () => distributeFrames,
35366
35472
  downloadToTemp: () => downloadToTemp,
35473
+ drainBrowserPool: () => drainBrowserPool,
35367
35474
  encodeFramesChunkedConcat: () => encodeFramesChunkedConcat,
35368
35475
  encodeFramesFromDir: () => encodeFramesFromDir,
35369
35476
  executeParallelCapture: () => executeParallelCapture,
@@ -42267,8 +42374,11 @@ function startServer(options = {}) {
42267
42374
  server.setTimeout(0);
42268
42375
  server.requestTimeout = 0;
42269
42376
  server.keepAliveTimeout = 0;
42270
- function shutdown(signal) {
42377
+ async function shutdown(signal) {
42271
42378
  log2.info(`Received ${signal}, shutting down`);
42379
+ const { drainBrowserPool: drainBrowserPool2 } = await Promise.resolve().then(() => (init_src2(), src_exports2));
42380
+ await drainBrowserPool2().catch(() => {
42381
+ });
42272
42382
  server.close(() => {
42273
42383
  log2.info("Server closed");
42274
42384
  process.exit(0);
@@ -44008,14 +44118,22 @@ async function getThumbnailBrowser() {
44008
44118
  }
44009
44119
  } catch {
44010
44120
  }
44011
- const acquired = await acquireBrowser2(buildChromeArgs2({ width: 1920, height: 1080 }), {
44012
- enableBrowserPool: false
44013
- });
44121
+ const acquired = await acquireBrowser2(buildChromeArgs2({ width: 1920, height: 1080 }));
44014
44122
  _thumbnailBrowser = acquired.browser;
44015
44123
  _thumbnailBrowser.on("disconnected", () => {
44016
44124
  _thumbnailBrowser = null;
44017
44125
  _thumbnailBrowserInitializing = null;
44018
44126
  });
44127
+ const onExit = async () => {
44128
+ const { releaseBrowser: releaseBrowser2 } = await Promise.resolve().then(() => (init_src2(), src_exports2));
44129
+ if (_thumbnailBrowser) {
44130
+ await releaseBrowser2(_thumbnailBrowser).catch(() => {
44131
+ });
44132
+ _thumbnailBrowser = null;
44133
+ }
44134
+ };
44135
+ process.once("SIGTERM", () => void onExit());
44136
+ process.once("SIGINT", () => void onExit());
44019
44137
  return _thumbnailBrowser;
44020
44138
  } catch {
44021
44139
  _thumbnailBrowserInitializing = null;
@@ -415,4 +415,4 @@ var ae=Object.defineProperty;var de=(n,e,t)=>e in n?ae(n,e,{enumerable:!0,config
415
415
  background: var(--hfp-accent, #fff);
416
416
  pointer-events: none;
417
417
  }
418
- `,K='<svg width="24" height="24" viewBox="0 0 18 18" fill="currentColor"><polygon points="4,2 16,9 4,16"/></svg>',fe='<svg width="24" height="24" viewBox="0 0 18 18" fill="currentColor"><rect x="3" y="2" width="4" height="14"/><rect x="11" y="2" width="4" height="14"/></svg>',ee='<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3z"/><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/><path d="M14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>',te='<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3z"/><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>',ge='<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3z"/><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z" opacity="0.3"/><line x1="18" y1="7" x2="14" y2="17" stroke="currentColor" stroke-width="2"/></svg>',_e=[.25,.5,1,1.5,2,4];function N(n){return Number.isInteger(n)?`${n}x`:`${n}x`}function ie(n){if(!Number.isFinite(n)||n<0)return"0:00";const e=Math.floor(n),t=Math.floor(e/60),i=e%60;return`${t}:${i.toString().padStart(2,"0")}`}function be(n,e,t={}){const i=t.speedPresets??_e,r=document.createElement("div");r.className="hfp-controls",r.addEventListener("click",o=>{o.stopPropagation()});const s=document.createElement("button");s.className="hfp-play-btn",s.type="button",s.innerHTML=K,s.setAttribute("aria-label","Play");const a=document.createElement("div");a.className="hfp-scrubber";const d=document.createElement("div");d.className="hfp-progress",d.style.width="0%",a.appendChild(d);const c=document.createElement("span");c.className="hfp-time",c.textContent="0:00 / 0:00";const m=document.createElement("div");m.className="hfp-speed-wrap";const p=document.createElement("button");p.className="hfp-speed-btn",p.type="button",p.textContent="1x",p.setAttribute("aria-label","Playback speed");const h=document.createElement("div");h.className="hfp-speed-menu",h.setAttribute("role","menu");for(const o of i){const l=document.createElement("button");l.className="hfp-speed-option",l.type="button",l.setAttribute("role","menuitem"),l.dataset.speed=String(o),l.textContent=N(o),o===1&&l.classList.add("hfp-active"),h.appendChild(l)}m.appendChild(h),m.appendChild(p);const _=document.createElement("div");_.className="hfp-volume-wrap";const f=document.createElement("button");f.className="hfp-mute-btn",f.type="button",f.innerHTML=ee,f.setAttribute("aria-label","Mute");const b=document.createElement("div");b.className="hfp-volume-slider-wrap";const g=document.createElement("div");g.className="hfp-volume-slider",g.setAttribute("role","slider"),g.setAttribute("aria-label","Volume"),g.setAttribute("aria-valuemin","0"),g.setAttribute("aria-valuemax","100"),g.setAttribute("aria-valuenow","100"),g.tabIndex=0;const y=document.createElement("div");y.className="hfp-volume-fill",y.style.width="100%",g.appendChild(y),b.appendChild(g),_.appendChild(b),_.appendChild(f),r.appendChild(s),r.appendChild(a),r.appendChild(c),r.appendChild(_),r.appendChild(m),n.appendChild(r);let M=!1,E=!1,w=1,x=null;i.indexOf(1);const L=(o,l)=>o?ge:l===0||l<.5?te:ee;s.addEventListener("click",o=>{o.stopPropagation(),M?e.onPause():e.onPlay()}),f.addEventListener("click",o=>{o.stopPropagation(),e.onMuteToggle()});let T=!1;const P=o=>{const l=g.getBoundingClientRect(),v=Math.max(0,Math.min(1,(o-l.left)/l.width));w=v,y.style.width=`${v*100}%`,g.setAttribute("aria-valuenow",String(Math.round(v*100))),E&&v>0&&e.onMuteToggle(),f.innerHTML=L(E,v),e.onVolumeChange(v)};g.addEventListener("mousedown",o=>{o.stopPropagation(),T=!0,P(o.clientX)});const H=o=>{T&&P(o.clientX)},$=()=>{T=!1};document.addEventListener("mousemove",H),document.addEventListener("mouseup",$),g.addEventListener("touchstart",o=>{T=!0;const l=o.touches[0];l&&P(l.clientX)},{passive:!0});const z=o=>{if(T){const l=o.touches[0];l&&P(l.clientX)}},j=()=>{T=!1};document.addEventListener("touchmove",z,{passive:!0}),document.addEventListener("touchend",j);const q=.05;g.addEventListener("keydown",o=>{let l=w;if(o.key==="ArrowRight"||o.key==="ArrowUp")l=Math.min(1,w+q);else if(o.key==="ArrowLeft"||o.key==="ArrowDown")l=Math.max(0,w-q);else return;o.preventDefault(),o.stopPropagation(),w=l,y.style.width=`${l*100}%`,g.setAttribute("aria-valuenow",String(Math.round(l*100))),E&&l>0&&e.onMuteToggle(),f.innerHTML=L(E,l),e.onVolumeChange(l)});const B=o=>{for(const l of h.querySelectorAll(".hfp-speed-option"))l.classList.toggle("hfp-active",l.dataset.speed===String(o))};p.addEventListener("click",o=>{o.stopPropagation();const l=h.classList.toggle("hfp-open");p.setAttribute("aria-expanded",String(l))}),h.addEventListener("click",o=>{o.stopPropagation();const l=o.target.closest(".hfp-speed-option");if(!l)return;const v=parseFloat(l.dataset.speed);i.indexOf(v),p.textContent=N(v),B(v),h.classList.remove("hfp-open"),p.setAttribute("aria-expanded","false"),e.onSpeedChange(v)});const W=()=>{h.classList.remove("hfp-open"),p.setAttribute("aria-expanded","false")};document.addEventListener("click",W);const R=o=>{const l=a.getBoundingClientRect(),v=Math.max(0,Math.min(1,(o-l.left)/l.width));e.onSeek(v)};let A=!1;a.addEventListener("mousedown",o=>{o.stopPropagation(),A=!0,R(o.clientX)});const X=o=>{A&&R(o.clientX)},G=()=>{A=!1};document.addEventListener("mousemove",X),document.addEventListener("mouseup",G),a.addEventListener("touchstart",o=>{A=!0;const l=o.touches[0];l&&R(l.clientX)},{passive:!0});const Y=o=>{if(A){const l=o.touches[0];l&&R(l.clientX)}},Q=()=>{A=!1};document.addEventListener("touchmove",Y,{passive:!0}),document.addEventListener("touchend",Q);const J=()=>{x&&clearTimeout(x),x=setTimeout(()=>{M&&r.classList.add("hfp-hidden")},3e3)},Z=n instanceof ShadowRoot?n.host:n;return Z.addEventListener("mousemove",()=>{r.classList.remove("hfp-hidden"),J()}),Z.addEventListener("mouseleave",()=>{M&&r.classList.add("hfp-hidden")}),{updateTime(o,l){const v=l>0?Math.min(o,l):o,oe=l>0?v/l*100:0;d.style.width=`${oe}%`,c.textContent=`${ie(v)} / ${ie(l)}`},updatePlaying(o){M=o,s.innerHTML=o?fe:K,s.setAttribute("aria-label",o?"Pause":"Play"),o?J():r.classList.remove("hfp-hidden")},updateSpeed(o){i.indexOf(o),p.textContent=N(o),B(o)},updateMuted(o){E=o,f.innerHTML=L(o,w),f.setAttribute("aria-label",o?"Unmute":"Mute")},updateVolume(o){w=o,y.style.width=`${o*100}%`,g.setAttribute("aria-valuenow",String(Math.round(o*100))),f.innerHTML=L(E,o)},show(){r.style.display=""},hide(){r.style.display="none"},destroy(){document.removeEventListener("mousemove",X),document.removeEventListener("mouseup",G),document.removeEventListener("touchmove",Y),document.removeEventListener("touchend",Q),document.removeEventListener("mousemove",H),document.removeEventListener("mouseup",$),document.removeEventListener("touchmove",z),document.removeEventListener("touchend",j),document.removeEventListener("click",W),x&&clearTimeout(x)}}}function ve(n,e,t,i,r){const s=i?i.split(",").map(Number).filter(c=>!isNaN(c)&&c>0):void 0,d=be(n,r,s?{speedPresets:s}:{});return d.updateMuted(e),d.updateVolume(t),d}function re(n,e,t){return e?(t||(t=document.createElement("img"),t.className="hfp-poster",n.appendChild(t)),t.src=e,t):(t==null||t.remove(),null)}function ye(n){return n.composedPath().some(e=>e instanceof HTMLElement&&e.classList.contains("hfp-controls"))}let I=null;function we(n,e){if(typeof CSSStyleSheet<"u")try{I||(I=new CSSStyleSheet,I.replaceSync(e)),n.adoptedStyleSheets=[I];return}catch{}const t=document.createElement("style");t.textContent=e,n.appendChild(t)}function Ee(){const n=document.createElement("div");n.className="hfp-container";const e=document.createElement("iframe");return e.className="hfp-iframe",e.sandbox.add("allow-scripts","allow-same-origin"),e.allow="autoplay; fullscreen",e.referrerPolicy="no-referrer",e.title="HyperFrames Composition",n.appendChild(e),{container:n,iframe:e}}function Te(n,e,t,i){const r=n.getBoundingClientRect();if(r.width===0||r.height===0)return;const s=Math.min(r.width/t,r.height/i);e.style.width=`${t}px`,e.style.height=`${i}px`,e.style.transform=`translate(-50%, -50%) scale(${s})`}const Ae=100;class Ce{constructor(e){u(this,"_raf",null);u(this,"_lastUpdateMs",0);this._callbacks=e}start(e,t,i,r){this.stop();const s=()=>{if(r()){this._raf=null;return}let a;try{a=e.time()}catch{this._raf=null;return}const d=i();d>0&&(a=Math.min(a,d));const c=d>0&&a>=d,m=performance.now();if((m-this._lastUpdateMs>Ae||c)&&(this._lastUpdateMs=m,this._callbacks.onTimeUpdate(a,d)),c){if(this._callbacks.getLoop()){this._callbacks.restart();return}try{e.pause()}catch{}this._callbacks.onPaused(),this._raf=null;return}this._raf=requestAnimationFrame(s)};this._raf=requestAnimationFrame(s)}stop(){this._raf!==null&&(cancelAnimationFrame(this._raf),this._raf=null)}get isRunning(){return this._raf!==null}}function xe(n){const e=Array.from(n.querySelectorAll("[data-composition-id]"));if(e.length===0)return n.body?[n.body]:[];const t=[];for(const i of e)Se(i)||t.push(i);return ke(n),t}function ke(n){const e=n.body;if(!e||typeof console>"u"||typeof console.warn!="function")return;const t=e.querySelectorAll("audio[data-start], video[data-start]");if(t.length===0)return;const i=[];for(const r of t)r.closest("[data-composition-id]")||i.push(r);i.length!==0&&console.warn(`[hyperframes-player] selectMediaObserverTargets: composition hosts are present, but ${i.length} body-level timed media element(s) sit outside every [data-composition-id] subtree and will not be observed. Move them inside a composition host or the parent-frame proxy will never adopt them.`,i)}function Se(n){let e=n.parentElement;for(;e;){if(e.hasAttribute("data-composition-id"))return!0;e=e.parentElement}return!1}const Me=.05,Le=2;class Pe{constructor(e){u(this,"_entries",[]);u(this,"_mediaObserver");u(this,"_playbackErrorPosted",!1);u(this,"_audioOwner","runtime");u(this,"_dispatchEvent");u(this,"_getMuted");u(this,"_getVolume");u(this,"_getPlaybackRate");u(this,"_getCurrentTime");u(this,"_isPaused");this._dispatchEvent=e.dispatchEvent,this._getMuted=e.getMuted,this._getVolume=e.getVolume,this._getPlaybackRate=e.getPlaybackRate,this._getCurrentTime=e.getCurrentTime,this._isPaused=e.isPaused}get audioOwner(){return this._audioOwner}get entries(){return this._entries}get playbackErrorPosted(){return this._playbackErrorPosted}resetForIframeLoad(){this._playbackErrorPosted=!1;const e=this._audioOwner==="parent";this._audioOwner="runtime",this.pauseAll(),this.teardownObserver(),e&&this._dispatchEvent(new CustomEvent("audioownershipchange",{detail:{owner:"runtime",reason:"iframe-reload"}}))}destroy(){this.teardownObserver();for(const e of this._entries)e.el.pause(),e.el.src="";this._entries=[]}updateMuted(e){for(const t of this._entries)t.el.muted=e}updateVolume(e){for(const t of this._entries)t.el.volume=e}updatePlaybackRate(e){for(const t of this._entries)t.el.playbackRate=e}playAll(){for(const e of this._entries)e.el.src&&e.el.play().catch(t=>this._reportPlaybackError(t))}pauseAll(){for(const e of this._entries)e.el.pause()}seekAll(e){for(const t of this._entries){const i=e-t.start;i>=0&&i<t.duration&&(t.el.currentTime=i)}}mirrorTime(e,t){const i=(t==null?void 0:t.force)===!0;for(const r of this._entries){const s=e-r.start;if(s<0||s>=r.duration){r.driftSamples=0;continue}Math.abs(r.el.currentTime-s)>Me?(r.driftSamples+=1,(i||r.driftSamples>=Le)&&(r.el.currentTime=s,r.driftSamples=0)):r.driftSamples=0}}promoteToParentProxy(e,t){if(this._audioOwner==="parent")return;if(this._audioOwner="parent",e)for(const r of e.querySelectorAll("video, audio"))r.muted=!0;const i=this._getCurrentTime();t?t(i,{force:!0}):this.mirrorTime(i,{force:!0}),this._isPaused()||this.playAll(),this._dispatchEvent(new CustomEvent("audioownershipchange",{detail:{owner:"parent",reason:"autoplay-blocked"}}))}setupFromIframe(e){const t=e.querySelectorAll("audio[data-start], video[data-start]");for(const i of t)this._adoptIframeMedia(i);this._observeDynamicMedia(e)}setupFromUrl(e){this._createEntry(e,"audio",0,1/0)}teardownObserver(){var e;(e=this._mediaObserver)==null||e.disconnect(),this._mediaObserver=void 0}_reportPlaybackError(e){this._playbackErrorPosted||(this._playbackErrorPosted=!0,this._dispatchEvent(new CustomEvent("playbackerror",{detail:{source:"parent-proxy",error:e}})))}_createEntry(e,t,i,r){if(this._entries.some(c=>c.el.src===e))return null;const s=t==="video"?document.createElement("video"):new Audio;s.preload="auto",s.src=e,s.load(),s.muted=this._getMuted(),s.volume=this._getVolume();const a=this._getPlaybackRate();a!==1&&(s.playbackRate=a);const d={el:s,start:i,duration:r,driftSamples:0};return this._entries.push(d),d}_adoptIframeMedia(e){var c;if(e.preload==="metadata"||e.preload==="none")return;const t=e.getAttribute("src")||((c=e.querySelector("source"))==null?void 0:c.getAttribute("src"));if(!t)return;const i=new URL(t,e.ownerDocument.baseURI).href,r=parseFloat(e.getAttribute("data-start")||"0"),s=parseFloat(e.getAttribute("data-duration")||"Infinity"),a=e.tagName==="VIDEO"?"video":"audio",d=this._createEntry(i,a,r,s);d&&this._audioOwner==="parent"&&(this.mirrorTime(this._getCurrentTime(),{force:!0}),!this._isPaused()&&d.el.src&&d.el.play().catch(m=>this._reportPlaybackError(m)))}_detachIframeMedia(e){var a;const t=e.getAttribute("src")||((a=e.querySelector("source"))==null?void 0:a.getAttribute("src"));if(!t)return;const i=new URL(t,e.ownerDocument.baseURI).href,r=this._entries.findIndex(d=>d.el.src===i);if(r===-1)return;const s=this._entries[r];s.el.pause(),s.el.src="",this._entries.splice(r,1)}_observeDynamicMedia(e){if(this.teardownObserver(),typeof MutationObserver>"u"||!e.body)return;const t=new MutationObserver(s=>{var a,d,c,m;for(const p of s){if(p.type==="attributes"&&p.attributeName==="preload"){const h=p.target;h instanceof HTMLMediaElement&&h.matches("audio[data-start], video[data-start]")&&h.preload==="auto"&&this._adoptIframeMedia(h);continue}for(const h of p.addedNodes){if(!(h instanceof Element))continue;const _=[];(a=h.matches)!=null&&a.call(h,"audio[data-start], video[data-start]")&&_.push(h);const f=(d=h.querySelectorAll)==null?void 0:d.call(h,"audio[data-start], video[data-start]");if(f)for(const b of f)_.push(b);for(const b of _)this._adoptIframeMedia(b)}for(const h of p.removedNodes){if(!(h instanceof Element))continue;const _=[];(c=h.matches)!=null&&c.call(h,"audio[data-start], video[data-start]")&&_.push(h);const f=(m=h.querySelectorAll)==null?void 0:m.call(h,"audio[data-start], video[data-start]");if(f)for(const b of f)_.push(b);for(const b of _)this._detachIframeMedia(b)}}}),i={childList:!0,subtree:!0,attributes:!0,attributeFilter:["preload"]},r=xe(e);for(const s of r)t.observe(s,i);this._mediaObserver=t}}const Re=100;function Ie(n,e,t,i){const r=(n.frame??0)/e,s=t.duration>0?Math.min(r,t.duration):r,a=!t.paused,d=!n.isPlaying,c=t.duration>0&&s>=t.duration&&(a||n.isPlaying);if(c&&i.getLoop())return i.media.audioOwner==="parent"&&i.media.pauseAll(),i.seek(0),i.play(),{...t,currentTime:s,paused:!1};const m={...t,currentTime:s,paused:d};i.media.audioOwner==="parent"&&(a&&d?i.media.pauseAll():!a&&!d&&i.media.playAll(),i.media.mirrorTime(s));const p=performance.now(),h=d!==t.paused;return(p-t.lastUpdateMs>Re||h)&&(m.lastUpdateMs=p,i.updateControlsTime(s,t.duration),i.updateControlsPlaying(!d),i.dispatchEvent(new CustomEvent("timeupdate",{detail:{currentTime:s}}))),c&&(i.media.audioOwner==="parent"&&i.media.pauseAll(),m.paused=!0,i.updateControlsPlaying(!1),i.dispatchEvent(new Event("ended"))),m}const ne=30;function Oe(n,e,t){if(n.source!==e)return;const i=n.data;if(!(!i||i.source!=="hf-preview")){if(i.type==="shader-transition-state"){const r=i.state&&typeof i.state=="object"?i.state:{};t.shaderLoader.update(r,t.getShaderLoadingMode()),t.dispatchEvent(new CustomEvent("shadertransitionstate",{detail:{compositionId:i.compositionId,state:r}}));return}if(i.type==="state"){t.setPlaybackState(Ie({frame:i.frame??0,isPlaying:!!i.isPlaying},ne,t.getPlaybackState(),t));return}if(i.type==="media-autoplay-blocked"){let r=null;try{r=t.getIframeDoc()}catch{}t.media.promoteToParentProxy(r,(s,a)=>t.media.mirrorTime(s,a)),t.sendControl("set-media-output-muted",{muted:!0});return}if(i.type==="timeline"&&i.durationInFrames>0){if(Number.isFinite(i.durationInFrames)){const r=t.getPlaybackState(),s=i.durationInFrames/ne;t.setPlaybackState({...r,duration:s}),t.updateControlsTime(r.currentTime,s)}return}i.type==="stage-size"&&i.width>0&&i.height>0&&t.setCompositionSize(i.width,i.height)}}const C="shader-capture-scale",k="shader-loading",De="__hf_shader_capture_scale",Ne="__hf_shader_loading",O=["Preparing scene transitions","Sampling outgoing scene motion","Sampling incoming scene motion","Caching transition frames","Finalizing transition preview"];function V(n){if(n===null)return null;const e=Number(n);return!Number.isFinite(e)||e<=0?null:String(Math.min(1,Math.max(.25,e)))}function Fe(n){if(n===null||n.trim()==="")return"composition";const e=n.trim().toLowerCase();return e==="none"||e==="false"||e==="0"||e==="off"?"none":e==="player"||e==="true"||e==="1"||e==="on"?"player":"composition"}function se(n,e,t){t===null?n.delete(e):n.set(e,t)}function Ue(n,e,t){const i=n.indexOf("#"),r=i>=0?n.slice(0,i):n,s=i>=0?n.slice(i):"",a=r.indexOf("?"),d=a>=0?r.slice(0,a):r,c=a>=0?r.slice(a+1):"",m=new URLSearchParams(c);se(m,De,e),se(m,Ne,t==="composition"?null:t);const p=m.toString();return`${d}${p?`?${p}`:""}${s}`}function Ve(n,e,t){if(e===null&&t==="composition")return n;const i=[];e!==null&&i.push(`window.__HF_SHADER_CAPTURE_SCALE=${JSON.stringify(e)};`),t!=="composition"&&i.push(`window.__HF_SHADER_LOADING=${JSON.stringify(t)};`);const r=`<script data-hyperframes-player-shader-options>${i.join("")}<\/script>`;return/<head\b[^>]*>/i.test(n)?n.replace(/<head\b[^>]*>/i,s=>`${s}${r}`):/<html\b[^>]*>/i.test(n)?n.replace(/<html\b[^>]*>/i,s=>`${s}${r}`):`${r}${n}`}function S(n){return Fe(n.getAttribute(k))}function He(n){return Number(V(n.getAttribute(C))??"1")}function F(n,e){return Ue(e,V(n.getAttribute(C)),S(n))}function U(n,e){return Ve(e,V(n.getAttribute(C)),S(n))}function $e(){const n=document.createElement("div");n.className="hfp-shader-loader",n.setAttribute("role","status"),n.setAttribute("aria-live","polite"),n.setAttribute("aria-label","Preparing scene transitions"),n.setAttribute("data-hyperframes-ignore",""),n.draggable=!1;const e=f=>{f.preventDefault(),f.stopPropagation()};for(const f of["selectstart","dragstart","pointerdown","mousedown","click","dblclick","contextmenu","touchstart"])n.addEventListener(f,e,{capture:!0});const t=document.createElement("div");t.className="hfp-shader-loader-panel",t.draggable=!1;const i=document.createElement("div");i.className="hfp-shader-loader-mark",i.draggable=!1,i.innerHTML=['<svg width="78" height="78" viewBox="0 0 100 100" fill="none" aria-hidden="true" draggable="false">','<path d="M10.1851 57.8021L33.1145 73.8313C36.2202 75.9978 41.5173 73.5433 42.4816 69.4984L51.7611 30.4271C52.7253 26.3822 48.5802 23.9277 44.4602 26.0942L13.917 42.1235C6.96677 45.7676 4.97564 54.1579 10.1851 57.8021Z" fill="url(#hfp-shader-loader-grad-left)"/>','<path d="M87.5129 57.5141L56.9696 73.5433C52.8371 75.7098 48.7046 73.2553 49.6688 69.2104L58.9483 30.1391C59.9125 26.0942 65.2097 23.6397 68.3154 25.8062L91.2447 41.8354C96.4668 45.4796 94.4631 53.8699 87.5129 57.5141Z" fill="url(#hfp-shader-loader-grad-right)"/>',"<defs>",'<linearGradient id="hfp-shader-loader-grad-left" x1="48.5676" y1="25" x2="44.7804" y2="71.9384" gradientUnits="userSpaceOnUse">','<stop stop-color="#06E3FA"/>','<stop offset="1" stop-color="#4FDB5E"/>',"</linearGradient>",'<linearGradient id="hfp-shader-loader-grad-right" x1="54.8282" y1="73.8392" x2="72.0989" y2="32.8932" gradientUnits="userSpaceOnUse">','<stop stop-color="#06E3FA"/>','<stop offset="1" stop-color="#4FDB5E"/>',"</linearGradient>","</defs>","</svg>"].join("");const r=document.createElement("div");r.className="hfp-shader-loader-title";const s=document.createElement("span");s.className="hfp-shader-loader-title-text",s.textContent=O[0],r.appendChild(s);const a=document.createElement("div");a.className="hfp-shader-loader-detail",a.textContent="Rendering animated scene samples for shader transitions.";const d=document.createElement("div");d.className="hfp-shader-loader-track",d.setAttribute("aria-hidden","true");const c=document.createElement("div");c.className="hfp-shader-loader-fill",d.appendChild(c);const m=document.createElement("div");m.className="hfp-shader-loader-progress";const p=f=>{const b=document.createElement("div");b.className="hfp-shader-loader-row";const g=document.createElement("span");g.className="hfp-shader-loader-label",g.textContent=f;const y=document.createElement("span");return y.className="hfp-shader-loader-value",b.appendChild(g),b.appendChild(y),m.appendChild(b),{row:b,label:g,value:y}},h=p("transition"),_=p("transition frame");return t.appendChild(i),t.appendChild(r),t.appendChild(a),t.appendChild(d),t.appendChild(m),n.appendChild(t),{root:n,fill:c,title:s,detail:a,transitionValue:h.value,frameLabel:_.label,frameValue:_.value,frameRow:_.row}}const ze=420;class je{constructor(e){u(this,"_el");u(this,"_hideTimeout",null);this._el=e}show(){this._hideTimeout&&(clearTimeout(this._hideTimeout),this._hideTimeout=null),this._el.root.classList.remove("hfp-hiding"),this._el.root.classList.add("hfp-visible")}hide(){if(this._el.root.classList.contains("hfp-hiding")){this._hideTimeout||this._scheduleCleanup();return}this._el.root.classList.contains("hfp-visible")&&(this._el.root.classList.add("hfp-hiding"),this._el.root.classList.remove("hfp-visible"),this._scheduleCleanup())}reset(){this._hideTimeout&&(clearTimeout(this._hideTimeout),this._hideTimeout=null),this._el.root.classList.remove("hfp-visible","hfp-hiding"),this._el.fill.style.transform="scaleX(0)",this._el.transitionValue.textContent="",this._el.frameValue.textContent="",this._el.frameRow.style.visibility="hidden"}update(e,t){if(t!=="player"){this.reset();return}if(e.ready||!e.loading){this.hide();return}const i=typeof e.progress=="number"&&Number.isFinite(e.progress)?e.progress:0,r=typeof e.total=="number"&&Number.isFinite(e.total)?e.total:0,s=r>0?Math.min(1,Math.max(0,i/r)):0,a=Math.min(O.length-1,Math.floor(s*O.length));this._el.title.textContent=O[a]||"Preparing scene transitions",this._el.detail.textContent=e.phase==="cached"?"Loading cached transition frames before playback.":e.phase==="finalizing"?"Uploading transition textures for smooth playback.":"Rendering animated scene samples for shader transitions.",this._el.fill.style.transform=`scaleX(${s})`,this._el.transitionValue.textContent=e.currentTransition!==void 0&&e.transitionTotal!==void 0?`${e.currentTransition}/${e.transitionTotal}`:r>0?`${i}/${r}`:"";const d=e.transitionFrame!==void 0&&e.transitionFrames!==void 0?`${e.transitionFrame}/${e.transitionFrames}`:"";this._el.frameLabel.textContent=e.phase==="cached"?"cached transition frames":e.phase==="finalizing"?"finalizing transition frames":"rendering transition frames",this._el.frameValue.textContent=d,this._el.frameRow.style.visibility=d?"visible":"hidden",this._el.root.setAttribute("aria-valuenow",String(Math.round(s*100))),this.show()}get hideTimeout(){return this._hideTimeout}destroy(){this._hideTimeout&&(clearTimeout(this._hideTimeout),this._hideTimeout=null)}_scheduleCleanup(){this._hideTimeout&&clearTimeout(this._hideTimeout),this._hideTimeout=setTimeout(()=>{this._el.root.classList.remove("hfp-hiding"),this._hideTimeout=null},ze)}}class qe extends HTMLElement{constructor(){super();u(this,"shadow");u(this,"container");u(this,"iframe");u(this,"posterEl",null);u(this,"controlsApi",null);u(this,"resizeObserver");u(this,"shaderLoader");u(this,"probe");u(this,"_ready",!1);u(this,"_currentTime",0);u(this,"_duration",0);u(this,"_paused",!0);u(this,"_lastUpdateMs",0);u(this,"_volume",1);u(this,"_compositionWidth",1920);u(this,"_compositionHeight",1080);u(this,"_directTimelineAdapter",null);u(this,"_directTimelineClock");u(this,"_parentTickRaf",null);u(this,"_media");this.shadow=this.attachShadow({mode:"open"}),we(this.shadow,me),{container:this.container,iframe:this.iframe}=Ee(),this.shadow.appendChild(this.container);const t=$e();this.shadow.appendChild(t.root),this.shaderLoader=new je(t),this._media=new Pe({dispatchEvent:i=>this.dispatchEvent(i),getMuted:()=>this.muted,getVolume:()=>this._volume,getPlaybackRate:()=>this.playbackRate,getCurrentTime:()=>this._currentTime,isPaused:()=>this._paused}),this._directTimelineClock=new Ce({onTimeUpdate:(i,r)=>{var s;this._currentTime=i,(s=this.controlsApi)==null||s.updateTime(i,r),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{currentTime:i}}))},getLoop:()=>this.loop,restart:()=>{this.seek(0),this.play()},onPaused:()=>{var i;this._media.audioOwner==="parent"&&this._media.pauseAll(),this._paused=!0,(i=this.controlsApi)==null||i.updatePlaying(!1),this.dispatchEvent(new Event("ended"))},onEnded:()=>this.loop}),this.probe=new pe(this.iframe,{onReady:i=>this._onProbeReady(i),onError:i=>this.dispatchEvent(new CustomEvent("error",{detail:{message:i}}))}),this.addEventListener("click",i=>{ye(i)||(this._paused?this.play():this.pause())}),this.resizeObserver=new ResizeObserver(()=>this._rescale()),this._onMessage=this._onMessage.bind(this),this._onIframeLoad=this._onIframeLoad.bind(this)}static get observedAttributes(){return["src","srcdoc","width","height","controls","muted","volume","poster","playback-rate","audio-src",C,k]}connectedCallback(){this.resizeObserver.observe(this),window.addEventListener("message",this._onMessage),this.iframe.addEventListener("load",this._onIframeLoad),this.hasAttribute("controls")&&this._setupControls(),this.hasAttribute("poster")&&(this.posterEl=re(this.shadow,this.getAttribute("poster"),this.posterEl)),this.hasAttribute("audio-src")&&this._media.setupFromUrl(this.getAttribute("audio-src")),this.hasAttribute("srcdoc")&&(this.iframe.srcdoc=U(this,this.getAttribute("srcdoc"))),this.hasAttribute("src")&&(this.iframe.src=F(this,this.getAttribute("src")))}disconnectedCallback(){var t;this.resizeObserver.disconnect(),window.removeEventListener("message",this._onMessage),this.iframe.removeEventListener("load",this._onIframeLoad),this.probe.stop(),this._directTimelineClock.stop(),this._stopParentTickClock(),this._directTimelineAdapter=null,this.shaderLoader.destroy(),this._media.destroy(),(t=this.controlsApi)==null||t.destroy()}attributeChangedCallback(t,i,r){var s,a,d,c,m,p;switch(t){case"src":r&&(this._ready=!1,this.iframe.src=F(this,r));break;case"srcdoc":this._ready=!1,r!==null?this.iframe.srcdoc=U(this,r):this.iframe.removeAttribute("srcdoc");break;case"width":this._compositionWidth=parseInt(r||"1920",10),this._rescale();break;case"height":this._compositionHeight=parseInt(r||"1080",10),this._rescale();break;case"controls":r!==null?this._setupControls():((s=this.controlsApi)==null||s.destroy(),this.controlsApi=null);break;case"poster":this.posterEl=re(this.shadow,r,this.posterEl);break;case"playback-rate":{const h=parseFloat(r||"1");this._media.updatePlaybackRate(h),this._sendControl("set-playback-rate",{playbackRate:h}),(d=(a=this._directTimelineAdapter)==null?void 0:a.timeScale)==null||d.call(a,h),(c=this.controlsApi)==null||c.updateSpeed(h),this.dispatchEvent(new Event("ratechange"));break}case"muted":this._media.updateMuted(r!==null),this._sendControl("set-muted",{muted:r!==null}),(m=this.controlsApi)==null||m.updateMuted(r!==null),this.dispatchEvent(new Event("volumechange"));break;case"volume":{const h=Math.max(0,Math.min(1,parseFloat(r||"1")));this._volume=h,this._media.updateVolume(h),this._sendControl("set-volume",{volume:h}),(p=this.controlsApi)==null||p.updateVolume(h),this.dispatchEvent(new Event("volumechange"));break}case"audio-src":r&&this._media.setupFromUrl(r);break;case C:case k:this._reloadShaderOptions();break}}get iframeElement(){return this.iframe}play(){var i,r;(i=this.posterEl)==null||i.remove(),this.posterEl=null,this._duration>0&&this._currentTime>=this._duration&&this.seek(0),this._paused=!1;const t=this._tryDirectTimelinePlay();t||(this._sendControl("play"),this._ready&&!this._directTimelineAdapter&&this._startParentTickClock()),this._media.audioOwner==="parent"&&this._media.playAll(),(r=this.controlsApi)==null||r.updatePlaying(!0),this.dispatchEvent(new Event("play")),t&&this._directTimelineAdapter&&this._directTimelineClock.start(this._directTimelineAdapter,()=>this._currentTime,()=>this._duration,()=>this._paused)}pause(){var t;this._tryDirectTimelinePause()||this._sendControl("pause"),this._directTimelineClock.stop(),this._stopParentTickClock(),this._media.audioOwner==="parent"&&this._media.pauseAll(),this._paused=!0,(t=this.controlsApi)==null||t.updatePlaying(!1),this.dispatchEvent(new Event("pause"))}seek(t){var i,r;!this._trySyncSeek(t)&&!this._tryDirectTimelineSeek(t)&&this._sendControl("seek",{frame:Math.round(t*30)}),this._directTimelineClock.stop(),this._stopParentTickClock(),this._currentTime=t,this._media.audioOwner==="parent"&&this._media.seekAll(t),this._paused=!0,(i=this.controlsApi)==null||i.updatePlaying(!1),(r=this.controlsApi)==null||r.updateTime(this._currentTime,this._duration)}get currentTime(){return this._currentTime}set currentTime(t){this.seek(t)}get duration(){return this._duration}get paused(){return this._paused}get ready(){return this._ready}get playbackRate(){return parseFloat(this.getAttribute("playback-rate")||"1")}set playbackRate(t){this.setAttribute("playback-rate",String(t))}get shaderCaptureScale(){return He(this)}set shaderCaptureScale(t){this.setAttribute(C,String(t))}get shaderLoading(){return S(this)}set shaderLoading(t){t==="composition"?this.removeAttribute(k):this.setAttribute(k,t)}get muted(){return this.hasAttribute("muted")}set muted(t){t?this.setAttribute("muted",""):this.removeAttribute("muted")}get volume(){return this._volume}set volume(t){this.setAttribute("volume",String(Math.max(0,Math.min(1,t))))}get loop(){return this.hasAttribute("loop")}set loop(t){t?this.setAttribute("loop",""):this.removeAttribute("loop")}_sendControl(t,i={}){var r;try{(r=this.iframe.contentWindow)==null||r.postMessage({source:"hf-parent",type:"control",action:t,...i},"*")}catch{}}_reloadShaderOptions(){if(S(this)!=="player"&&this.shaderLoader.reset(),this.hasAttribute("srcdoc")){this.iframe.srcdoc=U(this,this.getAttribute("srcdoc")||"");return}this.hasAttribute("src")&&(this.iframe.src=F(this,this.getAttribute("src")||""))}_trySyncSeek(t){try{const i=this.iframe.contentWindow,r=i==null?void 0:i.__player;return typeof(r==null?void 0:r.seek)!="function"?!1:(r.seek.call(r,t),!0)}catch{return!1}}_withDirectTimeline(t){const i=this._directTimelineAdapter||this.probe.resolveDirectTimelineAdapter();if(!i)return!1;try{return t(i),this._directTimelineAdapter=i,!0}catch{return!1}}_tryDirectTimelineSeek(t){return this._withDirectTimeline(i=>{i.seek(t),i.pause()})}_tryDirectTimelinePlay(){return this._withDirectTimeline(t=>void t.play())}_tryDirectTimelinePause(){return this._withDirectTimeline(t=>void t.pause())}_startParentTickClock(){this._stopParentTickClock();const t=()=>{if(this._paused){this._parentTickRaf=null;return}this._sendControl("tick"),this._parentTickRaf=requestAnimationFrame(t)};this._parentTickRaf=requestAnimationFrame(t)}_stopParentTickClock(){this._parentTickRaf!==null&&(cancelAnimationFrame(this._parentTickRaf),this._parentTickRaf=null)}_onMessage(t){Oe(t,this.iframe.contentWindow,{getPlaybackState:()=>({currentTime:this._currentTime,duration:this._duration,paused:this._paused,lastUpdateMs:this._lastUpdateMs}),setPlaybackState:({currentTime:i,duration:r,paused:s,lastUpdateMs:a})=>{this._currentTime=i,this._duration=r,this._paused=s,this._lastUpdateMs=a},getShaderLoadingMode:()=>S(this),shaderLoader:this.shaderLoader,setCompositionSize:(i,r)=>{this._compositionWidth=i,this._compositionHeight=r,this._rescale()},sendControl:(i,r)=>this._sendControl(i,r),getIframeDoc:()=>this.iframe.contentDocument,updateControlsTime:(i,r)=>{var s;return(s=this.controlsApi)==null?void 0:s.updateTime(i,r)},updateControlsPlaying:i=>{var r;return(r=this.controlsApi)==null?void 0:r.updatePlaying(i)},dispatchEvent:i=>this.dispatchEvent(i),seek:i=>this.seek(i),play:()=>this.play(),getLoop:()=>this.loop,media:this._media})}_onProbeReady({duration:t,adapter:i,compositionSize:r}){var s;this._duration=t,this._directTimelineAdapter=i.kind==="direct-timeline"?i.timeline:null,this._ready=!0,(s=this.controlsApi)==null||s.updateTime(0,t),this.dispatchEvent(new CustomEvent("ready",{detail:{duration:t}})),r&&(this._compositionWidth=r.width,this._compositionHeight=r.height,this._rescale());try{const a=this.iframe.contentDocument;a&&this._media.setupFromIframe(a)}catch{}this.hasAttribute("autoplay")&&this.play()}_rescale(){Te(this,this.iframe,this._compositionWidth,this._compositionHeight)}_onIframeLoad(){this._directTimelineAdapter=null,this._directTimelineClock.stop(),this._stopParentTickClock(),this.shaderLoader.reset(),this._media.resetForIframeLoad(),this.probe.start()}_setupControls(){this.controlsApi||(this.controlsApi=ve(this.shadow,this.muted,this._volume,this.getAttribute("speed-presets"),{onPlay:()=>this.play(),onPause:()=>this.pause(),onSeek:t=>this.seek(t*this._duration),onSpeedChange:t=>void(this.playbackRate=t),onMuteToggle:()=>void(this.muted=!this.muted),onVolumeChange:t=>void(this.volume=t)}))}get _audioOwner(){return this._media.audioOwner}get _parentMedia(){return this._media.entries}_mirrorParentMediaTime(t,i){this._media.mirrorTime(t,i)}_promoteToParentProxy(){let t=null;try{t=this.iframe.contentDocument}catch{}this._media.promoteToParentProxy(t,(i,r)=>this._mirrorParentMediaTime(i,r)),this._sendControl("set-media-output-muted",{muted:!0})}_observeDynamicMedia(t){this._media.setupFromIframe(t)}}customElements.get("hyperframes-player")||customElements.define("hyperframes-player",qe);export{qe as HyperframesPlayer,_e as SPEED_PRESETS,N as formatSpeed,ie as formatTime};
418
+ `,K='<svg width="24" height="24" viewBox="0 0 18 18" fill="currentColor"><polygon points="4,2 16,9 4,16"/></svg>',fe='<svg width="24" height="24" viewBox="0 0 18 18" fill="currentColor"><rect x="3" y="2" width="4" height="14"/><rect x="11" y="2" width="4" height="14"/></svg>',ee='<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3z"/><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/><path d="M14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>',te='<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3z"/><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>',ge='<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3z"/><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z" opacity="0.3"/><line x1="18" y1="7" x2="14" y2="17" stroke="currentColor" stroke-width="2"/></svg>',_e=[.25,.5,1,1.5,2,4];function N(n){return Number.isInteger(n)?`${n}x`:`${n}x`}function ie(n){if(!Number.isFinite(n)||n<0)return"0:00";const e=Math.floor(n),t=Math.floor(e/60),i=e%60;return`${t}:${i.toString().padStart(2,"0")}`}function be(n,e,t={}){const i=t.speedPresets??_e,r=document.createElement("div");r.className="hfp-controls",r.addEventListener("click",o=>{o.stopPropagation()});const s=document.createElement("button");s.className="hfp-play-btn",s.type="button",s.innerHTML=K,s.setAttribute("aria-label","Play");const a=document.createElement("div");a.className="hfp-scrubber";const d=document.createElement("div");d.className="hfp-progress",d.style.width="0%",a.appendChild(d);const c=document.createElement("span");c.className="hfp-time",c.textContent="0:00 / 0:00";const m=document.createElement("div");m.className="hfp-speed-wrap";const p=document.createElement("button");p.className="hfp-speed-btn",p.type="button",p.textContent="1x",p.setAttribute("aria-label","Playback speed");const h=document.createElement("div");h.className="hfp-speed-menu",h.setAttribute("role","menu");for(const o of i){const l=document.createElement("button");l.className="hfp-speed-option",l.type="button",l.setAttribute("role","menuitem"),l.dataset.speed=String(o),l.textContent=N(o),o===1&&l.classList.add("hfp-active"),h.appendChild(l)}m.appendChild(h),m.appendChild(p);const _=document.createElement("div");_.className="hfp-volume-wrap";const f=document.createElement("button");f.className="hfp-mute-btn",f.type="button",f.innerHTML=ee,f.setAttribute("aria-label","Mute");const b=document.createElement("div");b.className="hfp-volume-slider-wrap";const g=document.createElement("div");g.className="hfp-volume-slider",g.setAttribute("role","slider"),g.setAttribute("aria-label","Volume"),g.setAttribute("aria-valuemin","0"),g.setAttribute("aria-valuemax","100"),g.setAttribute("aria-valuenow","100"),g.tabIndex=0;const y=document.createElement("div");y.className="hfp-volume-fill",y.style.width="100%",g.appendChild(y),b.appendChild(g),_.appendChild(b),_.appendChild(f),r.appendChild(s),r.appendChild(a),r.appendChild(c),r.appendChild(_),r.appendChild(m),n.appendChild(r);let M=!1,E=!1,w=1,x=null;i.indexOf(1);const L=(o,l)=>o?ge:l===0||l<.5?te:ee;s.addEventListener("click",o=>{o.stopPropagation(),M?e.onPause():e.onPlay()}),f.addEventListener("click",o=>{o.stopPropagation(),e.onMuteToggle()});let T=!1;const P=o=>{const l=g.getBoundingClientRect(),v=Math.max(0,Math.min(1,(o-l.left)/l.width));w=v,y.style.width=`${v*100}%`,g.setAttribute("aria-valuenow",String(Math.round(v*100))),E&&v>0&&e.onMuteToggle(),f.innerHTML=L(E,v),e.onVolumeChange(v)};g.addEventListener("mousedown",o=>{o.stopPropagation(),T=!0,P(o.clientX)});const H=o=>{T&&P(o.clientX)},$=()=>{T=!1};document.addEventListener("mousemove",H),document.addEventListener("mouseup",$),g.addEventListener("touchstart",o=>{T=!0;const l=o.touches[0];l&&P(l.clientX)},{passive:!0});const z=o=>{if(T){const l=o.touches[0];l&&P(l.clientX)}},j=()=>{T=!1};document.addEventListener("touchmove",z,{passive:!0}),document.addEventListener("touchend",j);const q=.05;g.addEventListener("keydown",o=>{let l=w;if(o.key==="ArrowRight"||o.key==="ArrowUp")l=Math.min(1,w+q);else if(o.key==="ArrowLeft"||o.key==="ArrowDown")l=Math.max(0,w-q);else return;o.preventDefault(),o.stopPropagation(),w=l,y.style.width=`${l*100}%`,g.setAttribute("aria-valuenow",String(Math.round(l*100))),E&&l>0&&e.onMuteToggle(),f.innerHTML=L(E,l),e.onVolumeChange(l)});const B=o=>{for(const l of h.querySelectorAll(".hfp-speed-option"))l.classList.toggle("hfp-active",l.dataset.speed===String(o))};p.addEventListener("click",o=>{o.stopPropagation();const l=h.classList.toggle("hfp-open");p.setAttribute("aria-expanded",String(l))}),h.addEventListener("click",o=>{o.stopPropagation();const l=o.target.closest(".hfp-speed-option");if(!l)return;const v=parseFloat(l.dataset.speed);i.indexOf(v),p.textContent=N(v),B(v),h.classList.remove("hfp-open"),p.setAttribute("aria-expanded","false"),e.onSpeedChange(v)});const W=()=>{h.classList.remove("hfp-open"),p.setAttribute("aria-expanded","false")};document.addEventListener("click",W);const R=o=>{const l=a.getBoundingClientRect(),v=Math.max(0,Math.min(1,(o-l.left)/l.width));e.onSeek(v)};let A=!1;a.addEventListener("mousedown",o=>{o.stopPropagation(),A=!0,R(o.clientX)});const X=o=>{A&&R(o.clientX)},G=()=>{A=!1};document.addEventListener("mousemove",X),document.addEventListener("mouseup",G),a.addEventListener("touchstart",o=>{A=!0;const l=o.touches[0];l&&R(l.clientX)},{passive:!0});const Y=o=>{if(A){const l=o.touches[0];l&&R(l.clientX)}},Q=()=>{A=!1};document.addEventListener("touchmove",Y,{passive:!0}),document.addEventListener("touchend",Q);const J=()=>{x&&clearTimeout(x),x=setTimeout(()=>{M&&r.classList.add("hfp-hidden")},3e3)},Z=n instanceof ShadowRoot?n.host:n;return Z.addEventListener("mousemove",()=>{r.classList.remove("hfp-hidden"),J()}),Z.addEventListener("mouseleave",()=>{M&&r.classList.add("hfp-hidden")}),{updateTime(o,l){const v=l>0?Math.min(o,l):o,oe=l>0?v/l*100:0;d.style.width=`${oe}%`,c.textContent=`${ie(v)} / ${ie(l)}`},updatePlaying(o){M=o,s.innerHTML=o?fe:K,s.setAttribute("aria-label",o?"Pause":"Play"),o?J():r.classList.remove("hfp-hidden")},updateSpeed(o){i.indexOf(o),p.textContent=N(o),B(o)},updateMuted(o){E=o,f.innerHTML=L(o,w),f.setAttribute("aria-label",o?"Unmute":"Mute")},updateVolume(o){w=o,y.style.width=`${o*100}%`,g.setAttribute("aria-valuenow",String(Math.round(o*100))),f.innerHTML=L(E,o)},show(){r.style.display=""},hide(){r.style.display="none"},destroy(){document.removeEventListener("mousemove",X),document.removeEventListener("mouseup",G),document.removeEventListener("touchmove",Y),document.removeEventListener("touchend",Q),document.removeEventListener("mousemove",H),document.removeEventListener("mouseup",$),document.removeEventListener("touchmove",z),document.removeEventListener("touchend",j),document.removeEventListener("click",W),x&&clearTimeout(x)}}}function ve(n,e,t,i,r){const s=i?i.split(",").map(Number).filter(c=>!isNaN(c)&&c>0):void 0,d=be(n,r,s?{speedPresets:s}:{});return d.updateMuted(e),d.updateVolume(t),d}function re(n,e,t){return e?(t||(t=document.createElement("img"),t.className="hfp-poster",n.appendChild(t)),t.src=e,t):(t==null||t.remove(),null)}function ye(n){return n.composedPath().some(e=>e instanceof HTMLElement&&e.classList.contains("hfp-controls"))}let I=null;function we(n,e){if(typeof CSSStyleSheet<"u")try{I||(I=new CSSStyleSheet,I.replaceSync(e)),n.adoptedStyleSheets=[I];return}catch{}const t=document.createElement("style");t.textContent=e,n.appendChild(t)}function Ee(){const n=document.createElement("div");n.className="hfp-container";const e=document.createElement("iframe");return e.className="hfp-iframe",e.sandbox.add("allow-scripts","allow-same-origin"),e.allow="autoplay; fullscreen",e.referrerPolicy="no-referrer",e.title="HyperFrames Composition",n.appendChild(e),{container:n,iframe:e}}function Te(n,e,t,i){const r=n.getBoundingClientRect();if(r.width===0||r.height===0)return;const s=Math.min(r.width/t,r.height/i);e.style.width=`${t}px`,e.style.height=`${i}px`,e.style.transform=`translate(-50%, -50%) scale(${s})`}const Ae=100;class Ce{constructor(e){u(this,"_raf",null);u(this,"_lastUpdateMs",0);this._callbacks=e}start(e,t,i,r){this.stop();const s=()=>{if(r()){this._raf=null;return}let a;try{a=e.time()}catch{this._raf=null;return}const d=i();d>0&&(a=Math.min(a,d));const c=d>0&&a>=d,m=performance.now();if((m-this._lastUpdateMs>Ae||c)&&(this._lastUpdateMs=m,this._callbacks.onTimeUpdate(a,d)),c){if(this._callbacks.getLoop()){this._callbacks.restart();return}try{e.pause()}catch{}this._callbacks.onPaused(),this._raf=null;return}this._raf=requestAnimationFrame(s)};this._raf=requestAnimationFrame(s)}stop(){this._raf!==null&&(cancelAnimationFrame(this._raf),this._raf=null)}get isRunning(){return this._raf!==null}}function xe(n){const e=Array.from(n.querySelectorAll("[data-composition-id]"));if(e.length===0)return n.body?[n.body]:[];const t=[];for(const i of e)Se(i)||t.push(i);return ke(n),t}function ke(n){const e=n.body;if(!e||typeof console>"u"||typeof console.warn!="function")return;const t=e.querySelectorAll("audio[data-start], video[data-start]");if(t.length===0)return;const i=[];for(const r of t)r.closest("[data-composition-id]")||i.push(r);i.length!==0&&console.warn(`[hyperframes-player] selectMediaObserverTargets: composition hosts are present, but ${i.length} body-level timed media element(s) sit outside every [data-composition-id] subtree and will not be observed. Move them inside a composition host or the parent-frame proxy will never adopt them.`,i)}function Se(n){let e=n.parentElement;for(;e;){if(e.hasAttribute("data-composition-id"))return!0;e=e.parentElement}return!1}const Me=.05,Le=2;class Pe{constructor(e){u(this,"_entries",[]);u(this,"_mediaObserver");u(this,"_playbackErrorPosted",!1);u(this,"_audioOwner","runtime");u(this,"_dispatchEvent");u(this,"_getMuted");u(this,"_getVolume");u(this,"_getPlaybackRate");u(this,"_getCurrentTime");u(this,"_isPaused");this._dispatchEvent=e.dispatchEvent,this._getMuted=e.getMuted,this._getVolume=e.getVolume,this._getPlaybackRate=e.getPlaybackRate,this._getCurrentTime=e.getCurrentTime,this._isPaused=e.isPaused}get audioOwner(){return this._audioOwner}get entries(){return this._entries}get playbackErrorPosted(){return this._playbackErrorPosted}resetForIframeLoad(){this._playbackErrorPosted=!1;const e=this._audioOwner==="parent";this._audioOwner="runtime",this.pauseAll(),this.teardownObserver(),e&&this._dispatchEvent(new CustomEvent("audioownershipchange",{detail:{owner:"runtime",reason:"iframe-reload"}}))}destroy(){this.teardownObserver();for(const e of this._entries)e.el.pause(),e.el.src="";this._entries=[]}updateMuted(e){for(const t of this._entries)t.el.muted=e}updateVolume(e){for(const t of this._entries)t.el.volume=e}updatePlaybackRate(e){for(const t of this._entries)t.el.playbackRate=e}playAll(){for(const e of this._entries)e.el.src&&e.el.play().catch(t=>this._reportPlaybackError(t))}pauseAll(){for(const e of this._entries)e.el.pause()}seekAll(e){for(const t of this._entries){const i=e-t.start;i>=0&&i<t.duration&&(t.el.currentTime=i)}}mirrorTime(e,t){const i=(t==null?void 0:t.force)===!0;for(const r of this._entries){const s=e-r.start;if(s<0||s>=r.duration){r.driftSamples=0;continue}Math.abs(r.el.currentTime-s)>Me?(r.driftSamples+=1,(i||r.driftSamples>=Le)&&(r.el.currentTime=s,r.driftSamples=0)):r.driftSamples=0}}promoteToParentProxy(e,t){if(this._audioOwner==="parent")return;if(this._audioOwner="parent",e)for(const r of e.querySelectorAll("video, audio"))r.muted=!0;const i=this._getCurrentTime();t?t(i,{force:!0}):this.mirrorTime(i,{force:!0}),this._isPaused()||this.playAll(),this._dispatchEvent(new CustomEvent("audioownershipchange",{detail:{owner:"parent",reason:"autoplay-blocked"}}))}setupFromIframe(e){const t=e.querySelectorAll("audio[data-start], video[data-start]");for(const i of t)this._adoptIframeMedia(i);this._observeDynamicMedia(e)}setupFromUrl(e){this._createEntry(e,"audio",0,1/0)}teardownObserver(){var e;(e=this._mediaObserver)==null||e.disconnect(),this._mediaObserver=void 0}_reportPlaybackError(e){this._playbackErrorPosted||(this._playbackErrorPosted=!0,this._dispatchEvent(new CustomEvent("playbackerror",{detail:{source:"parent-proxy",error:e}})))}_createEntry(e,t,i,r){if(this._entries.some(c=>c.el.src===e))return null;const s=t==="video"?document.createElement("video"):new Audio;s.preload="auto",s.src=e,s.load(),s.muted=this._getMuted(),s.volume=this._getVolume();const a=this._getPlaybackRate();a!==1&&(s.playbackRate=a);const d={el:s,start:i,duration:r,driftSamples:0};return this._entries.push(d),d}_adoptIframeMedia(e){var c;if(e.preload==="metadata"||e.preload==="none")return;const t=e.getAttribute("src")||((c=e.querySelector("source"))==null?void 0:c.getAttribute("src"));if(!t)return;const i=new URL(t,e.ownerDocument.baseURI).href,r=parseFloat(e.getAttribute("data-start")||"0"),s=parseFloat(e.getAttribute("data-duration")||"Infinity"),a=e.tagName==="VIDEO"?"video":"audio",d=this._createEntry(i,a,r,s);d&&this._audioOwner==="parent"&&(this.mirrorTime(this._getCurrentTime(),{force:!0}),!this._isPaused()&&d.el.src&&d.el.play().catch(m=>this._reportPlaybackError(m)))}_detachIframeMedia(e){var a;const t=e.getAttribute("src")||((a=e.querySelector("source"))==null?void 0:a.getAttribute("src"));if(!t)return;const i=new URL(t,e.ownerDocument.baseURI).href,r=this._entries.findIndex(d=>d.el.src===i);if(r===-1)return;const s=this._entries[r];s.el.pause(),s.el.src="",this._entries.splice(r,1)}_observeDynamicMedia(e){if(this.teardownObserver(),typeof MutationObserver>"u"||!e.body)return;const t=new MutationObserver(s=>{var a,d,c,m;for(const p of s){if(p.type==="attributes"&&p.attributeName==="preload"){const h=p.target;h instanceof HTMLMediaElement&&h.matches("audio[data-start], video[data-start]")&&h.preload==="auto"&&this._adoptIframeMedia(h);continue}for(const h of p.addedNodes){if(!(h instanceof Element))continue;const _=[];(a=h.matches)!=null&&a.call(h,"audio[data-start], video[data-start]")&&_.push(h);const f=(d=h.querySelectorAll)==null?void 0:d.call(h,"audio[data-start], video[data-start]");if(f)for(const b of f)_.push(b);for(const b of _)this._adoptIframeMedia(b)}for(const h of p.removedNodes){if(!(h instanceof Element))continue;const _=[];(c=h.matches)!=null&&c.call(h,"audio[data-start], video[data-start]")&&_.push(h);const f=(m=h.querySelectorAll)==null?void 0:m.call(h,"audio[data-start], video[data-start]");if(f)for(const b of f)_.push(b);for(const b of _)this._detachIframeMedia(b)}}}),i={childList:!0,subtree:!0,attributes:!0,attributeFilter:["preload"]},r=xe(e);for(const s of r)t.observe(s,i);this._mediaObserver=t}}const Re=100;function Ie(n,e,t,i){const r=(n.frame??0)/e,s=t.duration>0?Math.min(r,t.duration):r,a=!t.paused,d=!n.isPlaying,c=t.duration>0&&s>=t.duration&&(a||n.isPlaying);if(c&&i.getLoop())return i.media.audioOwner==="parent"&&i.media.pauseAll(),i.seek(0),i.play(),{...t,currentTime:s,paused:!1};const m={...t,currentTime:s,paused:d};i.media.audioOwner==="parent"&&(a&&d?i.media.pauseAll():!a&&!d&&i.media.playAll(),i.media.mirrorTime(s));const p=performance.now(),h=d!==t.paused;return(p-t.lastUpdateMs>Re||h)&&(m.lastUpdateMs=p,i.updateControlsTime(s,t.duration),i.updateControlsPlaying(!d),i.dispatchEvent(new CustomEvent("timeupdate",{detail:{currentTime:s}}))),c&&(i.media.audioOwner==="parent"&&i.media.pauseAll(),m.paused=!0,i.updateControlsPlaying(!1),i.dispatchEvent(new Event("ended"))),m}const ne=30;function Oe(n,e,t){if(n.source!==e)return;const i=n.data;if(!(!i||i.source!=="hf-preview")){if(i.type==="shader-transition-state"){const r=i.state&&typeof i.state=="object"?i.state:{};t.shaderLoader.update(r,t.getShaderLoadingMode()),t.dispatchEvent(new CustomEvent("shadertransitionstate",{detail:{compositionId:i.compositionId,state:r}}));return}if(i.type==="state"){t.setPlaybackState(Ie({frame:i.frame??0,isPlaying:!!i.isPlaying},ne,t.getPlaybackState(),t));return}if(i.type==="media-autoplay-blocked"){let r=null;try{r=t.getIframeDoc()}catch{}t.media.promoteToParentProxy(r,(s,a)=>t.media.mirrorTime(s,a)),t.sendControl("set-media-output-muted",{muted:!0});return}if(i.type==="timeline"&&i.durationInFrames>0){if(Number.isFinite(i.durationInFrames)){const r=t.getPlaybackState(),s=i.durationInFrames/ne;t.setPlaybackState({...r,duration:s}),t.updateControlsTime(r.currentTime,s)}return}i.type==="stage-size"&&i.width>0&&i.height>0&&t.setCompositionSize(i.width,i.height)}}const C="shader-capture-scale",k="shader-loading",De="__hf_shader_capture_scale",Ne="__hf_shader_loading",O=["Preparing scene transitions","Sampling outgoing scene motion","Sampling incoming scene motion","Caching transition frames","Finalizing transition preview"];function V(n){if(n===null)return null;const e=Number(n);return!Number.isFinite(e)||e<=0?null:String(Math.min(1,Math.max(.25,e)))}function Fe(n){if(n===null||n.trim()==="")return"composition";const e=n.trim().toLowerCase();return e==="none"||e==="false"||e==="0"||e==="off"?"none":e==="player"||e==="true"||e==="1"||e==="on"?"player":"composition"}function se(n,e,t){t===null?n.delete(e):n.set(e,t)}function Ue(n,e,t){const i=n.indexOf("#"),r=i>=0?n.slice(0,i):n,s=i>=0?n.slice(i):"",a=r.indexOf("?"),d=a>=0?r.slice(0,a):r,c=a>=0?r.slice(a+1):"",m=new URLSearchParams(c);se(m,De,e),se(m,Ne,t==="composition"?null:t);const p=m.toString();return`${d}${p?`?${p}`:""}${s}`}function Ve(n,e,t){if(e===null&&t==="composition")return n;const i=[];e!==null&&i.push(`window.__HF_SHADER_CAPTURE_SCALE=${JSON.stringify(e)};`),t!=="composition"&&i.push(`window.__HF_SHADER_LOADING=${JSON.stringify(t)};`);const r=`<script data-hyperframes-player-shader-options>${i.join("")}<\/script>`;return/<head\b[^>]*>/i.test(n)?n.replace(/<head\b[^>]*>/i,s=>`${s}${r}`):/<html\b[^>]*>/i.test(n)?n.replace(/<html\b[^>]*>/i,s=>`${s}${r}`):`${r}${n}`}function S(n){return Fe(n.getAttribute(k))}function He(n){return Number(V(n.getAttribute(C))??"1")}function F(n,e){return Ue(e,V(n.getAttribute(C)),S(n))}function U(n,e){return Ve(e,V(n.getAttribute(C)),S(n))}function $e(){const n=document.createElement("div");n.className="hfp-shader-loader",n.setAttribute("role","status"),n.setAttribute("aria-live","polite"),n.setAttribute("aria-label","Preparing scene transitions"),n.setAttribute("data-hyperframes-ignore",""),n.draggable=!1;const e=f=>{f.preventDefault(),f.stopPropagation()};for(const f of["selectstart","dragstart","pointerdown","mousedown","click","dblclick","contextmenu","touchstart"])n.addEventListener(f,e,{capture:!0});const t=document.createElement("div");t.className="hfp-shader-loader-panel",t.draggable=!1;const i=document.createElement("div");i.className="hfp-shader-loader-mark",i.draggable=!1,i.innerHTML=['<svg width="78" height="78" viewBox="0 0 100 100" fill="none" aria-hidden="true" draggable="false">','<path d="M10.1851 57.8021L33.1145 73.8313C36.2202 75.9978 41.5173 73.5433 42.4816 69.4984L51.7611 30.4271C52.7253 26.3822 48.5802 23.9277 44.4602 26.0942L13.917 42.1235C6.96677 45.7676 4.97564 54.1579 10.1851 57.8021Z" fill="url(#hfp-shader-loader-grad-left)"/>','<path d="M87.5129 57.5141L56.9696 73.5433C52.8371 75.7098 48.7046 73.2553 49.6688 69.2104L58.9483 30.1391C59.9125 26.0942 65.2097 23.6397 68.3154 25.8062L91.2447 41.8354C96.4668 45.4796 94.4631 53.8699 87.5129 57.5141Z" fill="url(#hfp-shader-loader-grad-right)"/>',"<defs>",'<linearGradient id="hfp-shader-loader-grad-left" x1="48.5676" y1="25" x2="44.7804" y2="71.9384" gradientUnits="userSpaceOnUse">','<stop stop-color="#06E3FA"/>','<stop offset="1" stop-color="#4FDB5E"/>',"</linearGradient>",'<linearGradient id="hfp-shader-loader-grad-right" x1="54.8282" y1="73.8392" x2="72.0989" y2="32.8932" gradientUnits="userSpaceOnUse">','<stop stop-color="#06E3FA"/>','<stop offset="1" stop-color="#4FDB5E"/>',"</linearGradient>","</defs>","</svg>"].join("");const r=document.createElement("div");r.className="hfp-shader-loader-title";const s=document.createElement("span");s.className="hfp-shader-loader-title-text",s.textContent=O[0],r.appendChild(s);const a=document.createElement("div");a.className="hfp-shader-loader-detail",a.textContent="Rendering animated scene samples for shader transitions.";const d=document.createElement("div");d.className="hfp-shader-loader-track",d.setAttribute("aria-hidden","true");const c=document.createElement("div");c.className="hfp-shader-loader-fill",d.appendChild(c);const m=document.createElement("div");m.className="hfp-shader-loader-progress";const p=f=>{const b=document.createElement("div");b.className="hfp-shader-loader-row";const g=document.createElement("span");g.className="hfp-shader-loader-label",g.textContent=f;const y=document.createElement("span");return y.className="hfp-shader-loader-value",b.appendChild(g),b.appendChild(y),m.appendChild(b),{row:b,label:g,value:y}},h=p("transition"),_=p("transition frame");return t.appendChild(i),t.appendChild(r),t.appendChild(a),t.appendChild(d),t.appendChild(m),n.appendChild(t),{root:n,fill:c,title:s,detail:a,transitionValue:h.value,frameLabel:_.label,frameValue:_.value,frameRow:_.row}}const ze=420;class je{constructor(e){u(this,"_el");u(this,"_hideTimeout",null);this._el=e}show(){this._hideTimeout&&(clearTimeout(this._hideTimeout),this._hideTimeout=null),this._el.root.classList.remove("hfp-hiding"),this._el.root.classList.add("hfp-visible")}hide(){if(this._el.root.classList.contains("hfp-hiding")){this._hideTimeout||this._scheduleCleanup();return}this._el.root.classList.contains("hfp-visible")&&(this._el.root.classList.add("hfp-hiding"),this._el.root.classList.remove("hfp-visible"),this._scheduleCleanup())}reset(){this._hideTimeout&&(clearTimeout(this._hideTimeout),this._hideTimeout=null),this._el.root.classList.remove("hfp-visible","hfp-hiding"),this._el.fill.style.transform="scaleX(0)",this._el.transitionValue.textContent="",this._el.frameValue.textContent="",this._el.frameRow.style.visibility="hidden"}update(e,t){if(t!=="player"){this.reset();return}if(e.ready||!e.loading){this.hide();return}const i=typeof e.progress=="number"&&Number.isFinite(e.progress)?e.progress:0,r=typeof e.total=="number"&&Number.isFinite(e.total)?e.total:0,s=r>0?Math.min(1,Math.max(0,i/r)):0,a=Math.min(O.length-1,Math.floor(s*O.length));this._el.title.textContent=O[a]||"Preparing scene transitions",this._el.detail.textContent=e.phase==="cached"?"Loading cached transition frames before playback.":e.phase==="finalizing"?"Uploading transition textures for smooth playback.":"Rendering animated scene samples for shader transitions.",this._el.fill.style.transform=`scaleX(${s})`,this._el.transitionValue.textContent=e.currentTransition!==void 0&&e.transitionTotal!==void 0?`${e.currentTransition}/${e.transitionTotal}`:r>0?`${i}/${r}`:"";const d=e.transitionFrame!==void 0&&e.transitionFrames!==void 0?`${e.transitionFrame}/${e.transitionFrames}`:"";this._el.frameLabel.textContent=e.phase==="cached"?"cached transition frames":e.phase==="finalizing"?"finalizing transition frames":"rendering transition frames",this._el.frameValue.textContent=d,this._el.frameRow.style.visibility=d?"visible":"hidden",this._el.root.setAttribute("aria-valuenow",String(Math.round(s*100))),this.show()}get hideTimeout(){return this._hideTimeout}destroy(){this._hideTimeout&&(clearTimeout(this._hideTimeout),this._hideTimeout=null)}_scheduleCleanup(){this._hideTimeout&&clearTimeout(this._hideTimeout),this._hideTimeout=setTimeout(()=>{this._el.root.classList.remove("hfp-hiding"),this._hideTimeout=null},ze)}}class qe extends HTMLElement{constructor(){super();u(this,"shadow");u(this,"container");u(this,"iframe");u(this,"posterEl",null);u(this,"controlsApi",null);u(this,"resizeObserver");u(this,"shaderLoader");u(this,"probe");u(this,"_ready",!1);u(this,"_currentTime",0);u(this,"_duration",0);u(this,"_paused",!0);u(this,"_lastUpdateMs",0);u(this,"_volume",1);u(this,"_compositionWidth",1920);u(this,"_compositionHeight",1080);u(this,"_directTimelineAdapter",null);u(this,"_directTimelineClock");u(this,"_parentTickRaf",null);u(this,"_media");this.shadow=this.attachShadow({mode:"open"}),we(this.shadow,me),{container:this.container,iframe:this.iframe}=Ee(),this.shadow.appendChild(this.container);const t=$e();this.shadow.appendChild(t.root),this.shaderLoader=new je(t),this._media=new Pe({dispatchEvent:i=>this.dispatchEvent(i),getMuted:()=>this.muted,getVolume:()=>this._volume,getPlaybackRate:()=>this.playbackRate,getCurrentTime:()=>this._currentTime,isPaused:()=>this._paused}),this._directTimelineClock=new Ce({onTimeUpdate:(i,r)=>{var s;this._currentTime=i,(s=this.controlsApi)==null||s.updateTime(i,r),this.dispatchEvent(new CustomEvent("timeupdate",{detail:{currentTime:i}}))},getLoop:()=>this.loop,restart:()=>{this.seek(0),this.play()},onPaused:()=>{var i;this._media.audioOwner==="parent"&&this._media.pauseAll(),this._paused=!0,(i=this.controlsApi)==null||i.updatePlaying(!1),this.dispatchEvent(new Event("ended"))},onEnded:()=>this.loop}),this.probe=new pe(this.iframe,{onReady:i=>this._onProbeReady(i),onError:i=>this.dispatchEvent(new CustomEvent("error",{detail:{message:i}}))}),this.addEventListener("click",i=>{ye(i)||(this._paused?this.play():this.pause())}),this.resizeObserver=new ResizeObserver(()=>this._rescale()),this._onMessage=this._onMessage.bind(this),this._onIframeLoad=this._onIframeLoad.bind(this)}static get observedAttributes(){return["src","srcdoc","width","height","controls","muted","volume","poster","playback-rate","audio-src",C,k]}connectedCallback(){this.resizeObserver.observe(this),window.addEventListener("message",this._onMessage),this.iframe.addEventListener("load",this._onIframeLoad),this.hasAttribute("controls")&&this._setupControls(),this.hasAttribute("poster")&&(this.posterEl=re(this.shadow,this.getAttribute("poster"),this.posterEl)),this.hasAttribute("audio-src")&&this._media.setupFromUrl(this.getAttribute("audio-src")),this.hasAttribute("srcdoc")&&(this.iframe.srcdoc=U(this,this.getAttribute("srcdoc"))),this.hasAttribute("src")&&(this.iframe.src=F(this,this.getAttribute("src")))}disconnectedCallback(){var t;this.resizeObserver.disconnect(),window.removeEventListener("message",this._onMessage),this.iframe.removeEventListener("load",this._onIframeLoad),this.probe.stop(),this._directTimelineClock.stop(),this._stopParentTickClock(),this._directTimelineAdapter=null,this.shaderLoader.destroy(),this._media.destroy(),(t=this.controlsApi)==null||t.destroy()}attributeChangedCallback(t,i,r){var s,a,d,c,m,p;switch(t){case"src":r&&(this._ready=!1,this.iframe.src=F(this,r));break;case"srcdoc":this._ready=!1,r!==null?this.iframe.srcdoc=U(this,r):this.iframe.removeAttribute("srcdoc");break;case"width":this._compositionWidth=parseInt(r||"1920",10),this._rescale();break;case"height":this._compositionHeight=parseInt(r||"1080",10),this._rescale();break;case"controls":r!==null?this._setupControls():((s=this.controlsApi)==null||s.destroy(),this.controlsApi=null);break;case"poster":this.posterEl=re(this.shadow,r,this.posterEl);break;case"playback-rate":{const h=parseFloat(r||"1");this._media.updatePlaybackRate(h),this._sendControl("set-playback-rate",{playbackRate:h}),(d=(a=this._directTimelineAdapter)==null?void 0:a.timeScale)==null||d.call(a,h),(c=this.controlsApi)==null||c.updateSpeed(h),this.dispatchEvent(new Event("ratechange"));break}case"muted":this._media.updateMuted(r!==null),this._sendControl("set-muted",{muted:r!==null}),(m=this.controlsApi)==null||m.updateMuted(r!==null),this.dispatchEvent(new Event("volumechange"));break;case"volume":{const h=Math.max(0,Math.min(1,parseFloat(r||"1")));this._volume=h,this._media.updateVolume(h),this._sendControl("set-volume",{volume:h}),(p=this.controlsApi)==null||p.updateVolume(h),this.dispatchEvent(new Event("volumechange"));break}case"audio-src":r&&this._media.setupFromUrl(r);break;case C:case k:this._reloadShaderOptions();break}}get iframeElement(){return this.iframe}play(){var i,r;(i=this.posterEl)==null||i.remove(),this.posterEl=null,this._duration>0&&this._currentTime>=this._duration&&this.seek(0),this._paused=!1;const t=this._tryDirectTimelinePlay();t||(this._sendControl("play"),this._ready&&!this._directTimelineAdapter&&this._startParentTickClock()),this._media.audioOwner==="parent"&&this._media.playAll(),(r=this.controlsApi)==null||r.updatePlaying(!0),this.dispatchEvent(new Event("play")),t&&this._directTimelineAdapter&&this._directTimelineClock.start(this._directTimelineAdapter,()=>this._currentTime,()=>this._duration,()=>this._paused)}pause(){var t;this._tryDirectTimelinePause()||this._sendControl("pause"),this._directTimelineClock.stop(),this._stopParentTickClock(),this._media.audioOwner==="parent"&&this._media.pauseAll(),this._paused=!0,(t=this.controlsApi)==null||t.updatePlaying(!1),this.dispatchEvent(new Event("pause"))}seek(t){var i,r;!this._trySyncSeek(t)&&!this._tryDirectTimelineSeek(t)&&this._sendControl("seek",{frame:Math.round(t*30)}),this._directTimelineClock.stop(),this._stopParentTickClock(),this._currentTime=t,this._media.audioOwner==="parent"&&(this._media.pauseAll(),this._media.seekAll(t)),this._paused=!0,(i=this.controlsApi)==null||i.updatePlaying(!1),(r=this.controlsApi)==null||r.updateTime(this._currentTime,this._duration)}get currentTime(){return this._currentTime}set currentTime(t){this.seek(t)}get duration(){return this._duration}get paused(){return this._paused}get ready(){return this._ready}get playbackRate(){return parseFloat(this.getAttribute("playback-rate")||"1")}set playbackRate(t){this.setAttribute("playback-rate",String(t))}get shaderCaptureScale(){return He(this)}set shaderCaptureScale(t){this.setAttribute(C,String(t))}get shaderLoading(){return S(this)}set shaderLoading(t){t==="composition"?this.removeAttribute(k):this.setAttribute(k,t)}get muted(){return this.hasAttribute("muted")}set muted(t){t?this.setAttribute("muted",""):this.removeAttribute("muted")}get volume(){return this._volume}set volume(t){this.setAttribute("volume",String(Math.max(0,Math.min(1,t))))}get loop(){return this.hasAttribute("loop")}set loop(t){t?this.setAttribute("loop",""):this.removeAttribute("loop")}_sendControl(t,i={}){var r;try{(r=this.iframe.contentWindow)==null||r.postMessage({source:"hf-parent",type:"control",action:t,...i},"*")}catch{}}_reloadShaderOptions(){if(S(this)!=="player"&&this.shaderLoader.reset(),this.hasAttribute("srcdoc")){this.iframe.srcdoc=U(this,this.getAttribute("srcdoc")||"");return}this.hasAttribute("src")&&(this.iframe.src=F(this,this.getAttribute("src")||""))}_trySyncSeek(t){try{const i=this.iframe.contentWindow,r=i==null?void 0:i.__player;return typeof(r==null?void 0:r.seek)!="function"?!1:(r.seek.call(r,t),!0)}catch{return!1}}_withDirectTimeline(t){const i=this._directTimelineAdapter||this.probe.resolveDirectTimelineAdapter();if(!i)return!1;try{return t(i),this._directTimelineAdapter=i,!0}catch{return!1}}_tryDirectTimelineSeek(t){return this._withDirectTimeline(i=>{i.seek(t),i.pause()})}_tryDirectTimelinePlay(){return this._withDirectTimeline(t=>void t.play())}_tryDirectTimelinePause(){return this._withDirectTimeline(t=>void t.pause())}_startParentTickClock(){this._stopParentTickClock();const t=()=>{if(this._paused){this._parentTickRaf=null;return}this._sendControl("tick"),this._parentTickRaf=requestAnimationFrame(t)};this._parentTickRaf=requestAnimationFrame(t)}_stopParentTickClock(){this._parentTickRaf!==null&&(cancelAnimationFrame(this._parentTickRaf),this._parentTickRaf=null)}_onMessage(t){Oe(t,this.iframe.contentWindow,{getPlaybackState:()=>({currentTime:this._currentTime,duration:this._duration,paused:this._paused,lastUpdateMs:this._lastUpdateMs}),setPlaybackState:({currentTime:i,duration:r,paused:s,lastUpdateMs:a})=>{this._currentTime=i,this._duration=r,this._paused=s,this._lastUpdateMs=a},getShaderLoadingMode:()=>S(this),shaderLoader:this.shaderLoader,setCompositionSize:(i,r)=>{this._compositionWidth=i,this._compositionHeight=r,this._rescale()},sendControl:(i,r)=>this._sendControl(i,r),getIframeDoc:()=>this.iframe.contentDocument,updateControlsTime:(i,r)=>{var s;return(s=this.controlsApi)==null?void 0:s.updateTime(i,r)},updateControlsPlaying:i=>{var r;return(r=this.controlsApi)==null?void 0:r.updatePlaying(i)},dispatchEvent:i=>this.dispatchEvent(i),seek:i=>this.seek(i),play:()=>this.play(),getLoop:()=>this.loop,media:this._media})}_onProbeReady({duration:t,adapter:i,compositionSize:r}){var s;this._duration=t,this._directTimelineAdapter=i.kind==="direct-timeline"?i.timeline:null,this._ready=!0,(s=this.controlsApi)==null||s.updateTime(0,t),this.dispatchEvent(new CustomEvent("ready",{detail:{duration:t}})),r&&(this._compositionWidth=r.width,this._compositionHeight=r.height,this._rescale());try{const a=this.iframe.contentDocument;a&&this._media.setupFromIframe(a)}catch{}this.hasAttribute("autoplay")&&this.play()}_rescale(){Te(this,this.iframe,this._compositionWidth,this._compositionHeight)}_onIframeLoad(){this._directTimelineAdapter=null,this._directTimelineClock.stop(),this._stopParentTickClock(),this.shaderLoader.reset(),this._media.resetForIframeLoad(),this.probe.start()}_setupControls(){this.controlsApi||(this.controlsApi=ve(this.shadow,this.muted,this._volume,this.getAttribute("speed-presets"),{onPlay:()=>this.play(),onPause:()=>this.pause(),onSeek:t=>this.seek(t*this._duration),onSpeedChange:t=>void(this.playbackRate=t),onMuteToggle:()=>void(this.muted=!this.muted),onVolumeChange:t=>void(this.volume=t)}))}get _audioOwner(){return this._media.audioOwner}get _parentMedia(){return this._media.entries}_mirrorParentMediaTime(t,i){this._media.mirrorTime(t,i)}_promoteToParentProxy(){let t=null;try{t=this.iframe.contentDocument}catch{}this._media.promoteToParentProxy(t,(i,r)=>this._mirrorParentMediaTime(i,r)),this._sendControl("set-media-output-muted",{muted:!0})}_observeDynamicMedia(t){this._media.setupFromIframe(t)}}customElements.get("hyperframes-player")||customElements.define("hyperframes-player",qe);export{qe as HyperframesPlayer,_e as SPEED_PRESETS,N as formatSpeed,ie as formatTime};