hyperframes 0.8.49 → 0.8.50

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.
@@ -55501,7 +55501,7 @@ function buildChromeArgs(options, config) {
55501
55501
  // frame-capture loop then blocks waiting for it, deadlocking the render.
55502
55502
  "--autoplay-policy=no-user-gesture-required"
55503
55503
  ];
55504
- if (browserGpuMode !== "software") {
55504
+ if (browserGpuMode !== "software" || options.requiresWebGpu) {
55505
55505
  chromeArgs.push(WEBGPU_FLAG);
55506
55506
  }
55507
55507
  if (browserGpuMode === "software") {
@@ -55525,6 +55525,28 @@ function buildChromeArgs(options, config) {
55525
55525
  }
55526
55526
  return chromeArgs;
55527
55527
  }
55528
+ function compositionRequiresWebGpu(html) {
55529
+ for (const [tag] of html.matchAll(/<(?:[^<>"']|"[^"]*"|'[^']*')*>/g)) {
55530
+ if (/\bdata-composition-id\b/i.test(tag)) return /\bdata-requires-webgpu(?:\s|=|>)/i.test(tag);
55531
+ }
55532
+ return false;
55533
+ }
55534
+ async function assertWebGpuAdapterAvailable(page, requiresWebGpu) {
55535
+ if (!requiresWebGpu) return;
55536
+ const hasUsableAdapter = await page.evaluate(async (timeoutMs) => {
55537
+ if (typeof navigator === "undefined" || !navigator.gpu) return false;
55538
+ try {
55539
+ const adapter2 = await Promise.race([
55540
+ navigator.gpu.requestAdapter(),
55541
+ new Promise((resolve18) => setTimeout(() => resolve18(null), timeoutMs))
55542
+ ]);
55543
+ return !!adapter2 && !adapter2.info.isFallbackAdapter;
55544
+ } catch {
55545
+ return false;
55546
+ }
55547
+ }, WEBGPU_ADAPTER_PROBE_TIMEOUT_MS);
55548
+ if (!hasUsableAdapter) throw new WebGpuUnavailableError();
55549
+ }
55528
55550
  function getBrowserGpuArgs(mode, platform3) {
55529
55551
  if (mode === "software") {
55530
55552
  return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
@@ -55549,7 +55571,7 @@ function getBrowserGpuArgs(mode, platform3) {
55549
55571
  return ["--enable-gpu-rasterization"];
55550
55572
  }
55551
55573
  }
55552
- var _puppeteer, CACHED_HEADLESS_SHELL_EXECUTABLES, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS, BEGINFRAME_PROBE_TIMEOUT_MS, BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS, _autoBrowserGpuModeCache, _unverifiedHardwareGpuWarned, browserLeasePool, _cachedVramMb, CANVAS_DRAW_ELEMENT_FEATURE_FLAG, WEBGPU_FLAG;
55574
+ var _puppeteer, CACHED_HEADLESS_SHELL_EXECUTABLES, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS, BEGINFRAME_PROBE_TIMEOUT_MS, BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS, _autoBrowserGpuModeCache, _unverifiedHardwareGpuWarned, browserLeasePool, _cachedVramMb, CANVAS_DRAW_ELEMENT_FEATURE_FLAG, WEBGPU_FLAG, WebGpuUnavailableError, WEBGPU_ADAPTER_PROBE_TIMEOUT_MS;
55553
55575
  var init_browserManager = __esm({
55554
55576
  "../engine/src/services/browserManager.ts"() {
55555
55577
  "use strict";
@@ -55588,6 +55610,15 @@ var init_browserManager = __esm({
55588
55610
  _cachedVramMb = null;
55589
55611
  CANVAS_DRAW_ELEMENT_FEATURE_FLAG = "--enable-features=CanvasDrawElement";
55590
55612
  WEBGPU_FLAG = "--enable-unsafe-webgpu";
55613
+ WebGpuUnavailableError = class extends Error {
55614
+ constructor() {
55615
+ super(
55616
+ "This composition declares data-requires-webgpu, but no hardware WebGPU adapter could be obtained on this browser launch (a software fallback adapter such as swiftshader reports one but cannot render it). Run on a host with a GPU, or remove data-requires-webgpu."
55617
+ );
55618
+ this.name = "WebGpuUnavailableError";
55619
+ }
55620
+ };
55621
+ WEBGPU_ADAPTER_PROBE_TIMEOUT_MS = 1e4;
55591
55622
  }
55592
55623
  });
55593
55624
 
@@ -59198,8 +59229,9 @@ async function createCaptureSession(serverUrl, outputDir, options, onBeforeCaptu
59198
59229
  config
59199
59230
  );
59200
59231
  const preMode = headlessShell && isLinux && !effectiveForceScreenshot && !supersampling && !drawElementTransparent ? "beginframe" : "screenshot";
59232
+ const requiresWebGpu = options.requiresWebGpu ?? await fetch(`${serverUrl}/index.html`, { signal: AbortSignal.timeout(5e3) }).then((res) => res.text()).then(compositionRequiresWebGpu).catch(() => false);
59201
59233
  const chromeArgs = buildChromeArgs(
59202
- { width: options.width, height: options.height, captureMode: preMode },
59234
+ { width: options.width, height: options.height, captureMode: preMode, requiresWebGpu },
59203
59235
  { ...config, browserGpuMode: resolvedGpuMode }
59204
59236
  );
59205
59237
  const browserLease = await acquireBrowser(chromeArgs, config);
@@ -59210,7 +59242,8 @@ async function createCaptureSession(serverUrl, outputDir, options, onBeforeCaptu
59210
59242
  options,
59211
59243
  onBeforeCapture,
59212
59244
  config,
59213
- useDrawElement
59245
+ useDrawElement,
59246
+ requiresWebGpu
59214
59247
  });
59215
59248
  }
59216
59249
  async function constructCaptureSessionWithRollback(input) {
@@ -59259,6 +59292,7 @@ async function constructCaptureSession(input) {
59259
59292
  onBeforeCapture,
59260
59293
  config,
59261
59294
  useDrawElement,
59295
+ requiresWebGpu,
59262
59296
  onPageCreated
59263
59297
  } = input;
59264
59298
  const { browser, captureMode } = browserLease;
@@ -59321,6 +59355,7 @@ async function constructCaptureSession(input) {
59321
59355
  serverUrl,
59322
59356
  outputDir,
59323
59357
  onBeforeCapture,
59358
+ requiresWebGpu,
59324
59359
  isInitialized: false,
59325
59360
  browserConsoleBuffer: [],
59326
59361
  scriptLoadFailures: [],
@@ -59774,6 +59809,7 @@ async function initializeSession(session) {
59774
59809
  );
59775
59810
  throw error;
59776
59811
  }
59812
+ await assertWebGpuAdapterAvailable(page, session.requiresWebGpu ?? false);
59777
59813
  };
59778
59814
  if (session.captureMode === "screenshot") {
59779
59815
  await gotoEntryPage();
@@ -64589,6 +64625,37 @@ var init_htmlCompiler = __esm({
64589
64625
  }
64590
64626
  });
64591
64627
 
64628
+ // ../core/dist/compiler/scriptRuns.js
64629
+ function isClassicInline(el) {
64630
+ const type = (el.getAttribute("type") || "").trim().toLowerCase();
64631
+ return !type || type === "text/javascript" || type === "application/javascript";
64632
+ }
64633
+ function isSeparateExecution(el, isPinned) {
64634
+ return el.hasAttribute("src") || isPinned(el) || (el.getAttribute("type") || "").trim().toLowerCase() === "module";
64635
+ }
64636
+ function inlineScriptRuns(scripts, isPinned = () => false) {
64637
+ const runs = [];
64638
+ let members = [];
64639
+ for (const el of scripts) {
64640
+ if (isSeparateExecution(el, isPinned)) {
64641
+ if (members.length === 0)
64642
+ continue;
64643
+ runs.push({ members, anchor: el });
64644
+ members = [];
64645
+ } else if (isClassicInline(el)) {
64646
+ members.push(el);
64647
+ }
64648
+ }
64649
+ if (members.length > 0)
64650
+ runs.push({ members, anchor: null });
64651
+ return runs;
64652
+ }
64653
+ var init_scriptRuns = __esm({
64654
+ "../core/dist/compiler/scriptRuns.js"() {
64655
+ "use strict";
64656
+ }
64657
+ });
64658
+
64592
64659
  // ../core/dist/compiler/externalScripts.js
64593
64660
  function readExternalScriptAttributes(el) {
64594
64661
  const attributes2 = {};
@@ -68995,6 +69062,46 @@ var require_dist = __commonJS({
68995
69062
  }
68996
69063
  });
68997
69064
 
69065
+ // ../parsers/dist/topLevelElements.js
69066
+ function isSubCompositionHost(node) {
69067
+ return node.attrs["data-composition-src"] !== void 0 || node.attrs["data-composition-id"] !== void 0;
69068
+ }
69069
+ function isTimedElement(node) {
69070
+ const { attrs } = node;
69071
+ return attrs["data-start"] !== void 0 || attrs["data-track-index"] !== void 0 && attrs["data-duration"] !== void 0 || MEDIA_TAGS.has(node.tag.toLowerCase());
69072
+ }
69073
+ function topLevelElements(root) {
69074
+ const rows = [];
69075
+ const visit = (node) => {
69076
+ if (NON_RENDERED_TAGS.has(node.tag.toLowerCase())) return;
69077
+ if (isSubCompositionHost(node) || isTimedElement(node)) rows.push(node);
69078
+ else node.children.forEach(visit);
69079
+ };
69080
+ root.children.forEach(visit);
69081
+ return rows;
69082
+ }
69083
+ function trackKindOf(node) {
69084
+ const explicit = node.attrs["data-track-kind"]?.trim().toLowerCase();
69085
+ if (explicit && TRACK_KINDS.includes(explicit))
69086
+ return { kind: explicit, source: "attribute" };
69087
+ const tag = node.tag.toLowerCase();
69088
+ if (tag === "video" || tag === "audio") return { kind: tag, source: "tag" };
69089
+ if (isSubCompositionHost(node)) {
69090
+ const legacy = node.attrs["data-composition-id"] === "captions" || /(?:^|\s)caption[-_]/.test(node.attrs.class ?? "");
69091
+ return legacy ? { kind: "captions", source: "legacy-captions" } : { kind: "graphics", source: "sub-composition" };
69092
+ }
69093
+ return { kind: "graphics", source: "tag" };
69094
+ }
69095
+ var NON_RENDERED_TAGS, MEDIA_TAGS, TRACK_KINDS;
69096
+ var init_topLevelElements = __esm({
69097
+ "../parsers/dist/topLevelElements.js"() {
69098
+ "use strict";
69099
+ NON_RENDERED_TAGS = /* @__PURE__ */ new Set(["script", "style", "template", "noscript", "link", "meta"]);
69100
+ MEDIA_TAGS = /* @__PURE__ */ new Set(["video", "audio", "img"]);
69101
+ TRACK_KINDS = ["video", "audio", "captions", "graphics"];
69102
+ }
69103
+ });
69104
+
68998
69105
  // ../parsers/dist/assetResolution.js
68999
69106
  function hasUnresolvedTemplatingToken(url) {
69000
69107
  return /<<[^<>]+>>|\{\{[^{}]+\}\}|\$\{[^{}]+\}/.test(url);
@@ -73120,6 +73227,94 @@ function extractScenesFromClips(ctx) {
73120
73227
  collectCompositionIdScenes(ctx, seen, scenes);
73121
73228
  return scenes;
73122
73229
  }
73230
+ function toNode(open) {
73231
+ const attrs = {};
73232
+ for (const name of NODE_ATTRS) attrs[name] = readDecodedAttr(open.raw, name) ?? void 0;
73233
+ return { tag: open.name, attrs, children: [], open };
73234
+ }
73235
+ function enclosing(stack, root, index) {
73236
+ let top = stack.at(-1);
73237
+ while (top && stack.length > 1 && index >= top.end) {
73238
+ stack.pop();
73239
+ top = stack.at(-1);
73240
+ }
73241
+ return top?.node ?? root;
73242
+ }
73243
+ function buildTree(ctx) {
73244
+ const { rootTag } = ctx;
73245
+ const rootEnd = rootTag?.closeIndex;
73246
+ if (!rootTag || rootEnd == null) return null;
73247
+ const root = toNode(rootTag);
73248
+ const stack = [{ node: root, end: rootEnd }];
73249
+ for (const tag of ctx.tags.filter((t) => t.index > rootTag.index && t.index < rootEnd)) {
73250
+ const node = toNode(tag);
73251
+ enclosing(stack, root, tag.index).children.push(node);
73252
+ if (tag.closeIndex != null) stack.push({ node, end: tag.closeIndex });
73253
+ }
73254
+ return root;
73255
+ }
73256
+ function hasNestedStructure(node) {
73257
+ if (OPAQUE_TAGS.has(node.tag)) return null;
73258
+ for (const child of node.children) {
73259
+ if (NON_LAYOUT_TAGS.has(child.tag)) continue;
73260
+ if (!INLINE_TEXT_TAGS.has(child.tag)) return child;
73261
+ const deeper = hasNestedStructure(child);
73262
+ if (deeper) return deeper;
73263
+ }
73264
+ return null;
73265
+ }
73266
+ function nestedStructureFindings(rows, severity) {
73267
+ return rows.flatMap((row) => {
73268
+ const nested = isSubCompositionHost(row) ? null : hasNestedStructure(row);
73269
+ if (!nested) return [];
73270
+ return [
73271
+ {
73272
+ code: "nested_structure_needs_subcomposition",
73273
+ severity,
73274
+ message: `${describe(row)} is a timeline element that contains nested ${describe(nested)}. The timeline shows one row per top-level element, and the root composition is built only from sub-compositions.`,
73275
+ elementId: row.attrs.id,
73276
+ fixHint: `Move ${describe(row)} and its contents into a sub-composition file and mount it with data-composition-src.`
73277
+ }
73278
+ ];
73279
+ });
73280
+ }
73281
+ function missingDurationFindings(rows, severity) {
73282
+ const intendedClip = (row) => !MEDIA_TAGS2.has(row.tag) || row.attrs["data-start"] !== void 0 || row.attrs["data-track-index"] !== void 0;
73283
+ return rows.filter(
73284
+ (row) => row.attrs["data-duration"] === void 0 && row.attrs["data-end"] === void 0 && !isSubCompositionHost(row) && intendedClip(row)
73285
+ ).map((row) => {
73286
+ const isMedia = MEDIA_TAGS2.has(row.tag);
73287
+ return {
73288
+ code: isMedia ? "media_missing_duration" : "timeline_element_missing_timing",
73289
+ severity,
73290
+ message: isMedia ? `${describe(row)} is media on the timeline without data-duration, so its clip has no length.` : `${describe(row)} is a timeline element without data-duration, so the timeline cannot draw where it ends.`,
73291
+ elementId: row.attrs.id,
73292
+ fixHint: `Add data-duration (in seconds) to ${describe(row)}.`
73293
+ };
73294
+ });
73295
+ }
73296
+ function captionFindings(rows, severity) {
73297
+ const captionRows = rows.filter((row) => trackKindOf(row).kind === "captions");
73298
+ const findings = captionRows.filter((row) => trackKindOf(row).source === "legacy-captions").map((row) => ({
73299
+ code: "caption_track_kind_missing",
73300
+ severity,
73301
+ message: `${describe(row)} looks like captions but is not marked as such, so the timeline cannot group it on the caption track.`,
73302
+ elementId: row.attrs.id,
73303
+ fixHint: `Add data-track-kind="captions" to ${describe(row)}.`
73304
+ }));
73305
+ const lanes = new Set(
73306
+ captionRows.flatMap((row) => row.attrs["data-track-index"] ?? row.attrs["data-track"] ?? [])
73307
+ );
73308
+ if (lanes.size > 1) {
73309
+ findings.push({
73310
+ code: "multiple_caption_tracks",
73311
+ severity,
73312
+ message: `Captions are spread across ${lanes.size} timeline tracks. Keep all captions on one track.`,
73313
+ fixHint: "Give every caption element the same data-track-index."
73314
+ });
73315
+ }
73316
+ return findings;
73317
+ }
73123
73318
  function dedupeKeyFor(finding) {
73124
73319
  return [
73125
73320
  finding.code,
@@ -73174,7 +73369,7 @@ async function lintHyperframeHtml(html, options = {}) {
73174
73369
  timings: { totalMs: performance.now() - startedAt, ...timings }
73175
73370
  };
73176
73371
  }
73177
- var import_postcss_selector_parser, COMPOSITION_ID_IN_CSS_PATTERN, TIMELINE_REGISTRY_INIT_PATTERN, TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN, TIMELINE_REGISTRY_ASSIGN_PATTERN, WINDOW_TIMELINE_ASSIGN_PATTERN, INVALID_SCRIPT_CLOSE_PATTERN, TIMELINE_REGISTRY_KEY_PATTERN, TIMELINE_REGISTRY_OBJECT_OPEN_PATTERN, TIMELINE_REGISTRY_OBJECT_ENTRY_PATTERN, REGEX_ALLOWED_BEFORE, REGEX_ALLOWED_KEYWORDS, WORD_CHAR, CodeContext, VISIBLE_MARKUP_COMMENT_PATTERN, VISIBLE_MARKUP_COMMENT_PROTECTED_BLOCK_PATTERN, coreRules, IMAGE_SRC_EXT, VIDEO_SRC_EXT, AUDIO_SRC_EXT, SRC_KIND_NOUN, mediaRules, AUDIO_GROUP_TIMING_ATTRS, MAX_COMPOSITION_LINES, MAX_TIMED_ELEMENTS_PER_TRACK, TRACK_DENSITY_EXEMPT_TAGS, CAPTION_CUE_TOKEN, HEAVY_OVERLAY_ELEMENT_COUNT_WARN, HEAVY_OVERLAY_EXEMPT_TAGS, HEAVY_OVERLAY_CSS_PATTERN, INLINE_STYLE_DISPLAY_NONE_PATTERN, compositionRules, SCENE_BOUNDARY_EPSILON_SECONDS, UNRESOLVED_TARGET, gsapWindowsCache, CONFLICTING_TRANSLATE_PROPS, CONFLICTING_SCALE_PROPS, RELATIVE_TWEEN_VALUE, TRANSFORM_SENSITIVE_READ, TRANSFORM_INVARIANT_READ, CALLBACK_MEASUREMENT_PATTERN, NUMBER_METHODS, gsapRules, captionRules, adapterRules, TEXTURE_BASE_CLASS, TEXTURE_CLASS_PREFIX, textureRules, GENERIC_FAMILIES, fontRules, slideshowRules, RULE_GROUPS, LINT_RULE_COUNT, LINT_RULE_GROUP_COUNTS;
73372
+ var import_postcss_selector_parser, COMPOSITION_ID_IN_CSS_PATTERN, TIMELINE_REGISTRY_INIT_PATTERN, TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN, TIMELINE_REGISTRY_ASSIGN_PATTERN, WINDOW_TIMELINE_ASSIGN_PATTERN, INVALID_SCRIPT_CLOSE_PATTERN, TIMELINE_REGISTRY_KEY_PATTERN, TIMELINE_REGISTRY_OBJECT_OPEN_PATTERN, TIMELINE_REGISTRY_OBJECT_ENTRY_PATTERN, REGEX_ALLOWED_BEFORE, REGEX_ALLOWED_KEYWORDS, WORD_CHAR, CodeContext, VISIBLE_MARKUP_COMMENT_PATTERN, VISIBLE_MARKUP_COMMENT_PROTECTED_BLOCK_PATTERN, coreRules, IMAGE_SRC_EXT, VIDEO_SRC_EXT, AUDIO_SRC_EXT, SRC_KIND_NOUN, mediaRules, AUDIO_GROUP_TIMING_ATTRS, MAX_COMPOSITION_LINES, MAX_TIMED_ELEMENTS_PER_TRACK, TRACK_DENSITY_EXEMPT_TAGS, CAPTION_CUE_TOKEN, HEAVY_OVERLAY_ELEMENT_COUNT_WARN, HEAVY_OVERLAY_EXEMPT_TAGS, HEAVY_OVERLAY_CSS_PATTERN, INLINE_STYLE_DISPLAY_NONE_PATTERN, compositionRules, SCENE_BOUNDARY_EPSILON_SECONDS, UNRESOLVED_TARGET, gsapWindowsCache, CONFLICTING_TRANSLATE_PROPS, CONFLICTING_SCALE_PROPS, RELATIVE_TWEEN_VALUE, TRANSFORM_SENSITIVE_READ, TRANSFORM_INVARIANT_READ, CALLBACK_MEASUREMENT_PATTERN, NUMBER_METHODS, gsapRules, captionRules, adapterRules, TEXTURE_BASE_CLASS, TEXTURE_CLASS_PREFIX, textureRules, GENERIC_FAMILIES, fontRules, slideshowRules, INLINE_TEXT_TAGS, OPAQUE_TAGS, NON_LAYOUT_TAGS, MEDIA_TAGS2, NODE_ATTRS, describe, structureRules, RULE_GROUPS, LINT_RULE_COUNT, LINT_RULE_GROUP_COUNTS;
73178
73373
  var init_dist3 = __esm({
73179
73374
  "../lint/dist/index.js"() {
73180
73375
  "use strict";
@@ -73188,6 +73383,7 @@ var init_dist3 = __esm({
73188
73383
  init_compositionContract();
73189
73384
  init_composition();
73190
73385
  init_slideshow();
73386
+ init_topLevelElements();
73191
73387
  init_esm10();
73192
73388
  init_esm10();
73193
73389
  COMPOSITION_ID_IN_CSS_PATTERN = /\[data-composition-id=["']([^"']+)["']\]/g;
@@ -76263,6 +76459,64 @@ ${other.raw}`)
76263
76459
  return findings;
76264
76460
  }
76265
76461
  ];
76462
+ INLINE_TEXT_TAGS = /* @__PURE__ */ new Set([
76463
+ "br",
76464
+ "wbr",
76465
+ "b",
76466
+ "i",
76467
+ "u",
76468
+ "s",
76469
+ "em",
76470
+ "strong",
76471
+ "small",
76472
+ "sub",
76473
+ "sup",
76474
+ "mark",
76475
+ "span",
76476
+ "a",
76477
+ "code",
76478
+ "abbr"
76479
+ ]);
76480
+ OPAQUE_TAGS = /* @__PURE__ */ new Set([
76481
+ "svg",
76482
+ "canvas",
76483
+ "picture",
76484
+ "video",
76485
+ "audio",
76486
+ "select",
76487
+ "textarea",
76488
+ "iframe",
76489
+ "object"
76490
+ ]);
76491
+ NON_LAYOUT_TAGS = /* @__PURE__ */ new Set(["style", "script", "template", "noscript"]);
76492
+ MEDIA_TAGS2 = /* @__PURE__ */ new Set(["img", "video", "audio"]);
76493
+ NODE_ATTRS = [
76494
+ "id",
76495
+ "class",
76496
+ "data-start",
76497
+ "data-duration",
76498
+ "data-end",
76499
+ "data-track",
76500
+ "data-track-index",
76501
+ "data-track-kind",
76502
+ "data-composition-id",
76503
+ "data-composition-src"
76504
+ ];
76505
+ describe = (node) => `<${node.tag}${node.attrs.id ? ` id="${node.attrs.id}"` : ""}>`;
76506
+ structureRules = [
76507
+ (ctx) => {
76508
+ if (ctx.options.isSubComposition) return [];
76509
+ const root = buildTree(ctx);
76510
+ if (!root) return [];
76511
+ const severity = ctx.options.host === "studio" ? "error" : "warning";
76512
+ const rows = topLevelElements(root);
76513
+ return [
76514
+ ...nestedStructureFindings(rows, severity),
76515
+ ...missingDurationFindings(rows, severity),
76516
+ ...captionFindings(rows, severity)
76517
+ ];
76518
+ }
76519
+ ];
76266
76520
  RULE_GROUPS = [
76267
76521
  { group: "core", rules: coreRules },
76268
76522
  { group: "media", rules: mediaRules },
@@ -76272,7 +76526,8 @@ ${other.raw}`)
76272
76526
  { group: "adapters", rules: adapterRules },
76273
76527
  { group: "textures", rules: textureRules },
76274
76528
  { group: "fonts", rules: fontRules },
76275
- { group: "slideshow", rules: slideshowRules }
76529
+ { group: "slideshow", rules: slideshowRules },
76530
+ { group: "structure", rules: structureRules }
76276
76531
  ];
76277
76532
  LINT_RULE_COUNT = RULE_GROUPS.reduce((n, g) => n + g.rules.length, 0);
76278
76533
  LINT_RULE_GROUP_COUNTS = Object.fromEntries(
@@ -76714,6 +76969,7 @@ var MAX_INLINE_ASSET_BYTES;
76714
76969
  var init_htmlBundler = __esm({
76715
76970
  "../core/dist/compiler/htmlBundler.js"() {
76716
76971
  "use strict";
76972
+ init_scriptRuns();
76717
76973
  init_externalScripts();
76718
76974
  init_flattenedRoot();
76719
76975
  init_flattenedRoot();
@@ -76754,6 +77010,7 @@ var init_compiler = __esm({
76754
77010
  init_getVariables();
76755
77011
  init_htmlParityContract();
76756
77012
  init_htmlDocument();
77013
+ init_scriptRuns();
76757
77014
  init_staticGuard();
76758
77015
  init_compositionScoping();
76759
77016
  init_inlineSubCompositions();
@@ -82554,6 +82811,7 @@ __export(src_exports, {
82554
82811
  TRANSITIONS: () => TRANSITIONS,
82555
82812
  VIDEO_FRAME_FORMATS: () => VIDEO_FRAME_FORMATS,
82556
82813
  VideoSourceExtractionError: () => VideoSourceExtractionError,
82814
+ WebGpuUnavailableError: () => WebGpuUnavailableError,
82557
82815
  acquireBrowser: () => acquireBrowser,
82558
82816
  analyzeClipMediaFit: () => analyzeClipMediaFit,
82559
82817
  analyzeCompositionHdr: () => analyzeCompositionHdr,
@@ -82566,6 +82824,7 @@ __export(src_exports, {
82566
82824
  assertMediaPayload: () => assertMediaPayload,
82567
82825
  assertPublicHttpsUrl: () => assertPublicHttpsUrl,
82568
82826
  assertSwiftShader: () => assertSwiftShader,
82827
+ assertWebGpuAdapterAvailable: () => assertWebGpuAdapterAvailable,
82569
82828
  augmentPageNavigationTimeoutError: () => augmentPageNavigationTimeoutError,
82570
82829
  augmentProtocolTimeoutError: () => augmentProtocolTimeoutError,
82571
82830
  beginFrameCapture: () => beginFrameCapture,
@@ -82589,6 +82848,7 @@ __export(src_exports, {
82589
82848
  cloneCaptureWarnings: () => cloneCaptureWarnings,
82590
82849
  closeCaptureSession: () => closeCaptureSession,
82591
82850
  completeDeferredDrawElementInit: () => completeDeferredDrawElementInit,
82851
+ compositionRequiresWebGpu: () => compositionRequiresWebGpu,
82592
82852
  computeWorkerSizing: () => computeWorkerSizing,
82593
82853
  convertTransfer: () => convertTransfer,
82594
82854
  createCaptureSession: () => createCaptureSession,
@@ -91297,22 +91557,16 @@ function coalesceHeadStylesAndBodyScripts(html) {
91297
91557
  }
91298
91558
  }
91299
91559
  if (body) {
91300
- const bodyScripts = Array.from(body.querySelectorAll("script")).filter((el) => {
91301
- const src = (el.getAttribute("src") || "").trim();
91302
- if (src) return false;
91303
- const type = (el.getAttribute("type") || "").trim().toLowerCase();
91304
- return !type || type === "text/javascript" || type === "application/javascript";
91305
- });
91306
- if (bodyScripts.length > 0) {
91307
- const mergedJs = bodyScripts.map((el) => (el.textContent || "").trim()).filter(Boolean).join("\n;\n").trim();
91308
- for (const el of bodyScripts) {
91309
- el.remove();
91310
- }
91311
- if (mergedJs) {
91312
- const script = document2.createElement("script");
91313
- script.textContent = mergedJs;
91314
- body.appendChild(script);
91315
- }
91560
+ for (const { members, anchor } of inlineScriptRuns(
91561
+ Array.from(body.querySelectorAll("script"))
91562
+ )) {
91563
+ const mergedJs = members.map((el) => (el.textContent || "").trim()).filter(Boolean).join("\n;\n").trim();
91564
+ for (const el of members) el.remove();
91565
+ if (!mergedJs) continue;
91566
+ const script = document2.createElement("script");
91567
+ script.textContent = mergedJs;
91568
+ if (anchor) anchor.before(script);
91569
+ else body.appendChild(script);
91316
91570
  }
91317
91571
  }
91318
91572
  return document2.toString();
@@ -92675,7 +92929,8 @@ async function runProbeStage(input) {
92675
92929
  quality: captureFormat === "png" ? void 0 : 80,
92676
92930
  variables: job.config.variables,
92677
92931
  deviceScaleFactor,
92678
- motionBlur
92932
+ motionBlur,
92933
+ requiresWebGpu: compositionRequiresWebGpu(compiled.html)
92679
92934
  };
92680
92935
  const PROBE_MAX_ATTEMPTS = 2;
92681
92936
  for (let attempt = 1; attempt <= PROBE_MAX_ATTEMPTS; attempt++) {
@@ -98366,7 +98621,8 @@ async function executeRenderPipeline(input) {
98366
98621
  skipReadinessVideoIds: videoReadinessSkipIds,
98367
98622
  // Probe-resolved duration: drawElement self-verification derives its
98368
98623
  // sample frame indices from this so they land inside the drained range.
98369
- compositionDurationSeconds: job.duration
98624
+ compositionDurationSeconds: job.duration,
98625
+ requiresWebGpu: compositionRequiresWebGpu(compiled.html)
98370
98626
  });
98371
98627
  const createRenderVideoFrameInjector = () => createVideoFrameInjector(frameLookup, {
98372
98628
  frameDataUriCacheLimit: cfg.frameDataUriCacheLimit,
@@ -100717,8 +100973,8 @@ async function runFontLocalize(io, localize) {
100717
100973
  }
100718
100974
 
100719
100975
  // src/version.ts
100720
- var VERSION = true ? "0.8.49" : "0.0.0-dev";
100721
- var PRODUCER_VERSION = true ? "0.8.49" : "0.0.0-dev";
100976
+ var VERSION = true ? "0.8.50" : "0.0.0-dev";
100977
+ var PRODUCER_VERSION = true ? "0.8.50" : "0.0.0-dev";
100722
100978
 
100723
100979
  // src/fontLocalizeCli.ts
100724
100980
  async function readStdin() {
@@ -1,4 +1,4 @@
1
- "use strict";var HyperframesPlayer=(()=>{var ee=Object.defineProperty;var ot=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var at=Object.prototype.hasOwnProperty;var dt=(r,e)=>{for(var t in e)ee(r,t,{get:e[t],enumerable:!0})},lt=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of st(e))!at.call(r,n)&&n!==t&&ee(r,n,{get:()=>e[n],enumerable:!(i=ot(e,n))||i.enumerable});return r};var ut=r=>lt(ee({},"__esModule",{value:!0}),r);var Kt={};dt(Kt,{HyperframesPlayer:()=>K,SPEED_PRESETS:()=>re,formatSpeed:()=>N,formatTime:()=>G});function ke(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function P(r){return typeof r=="object"&&r!==null}function xe(r){return P(r)&&typeof r.getDuration=="function"}function Me(r){return P(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}var k="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.8.49/dist/hyperframe.runtime.iife.js";function O(r){if(r===null)return null;let e=Number.parseInt(r,10);return Number.isFinite(e)&&e>0?e:null}function ct(r){let e=r?.querySelector("[data-composition-id][data-width][data-height]")??r?.querySelector("[data-width][data-height]");if(!e)return null;let t=O(e.getAttribute("data-width")),i=O(e.getAttribute("data-height"));return t!==null&&i!==null?{width:t,height:i}:null}var q=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 i=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(ke({hasRuntime:i,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!i)return;let s=this._resolvePlaybackDurationAdapter(t);if(s&&s.getDuration()>0){this.stop();let a=ct(this._iframe.contentDocument);this._callbacks.onReady({duration:s.getDuration(),adapter:s,compositionSize:a});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||P(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=k,(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(!P(t))return null;let i=Object.keys(t);if(i.length===0)return null;let n=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=n&&n in t?n:i[i.length-1],s=t[o];return Me(s)?s:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(xe(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let i=this._resolveDirectTimelineAdapterFromWindow(e);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}};var Le=`
1
+ "use strict";var HyperframesPlayer=(()=>{var ee=Object.defineProperty;var ot=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var at=Object.prototype.hasOwnProperty;var dt=(r,e)=>{for(var t in e)ee(r,t,{get:e[t],enumerable:!0})},lt=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of st(e))!at.call(r,n)&&n!==t&&ee(r,n,{get:()=>e[n],enumerable:!(i=ot(e,n))||i.enumerable});return r};var ut=r=>lt(ee({},"__esModule",{value:!0}),r);var Kt={};dt(Kt,{HyperframesPlayer:()=>K,SPEED_PRESETS:()=>re,formatSpeed:()=>N,formatTime:()=>G});function ke(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function P(r){return typeof r=="object"&&r!==null}function xe(r){return P(r)&&typeof r.getDuration=="function"}function Me(r){return P(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}var k="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.8.50/dist/hyperframe.runtime.iife.js";function O(r){if(r===null)return null;let e=Number.parseInt(r,10);return Number.isFinite(e)&&e>0?e:null}function ct(r){let e=r?.querySelector("[data-composition-id][data-width][data-height]")??r?.querySelector("[data-width][data-height]");if(!e)return null;let t=O(e.getAttribute("data-width")),i=O(e.getAttribute("data-height"));return t!==null&&i!==null?{width:t,height:i}:null}var q=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 i=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(ke({hasRuntime:i,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!i)return;let s=this._resolvePlaybackDurationAdapter(t);if(s&&s.getDuration()>0){this.stop();let a=ct(this._iframe.contentDocument);this._callbacks.onReady({duration:s.getDuration(),adapter:s,compositionSize:a});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||P(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=k,(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(!P(t))return null;let i=Object.keys(t);if(i.length===0)return null;let n=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=n&&n in t?n:i[i.length-1],s=t[o];return Me(s)?s:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(xe(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let i=this._resolveDirectTimelineAdapterFromWindow(e);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}};var Le=`
2
2
  :host {
3
3
  display: block;
4
4
  position: relative;