hyperframes 0.7.75 → 0.7.77

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.
@@ -935,7 +935,8 @@
935
935
  // (the pre-#U10 behaviour). Longer prose survives a nibbled edge; only flag
936
936
  // once a real share of it is covered — see `occludedTextIssue`.
937
937
  const ATOMIC_LABEL_MAX_CHARS = 16;
938
- const PROSE_COVERAGE_FLOOR = 0.15;
938
+ // Default prose floor — callers may lower via auditLayout({ proseCoverageFloor }).
939
+ const DEFAULT_PROSE_COVERAGE_FLOOR = 0.15;
939
940
 
940
941
  function isAtomicLabel(text) {
941
942
  return text.length > 0 && text.length <= ATOMIC_LABEL_MAX_CHARS && !/\s/.test(text);
@@ -995,12 +996,8 @@
995
996
  return false;
996
997
  }
997
998
 
998
- // Catches the blind spot the overflow checks miss: text that fits its box
999
- // perfectly but is covered by a later sibling/overlay. An atomic label
1000
- // (short, no whitespace) flags at any coverage; ordinary prose only flags
1001
- // once coveredFraction clears PROSE_COVERAGE_FLOOR, since a sliver of edge
1002
- // cover on a paragraph is usually a styling artifact, not a reading defect.
1003
- function occludedTextIssue(element, time) {
999
+ // text_occluded: atomic labels flag at any hit; prose needs coveredFraction >= proseCoverageFloor (default 0.15).
1000
+ function occludedTextIssue(element, time, proseCoverageFloor) {
1004
1001
  if (hasAllowOcclusionFlag(element)) return null;
1005
1002
  if (!hasVisibleTextInk(element)) return null;
1006
1003
  const textRect = textRectFor(element, true);
@@ -1012,7 +1009,7 @@
1012
1009
  textRects.length > 0 ? textRects : [textRect],
1013
1010
  );
1014
1011
  if (!occluder) return null;
1015
- if (!isAtomicLabel(text) && coveredFraction < PROSE_COVERAGE_FLOOR) return null;
1012
+ if (!isAtomicLabel(text) && coveredFraction < proseCoverageFloor) return null;
1016
1013
  return {
1017
1014
  code: "text_occluded",
1018
1015
  severity: "error",
@@ -1198,6 +1195,7 @@
1198
1195
  return issues;
1199
1196
  }
1200
1197
 
1198
+ // Soft prior only — the counterfactual attach test (below) is what makes detachment a finding.
1201
1199
  const CONNECTOR_NAME = /\b(conn(ector)?|arrow|edge|link|flow|wire)\b/i;
1202
1200
  const CONNECTOR_SKIP_CONTAINERS = "defs, marker, clipPath, mask, symbol, pattern";
1203
1201
 
@@ -1207,14 +1205,16 @@
1207
1205
  return `${element.id || ""} ${className}`;
1208
1206
  }
1209
1207
 
1210
- // Screen-space endpoints via the browser: getScreenCTM covers viewBox, preserveAspectRatio and group transforms.
1211
- function pathScreenEndpoints(svg, path) {
1212
- if (
1213
- typeof path.getTotalLength !== "function" ||
1214
- typeof path.getPointAtLength !== "function" ||
1215
- typeof path.getScreenCTM !== "function" ||
1216
- typeof svg.createSVGPoint !== "function"
1217
- ) {
1208
+ function isConnectorPath(svg, path) {
1209
+ if (path.hasAttribute("marker-start") || path.hasAttribute("marker-end")) return true;
1210
+ return (
1211
+ CONNECTOR_NAME.test(connectorNameFor(svg)) || CONNECTOR_NAME.test(connectorNameFor(path))
1212
+ );
1213
+ }
1214
+
1215
+ /** Raw `d`-space endpoints (no CTM) — the mapping authors use when they paste screen coords into `d`. */
1216
+ function pathUserEndpoints(path) {
1217
+ if (typeof path.getTotalLength !== "function" || typeof path.getPointAtLength !== "function") {
1218
1218
  return null;
1219
1219
  }
1220
1220
  let total;
@@ -1224,6 +1224,20 @@
1224
1224
  return null;
1225
1225
  }
1226
1226
  if (!Number.isFinite(total) || total <= 0) return null;
1227
+ const start = path.getPointAtLength(0);
1228
+ const end = path.getPointAtLength(total);
1229
+ return { start: { x: start.x, y: start.y }, end: { x: end.x, y: end.y } };
1230
+ }
1231
+
1232
+ // Screen endpoints via getScreenCTM (viewBox, preserveAspectRatio, group transforms).
1233
+ function pathScreenEndpoints(svg, path, user) {
1234
+ if (
1235
+ !user ||
1236
+ typeof path.getScreenCTM !== "function" ||
1237
+ typeof svg.createSVGPoint !== "function"
1238
+ ) {
1239
+ return null;
1240
+ }
1227
1241
  const matrix = path.getScreenCTM();
1228
1242
  if (!matrix) return null;
1229
1243
  const toScreen = (local) => {
@@ -1233,10 +1247,7 @@
1233
1247
  const mapped = point.matrixTransform(matrix);
1234
1248
  return { x: mapped.x, y: mapped.y };
1235
1249
  };
1236
- return {
1237
- start: toScreen(path.getPointAtLength(0)),
1238
- end: toScreen(path.getPointAtLength(total)),
1239
- };
1250
+ return { start: toScreen(user.start), end: toScreen(user.end) };
1240
1251
  }
1241
1252
 
1242
1253
  function distanceToRect(point, rect) {
@@ -1246,6 +1257,7 @@
1246
1257
  }
1247
1258
 
1248
1259
  // Solid, compact elements a connector could plausibly anchor to.
1260
+ // Both tiers keep `element` so attachment identity is stable across containment vs near-miss.
1249
1261
  function connectorAnchorRects(root, rootRect) {
1250
1262
  const compact = [];
1251
1263
  const painted = [];
@@ -1261,42 +1273,57 @@
1261
1273
  if (area < 400) continue;
1262
1274
  // Containment tier: large opaque targets only — a text-bearing wrapper contains its own diagram's endpoints.
1263
1275
  if (opaque && area <= rootArea * 0.6) painted.push({ rect, element });
1264
- if (area <= rootArea * 0.15) compact.push(rect);
1276
+ if (area <= rootArea * 0.15) compact.push({ rect, element });
1265
1277
  }
1266
1278
  return { compact, painted };
1267
1279
  }
1268
1280
 
1269
- function isConnectorPath(svg, path) {
1270
- if (path.hasAttribute("marker-start") || path.hasAttribute("marker-end")) return true;
1271
- return (
1272
- CONNECTOR_NAME.test(connectorNameFor(svg)) || CONNECTOR_NAME.test(connectorNameFor(path))
1273
- );
1274
- }
1275
-
1276
- // A connector whose BOTH endpoints land far from every anchorable element was drawn in the wrong frame.
1277
- // min over the two endpoints is intentional: a half-attached connector is a design choice, not frame drift.
1281
+ // Flag only the documented bug: rendered endpoints miss, but user-space-as-screen would attach.
1278
1282
  function connectorDetachmentIssues(root, rootRect, time) {
1279
1283
  const issues = [];
1280
1284
  let anchors = null;
1285
+ // Attach near-miss tolerance (screen px). Separate from the closed-glyph chord floor.
1281
1286
  const threshold = Math.max(32, Math.min(rootRect.width, rootRect.height) * 0.02);
1287
+ const MIN_CONNECTOR_CHORD_PX = 8;
1282
1288
  for (const svg of Array.from(root.querySelectorAll("svg"))) {
1283
1289
  if (!isVisibleElement(svg) || hasAllowOverflowFlag(svg)) continue;
1284
1290
  for (const path of Array.from(svg.querySelectorAll("path"))) {
1285
1291
  if (path.closest(CONNECTOR_SKIP_CONTAINERS)) continue;
1286
1292
  if (!isConnectorPath(svg, path)) continue;
1287
- const endpoints = pathScreenEndpoints(svg, path);
1288
- if (!endpoints) continue;
1293
+ const user = pathUserEndpoints(path);
1294
+ const rendered = pathScreenEndpoints(svg, path, user);
1295
+ if (!user || !rendered) continue;
1296
+ // Closed/glyph paths collapse to one point — compare in screen px (not user units).
1297
+ const renderedChord = Math.hypot(
1298
+ rendered.end.x - rendered.start.x,
1299
+ rendered.end.y - rendered.start.y,
1300
+ );
1301
+ if (renderedChord < MIN_CONNECTOR_CHORD_PX) continue;
1289
1302
  if (anchors === null) anchors = connectorAnchorRects(root, rootRect);
1290
1303
  if (anchors.compact.length < 2) return issues;
1291
- const attached = (point) =>
1292
- anchors.painted.some(
1293
- (anchor) => !anchor.element.contains(svg) && distanceToRect(point, anchor.rect) === 0,
1294
- ) || anchors.compact.some((rect) => distanceToRect(point, rect) <= threshold);
1295
- if (attached(endpoints.start) || attached(endpoints.end)) continue;
1304
+ // Stable DOM identity across painted (inside) and compact (near-miss) tiers.
1305
+ const attachmentKey = (point) => {
1306
+ for (const anchor of anchors.painted) {
1307
+ if (!anchor.element.contains(svg) && distanceToRect(point, anchor.rect) === 0) {
1308
+ return anchor.element;
1309
+ }
1310
+ }
1311
+ for (const anchor of anchors.compact) {
1312
+ if (distanceToRect(point, anchor.rect) <= threshold) return anchor.element;
1313
+ }
1314
+ return null;
1315
+ };
1316
+ const attached = (point) => attachmentKey(point) !== null;
1317
+ // Half-attached as drawn is allowed; only full render-miss proceeds.
1318
+ if (attached(rendered.start) || attached(rendered.end)) continue;
1319
+ // Paste-into-`d` bug: both raw endpoints land on distinct anchors as screen pixels.
1320
+ const userStartKey = attachmentKey(user.start);
1321
+ const userEndKey = attachmentKey(user.end);
1322
+ if (!userStartKey || !userEndKey || userStartKey === userEndKey) continue;
1296
1323
  const gap = Math.round(
1297
1324
  Math.min(
1298
- Math.min(...anchors.compact.map((rect) => distanceToRect(endpoints.start, rect))),
1299
- Math.min(...anchors.compact.map((rect) => distanceToRect(endpoints.end, rect))),
1325
+ Math.min(...anchors.compact.map((a) => distanceToRect(rendered.start, a.rect))),
1326
+ Math.min(...anchors.compact.map((a) => distanceToRect(rendered.end, a.rect))),
1300
1327
  ),
1301
1328
  );
1302
1329
  issues.push({
@@ -1305,17 +1332,17 @@
1305
1332
  time,
1306
1333
  selector: selectorFor(path),
1307
1334
  containerSelector: selectorFor(svg),
1308
- message: `Connector path endpoints are ${gap}px from the nearest anchorable element measured coordinates were likely drawn into an SVG with a different origin.`,
1335
+ message: `Connector path endpoints render ${gap}px from the nearest anchorable element, but the path's user-space coordinates would attach if read as screen pixels — screen/viewport numbers were likely written into SVG \`d\` without inverting the CTM.`,
1309
1336
  rect: toRect({
1310
- left: Math.min(endpoints.start.x, endpoints.end.x),
1311
- top: Math.min(endpoints.start.y, endpoints.end.y),
1312
- right: Math.max(endpoints.start.x, endpoints.end.x),
1313
- bottom: Math.max(endpoints.start.y, endpoints.end.y),
1314
- width: Math.abs(endpoints.end.x - endpoints.start.x),
1315
- height: Math.abs(endpoints.end.y - endpoints.start.y),
1337
+ left: Math.min(rendered.start.x, rendered.end.x),
1338
+ top: Math.min(rendered.start.y, rendered.end.y),
1339
+ right: Math.max(rendered.start.x, rendered.end.x),
1340
+ bottom: Math.max(rendered.start.y, rendered.end.y),
1341
+ width: Math.abs(rendered.end.x - rendered.start.x),
1342
+ height: Math.abs(rendered.end.y - rendered.start.y),
1316
1343
  }),
1317
1344
  fixHint:
1318
- "Subtract the SVG's own rect when converting measured coordinates, and keep the SVG a direct child of the stage.",
1345
+ "Convert measured screen coordinates into the SVG's user space (subtract the SVG rect / invert getScreenCTM) before writing path `d`, and keep the SVG a direct child of the stage.",
1319
1346
  });
1320
1347
  }
1321
1348
  }
@@ -1390,6 +1417,10 @@
1390
1417
  const time = options && typeof options.time === "number" ? options.time : 0;
1391
1418
  const tolerance =
1392
1419
  options && typeof options.tolerance === "number" ? Math.max(0, options.tolerance) : 2;
1420
+ const proseCoverageFloor =
1421
+ options && typeof options.proseCoverageFloor === "number"
1422
+ ? Math.min(1, Math.max(0, options.proseCoverageFloor))
1423
+ : DEFAULT_PROSE_COVERAGE_FLOOR;
1393
1424
  const root =
1394
1425
  document.querySelector("[data-composition-id][data-width][data-height]") ||
1395
1426
  document.querySelector("[data-composition-id]") ||
@@ -1407,7 +1438,7 @@
1407
1438
  const clipped = clippedTextIssue(element, time, tolerance);
1408
1439
  if (clipped) issues.push(clipped);
1409
1440
  issues.push(...textOverflowIssues(element, root, rootRect, time, tolerance));
1410
- const occluded = occludedTextIssue(element, time);
1441
+ const occluded = occludedTextIssue(element, time, proseCoverageFloor);
1411
1442
  if (occluded) issues.push(occluded);
1412
1443
  const invisible = invisibleTextIssue(element, time);
1413
1444
  if (invisible) issues.push(invisible);
@@ -1,4 +1,4 @@
1
- "use strict";var HyperframesPlayer=(()=>{var J=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var qe=Object.getOwnPropertyNames;var Ye=Object.prototype.hasOwnProperty;var Xe=(i,e)=>{for(var t in e)J(i,t,{get:e[t],enumerable:!0})},Ze=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of qe(e))!Ye.call(i,n)&&n!==t&&J(i,n,{get:()=>e[n],enumerable:!(r=Ge(e,n))||r.enumerable});return i};var Qe=i=>Ze(J({},"__esModule",{value:!0}),i);var Lt={};Xe(Lt,{HyperframesPlayer:()=>Q,SPEED_PRESETS:()=>te,formatSpeed:()=>N,formatTime:()=>$});function ye(i){return i.hasRuntime||i.runtimeInjected?!1:!!(i.hasNestedCompositions||i.hasTimelines&&i.attempts>=5)}function I(i){return typeof i=="object"&&i!==null}function Ee(i){return I(i)&&typeof i.getDuration=="function"}function Se(i){return I(i)&&typeof i.duration=="function"&&typeof i.time=="function"&&typeof i.seek=="function"&&typeof i.play=="function"&&typeof i.pause=="function"}var Je="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.7.75/dist/hyperframe.runtime.iife.js";function D(i){if(i===null)return null;let e=Number.parseInt(i,10);return Number.isFinite(e)&&e>0?e:null}function Ke(i){let e=i?.querySelector("[data-composition-id][data-width][data-height]")??i?.querySelector("[data-width][data-height]");if(!e)return null;let t=D(e.getAttribute("data-width")),r=D(e.getAttribute("data-height"));return t!==null&&r!==null?{width:t,height:r}:null}var j=class{constructor(e,t){this._iframe=e;this._callbacks=t}_iframe;_callbacks;_interval=null;_runtimeInjected=!1;get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let e=0;this._interval=setInterval(()=>{e++;try{let t=this._iframe.contentWindow;if(!t)return;let r=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(ye({hasRuntime:r,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!r)return;let s=this._resolvePlaybackDurationAdapter(t);if(s&&s.getDuration()>0){this.stop();let l=Ke(this._iframe.contentDocument);this._callbacks.onReady({duration:s.getDuration(),adapter:s,compositionSize:l});return}}catch{}e>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{let e=this._iframe.contentWindow;return e?this._resolveDirectTimelineAdapterFromWindow(e):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(e){return this._resolveDirectTimelineAdapterFromWindow(e)}hasRuntimeBridge(e){return Reflect.get(e,"__hf")!==void 0||I(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=Je,(e.head||e.documentElement).appendChild(t),this._callbacks.onRuntimeInjected?.()}catch{}}_resolveDirectTimelineAdapterFromWindow(e){if(this.hasRuntimeBridge(e))return null;let t=Reflect.get(e,"__timelines");if(!I(t))return null;let r=Object.keys(t);if(r.length===0)return null;let n=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=n&&n in t?n:r[r.length-1],s=t[o];return Se(s)?s:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(Ee(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let r=this._resolveDirectTimelineAdapterFromWindow(e);return r?{kind:"direct-timeline",timeline:r,getDuration:()=>r.duration()}:null}};var Te=`
1
+ "use strict";var HyperframesPlayer=(()=>{var J=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var qe=Object.getOwnPropertyNames;var Ye=Object.prototype.hasOwnProperty;var Xe=(i,e)=>{for(var t in e)J(i,t,{get:e[t],enumerable:!0})},Ze=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of qe(e))!Ye.call(i,n)&&n!==t&&J(i,n,{get:()=>e[n],enumerable:!(r=Ge(e,n))||r.enumerable});return i};var Qe=i=>Ze(J({},"__esModule",{value:!0}),i);var Lt={};Xe(Lt,{HyperframesPlayer:()=>Q,SPEED_PRESETS:()=>te,formatSpeed:()=>N,formatTime:()=>$});function ye(i){return i.hasRuntime||i.runtimeInjected?!1:!!(i.hasNestedCompositions||i.hasTimelines&&i.attempts>=5)}function I(i){return typeof i=="object"&&i!==null}function Ee(i){return I(i)&&typeof i.getDuration=="function"}function Se(i){return I(i)&&typeof i.duration=="function"&&typeof i.time=="function"&&typeof i.seek=="function"&&typeof i.play=="function"&&typeof i.pause=="function"}var Je="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.7.77/dist/hyperframe.runtime.iife.js";function D(i){if(i===null)return null;let e=Number.parseInt(i,10);return Number.isFinite(e)&&e>0?e:null}function Ke(i){let e=i?.querySelector("[data-composition-id][data-width][data-height]")??i?.querySelector("[data-width][data-height]");if(!e)return null;let t=D(e.getAttribute("data-width")),r=D(e.getAttribute("data-height"));return t!==null&&r!==null?{width:t,height:r}:null}var j=class{constructor(e,t){this._iframe=e;this._callbacks=t}_iframe;_callbacks;_interval=null;_runtimeInjected=!1;get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let e=0;this._interval=setInterval(()=>{e++;try{let t=this._iframe.contentWindow;if(!t)return;let r=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(ye({hasRuntime:r,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!r)return;let s=this._resolvePlaybackDurationAdapter(t);if(s&&s.getDuration()>0){this.stop();let l=Ke(this._iframe.contentDocument);this._callbacks.onReady({duration:s.getDuration(),adapter:s,compositionSize:l});return}}catch{}e>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{let e=this._iframe.contentWindow;return e?this._resolveDirectTimelineAdapterFromWindow(e):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(e){return this._resolveDirectTimelineAdapterFromWindow(e)}hasRuntimeBridge(e){return Reflect.get(e,"__hf")!==void 0||I(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=Je,(e.head||e.documentElement).appendChild(t),this._callbacks.onRuntimeInjected?.()}catch{}}_resolveDirectTimelineAdapterFromWindow(e){if(this.hasRuntimeBridge(e))return null;let t=Reflect.get(e,"__timelines");if(!I(t))return null;let r=Object.keys(t);if(r.length===0)return null;let n=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=n&&n in t?n:r[r.length-1],s=t[o];return Se(s)?s:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(Ee(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let r=this._resolveDirectTimelineAdapterFromWindow(e);return r?{kind:"direct-timeline",timeline:r,getDuration:()=>r.duration()}:null}};var Te=`
2
2
  :host {
3
3
  display: block;
4
4
  position: relative;
@@ -1,4 +1,4 @@
1
- var ce=Object.defineProperty;var pe=(r,t,e)=>t in r?ce(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var c=(r,t,e)=>pe(r,typeof t!="symbol"?t+"":t,e);import{r as ne,i as me,a as fe}from"./index-DzDajONI.js";function _e(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function F(r){return typeof r=="object"&&r!==null}function ge(r){return F(r)&&typeof r.getDuration=="function"}function ye(r){return F(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}function ve(r){if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid HyperFrames runtime version: ${r}`);return`https://cdn.jsdelivr.net/npm/@hyperframes/core@${r}/dist/hyperframe.runtime.iife.js`}const be=typeof __HYPERFRAMES_RUNTIME_CDN_URL__=="string"?__HYPERFRAMES_RUNTIME_CDN_URL__:ve("0.0.0-dev");function H(r){if(r===null)return null;const t=Number.parseInt(r,10);return Number.isFinite(t)&&t>0?t:null}function we(r){const t=(r==null?void 0:r.querySelector("[data-composition-id][data-width][data-height]"))??(r==null?void 0:r.querySelector("[data-width][data-height]"));if(!t)return null;const e=H(t.getAttribute("data-width")),i=H(t.getAttribute("data-height"));return e!==null&&i!==null?{width:e,height:i}:null}class Ae{constructor(t,e){c(this,"_interval",null);c(this,"_runtimeInjected",!1);this._iframe=t,this._callbacks=e}get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let t=0;this._interval=setInterval(()=>{var e;t++;try{const i=this._iframe.contentWindow;if(!i)return;const s=!!(i.__hf||i.__player),o=!!(i.__timelines&&Object.keys(i.__timelines).length>0),d=!!((e=this._iframe.contentDocument)!=null&&e.querySelector("[data-composition-src]"));if(_e({hasRuntime:s,hasTimelines:o,hasNestedCompositions:d,runtimeInjected:this._runtimeInjected,attempts:t})){this._injectRuntime();return}if(this._runtimeInjected&&!s)return;const a=this._resolvePlaybackDurationAdapter(i);if(a&&a.getDuration()>0){this.stop();const h=we(this._iframe.contentDocument);this._callbacks.onReady({duration:a.getDuration(),adapter:a,compositionSize:h});return}}catch{}t>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{const t=this._iframe.contentWindow;return t?this._resolveDirectTimelineAdapterFromWindow(t):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(t){return this._resolveDirectTimelineAdapterFromWindow(t)}hasRuntimeBridge(t){return Reflect.get(t,"__hf")!==void 0||F(Reflect.get(t,"__player"))}_injectRuntime(){var t,e;this._runtimeInjected=!0;try{const i=this._iframe.contentDocument;if(!i)return;const s=i.createElement("script");s.src=be,(i.head||i.documentElement).appendChild(s),(e=(t=this._callbacks).onRuntimeInjected)==null||e.call(t)}catch{}}_resolveDirectTimelineAdapterFromWindow(t){var a,h;if(this.hasRuntimeBridge(t))return null;const e=Reflect.get(t,"__timelines");if(!F(e))return null;const i=Object.keys(e);if(i.length===0)return null;const s=(h=(a=this._iframe.contentDocument)==null?void 0:a.querySelector("[data-composition-id]"))==null?void 0:h.getAttribute("data-composition-id"),o=s&&s in e?s:i[i.length-1],d=e[o];return ye(d)?d:null}_resolvePlaybackDurationAdapter(t){const e=Reflect.get(t,"__player");if(ge(e))return{kind:"runtime",getDuration:()=>e.getDuration()};const i=this._resolveDirectTimelineAdapterFromWindow(t);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}}const Ee=`
1
+ var ce=Object.defineProperty;var pe=(r,t,e)=>t in r?ce(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var c=(r,t,e)=>pe(r,typeof t!="symbol"?t+"":t,e);import{r as ne,i as me,a as fe}from"./index-Bp4jAYZG.js";function _e(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function F(r){return typeof r=="object"&&r!==null}function ge(r){return F(r)&&typeof r.getDuration=="function"}function ye(r){return F(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}function ve(r){if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid HyperFrames runtime version: ${r}`);return`https://cdn.jsdelivr.net/npm/@hyperframes/core@${r}/dist/hyperframe.runtime.iife.js`}const be=typeof __HYPERFRAMES_RUNTIME_CDN_URL__=="string"?__HYPERFRAMES_RUNTIME_CDN_URL__:ve("0.0.0-dev");function H(r){if(r===null)return null;const t=Number.parseInt(r,10);return Number.isFinite(t)&&t>0?t:null}function we(r){const t=(r==null?void 0:r.querySelector("[data-composition-id][data-width][data-height]"))??(r==null?void 0:r.querySelector("[data-width][data-height]"));if(!t)return null;const e=H(t.getAttribute("data-width")),i=H(t.getAttribute("data-height"));return e!==null&&i!==null?{width:e,height:i}:null}class Ae{constructor(t,e){c(this,"_interval",null);c(this,"_runtimeInjected",!1);this._iframe=t,this._callbacks=e}get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let t=0;this._interval=setInterval(()=>{var e;t++;try{const i=this._iframe.contentWindow;if(!i)return;const s=!!(i.__hf||i.__player),o=!!(i.__timelines&&Object.keys(i.__timelines).length>0),d=!!((e=this._iframe.contentDocument)!=null&&e.querySelector("[data-composition-src]"));if(_e({hasRuntime:s,hasTimelines:o,hasNestedCompositions:d,runtimeInjected:this._runtimeInjected,attempts:t})){this._injectRuntime();return}if(this._runtimeInjected&&!s)return;const a=this._resolvePlaybackDurationAdapter(i);if(a&&a.getDuration()>0){this.stop();const h=we(this._iframe.contentDocument);this._callbacks.onReady({duration:a.getDuration(),adapter:a,compositionSize:h});return}}catch{}t>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{const t=this._iframe.contentWindow;return t?this._resolveDirectTimelineAdapterFromWindow(t):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(t){return this._resolveDirectTimelineAdapterFromWindow(t)}hasRuntimeBridge(t){return Reflect.get(t,"__hf")!==void 0||F(Reflect.get(t,"__player"))}_injectRuntime(){var t,e;this._runtimeInjected=!0;try{const i=this._iframe.contentDocument;if(!i)return;const s=i.createElement("script");s.src=be,(i.head||i.documentElement).appendChild(s),(e=(t=this._callbacks).onRuntimeInjected)==null||e.call(t)}catch{}}_resolveDirectTimelineAdapterFromWindow(t){var a,h;if(this.hasRuntimeBridge(t))return null;const e=Reflect.get(t,"__timelines");if(!F(e))return null;const i=Object.keys(e);if(i.length===0)return null;const s=(h=(a=this._iframe.contentDocument)==null?void 0:a.querySelector("[data-composition-id]"))==null?void 0:h.getAttribute("data-composition-id"),o=s&&s in e?s:i[i.length-1],d=e[o];return ye(d)?d:null}_resolvePlaybackDurationAdapter(t){const e=Reflect.get(t,"__player");if(ge(e))return{kind:"runtime",getDuration:()=>e.getDuration()};const i=this._resolveDirectTimelineAdapterFromWindow(t);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}}const Ee=`
2
2
  :host {
3
3
  display: block;
4
4
  position: relative;
@@ -1 +1 @@
1
- import{g as P}from"./index-DzDajONI.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
1
+ import{g as P}from"./index-Bp4jAYZG.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
@@ -1,4 +1,4 @@
1
- import{n as Qi}from"./index-DzDajONI.js";/*!
1
+ import{n as Qi}from"./index-Bp4jAYZG.js";/*!
2
2
  * Copyright (c) 2026-present, Vanilagy and contributors
3
3
  *
4
4
  * This Source Code Form is subject to the terms of the Mozilla Public