hyperframes 0.8.65 → 0.8.67

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.
@@ -12773,10 +12773,10 @@ function resolveSlideshow(manifest, scenes) {
12773
12773
  return { resolved: { slides, sequences }, errors };
12774
12774
  }
12775
12775
  function isSceneLikeCompositionId(compositionId) {
12776
- const normalized = compositionId.trim().toLowerCase();
12777
- if (!normalized || normalized === "main") return false;
12778
- if (normalized.includes("caption")) return false;
12779
- if (normalized.includes("ambient")) return false;
12776
+ const normalized2 = compositionId.trim().toLowerCase();
12777
+ if (!normalized2 || normalized2 === "main") return false;
12778
+ if (normalized2.includes("caption")) return false;
12779
+ if (normalized2.includes("ambient")) return false;
12780
12780
  return true;
12781
12781
  }
12782
12782
  var SLIDESHOW_ISLAND_TYPE;
@@ -50616,14 +50616,14 @@ function parseReferenceOffset(value) {
50616
50616
  return { refId, operator, magnitude };
50617
50617
  }
50618
50618
  function parseStartExpression(raw) {
50619
- const normalized = (raw ?? "").trim();
50620
- if (!normalized) return null;
50621
- const absolute = parseNumeric(normalized);
50619
+ const normalized2 = (raw ?? "").trim();
50620
+ if (!normalized2) return null;
50621
+ const absolute = parseNumeric(normalized2);
50622
50622
  if (absolute != null) return { kind: "absolute", value: absolute };
50623
- if (REFERENCE_ID_PATTERN.test(normalized)) {
50624
- return { kind: "reference", refId: normalized, offset: 0 };
50623
+ if (REFERENCE_ID_PATTERN.test(normalized2)) {
50624
+ return { kind: "reference", refId: normalized2, offset: 0 };
50625
50625
  }
50626
- const reference = parseReferenceOffset(normalized);
50626
+ const reference = parseReferenceOffset(normalized2);
50627
50627
  if (!reference) return null;
50628
50628
  return {
50629
50629
  kind: "reference",
@@ -52584,8 +52584,8 @@ function rewriteAssetPath(compSrcPath, relativePath, assetExists) {
52584
52584
  return assetExists(sibling2) ? sibling2 + suffix : relativePath;
52585
52585
  }
52586
52586
  const resolved = join(compDir, relativePath);
52587
- const normalized = resolve2("/", resolved).slice(1);
52588
- return normalized;
52587
+ const normalized2 = resolve2("/", resolved).slice(1);
52588
+ return normalized2;
52589
52589
  }
52590
52590
  function rewriteAssetPaths(elements, compSrcPath, getAttr2, setAttr2, assetExists) {
52591
52591
  for (const el of elements) {
@@ -52647,6 +52647,14 @@ var init_assetPaths = __esm({
52647
52647
  });
52648
52648
 
52649
52649
  // ../parsers/dist/subCompositionValidity.js
52650
+ function resolveSubCompositionContent(html, document2) {
52651
+ const template = document2.querySelector("template");
52652
+ if (template) return { contentHtml: template.innerHTML ?? "", hasTemplate: true };
52653
+ const body = document2.querySelector("body");
52654
+ if (body) return { contentHtml: body.innerHTML ?? "", hasTemplate: false };
52655
+ const contentHtml = document2.querySelector("html") ? "" : html;
52656
+ return { contentHtml, hasTemplate: false };
52657
+ }
52650
52658
  function checkSubCompositionUsability(html, parseHtml) {
52651
52659
  if (html == null || !html.trim()) {
52652
52660
  return {
@@ -52663,8 +52671,7 @@ function checkSubCompositionUsability(html, parseHtml) {
52663
52671
  detail: "the file's contents could not be parsed as HTML"
52664
52672
  };
52665
52673
  }
52666
- const contentRoot = compDoc.querySelector("template");
52667
- const contentHtml = contentRoot ? contentRoot.innerHTML || "" : compDoc.body?.innerHTML || "";
52674
+ const { contentHtml } = resolveSubCompositionContent(html, compDoc);
52668
52675
  if (!contentHtml.trim()) {
52669
52676
  return {
52670
52677
  ok: false,
@@ -52677,14 +52684,14 @@ function checkSubCompositionUsability(html, parseHtml) {
52677
52684
  return {
52678
52685
  ok: false,
52679
52686
  reason: "unparsable",
52680
- detail: "the file's <template>/<body> contents could not be parsed as HTML"
52687
+ detail: "the file's resolved contents could not be parsed as HTML"
52681
52688
  };
52682
52689
  }
52683
52690
  if (!contentDoc.querySelector("[data-composition-id]")) {
52684
52691
  return {
52685
52692
  ok: false,
52686
52693
  reason: "no-composition-root",
52687
- detail: "the file's <template>/<body> content has no element with a data-composition-id attribute"
52694
+ detail: "the file's resolved content has no element with a data-composition-id attribute"
52688
52695
  };
52689
52696
  }
52690
52697
  return { ok: true };
@@ -55359,8 +55366,8 @@ function resolveExtractCacheDir(env = process.env) {
55359
55366
  if (raw === void 0) {
55360
55367
  return { dir: defaultExtractCacheDir(), disabled: false, source: "default" };
55361
55368
  }
55362
- const normalized = raw.trim().toLowerCase();
55363
- if (EXTRACT_CACHE_DIR_DISABLED_ALIASES.includes(normalized)) {
55369
+ const normalized2 = raw.trim().toLowerCase();
55370
+ if (EXTRACT_CACHE_DIR_DISABLED_ALIASES.includes(normalized2)) {
55364
55371
  return { dir: void 0, disabled: true, source: "env", rawValue: raw };
55365
55372
  }
55366
55373
  return { dir: raw, disabled: false, source: "env", rawValue: raw };
@@ -59347,8 +59354,8 @@ function candidateFileName(candidate) {
59347
59354
  return candidate.split(/[\\/]/).at(-1)?.toLowerCase() ?? candidate.toLowerCase();
59348
59355
  }
59349
59356
  function chooseBestPathCandidate(name, candidates) {
59350
- const normalized = candidates.map((candidate) => candidate.trim()).filter(Boolean);
59351
- return normalized.find((candidate) => candidateFileName(candidate) === `${name}.exe`) ?? normalized.find((candidate) => candidateFileName(candidate) === name) ?? normalized.find((candidate) => !candidateFileName(candidate).match(/\.(cmd|bat)$/i)) ?? normalized[0];
59357
+ const normalized2 = candidates.map((candidate) => candidate.trim()).filter(Boolean);
59358
+ return normalized2.find((candidate) => candidateFileName(candidate) === `${name}.exe`) ?? normalized2.find((candidate) => candidateFileName(candidate) === name) ?? normalized2.find((candidate) => !candidateFileName(candidate).match(/\.(cmd|bat)$/i)) ?? normalized2[0];
59352
59359
  }
59353
59360
  function isExecutablePathCandidate(candidate) {
59354
59361
  if (process.platform === "win32") return existsSync3(candidate);
@@ -59700,8 +59707,8 @@ function matchesAny(message, patterns) {
59700
59707
  return patterns.some((pattern) => pattern.test(message));
59701
59708
  }
59702
59709
  function hasIoOperationFailure(message) {
59703
- const normalized = message.toLowerCase();
59704
- return normalized.split(/[\r\n]/).some(
59710
+ const normalized2 = message.toLowerCase();
59711
+ return normalized2.split(/[\r\n]/).some(
59705
59712
  (line) => IO_OPERATION_TOKENS.some((operation) => {
59706
59713
  const operationIndex = line.indexOf(operation);
59707
59714
  if (operationIndex < 0) return false;
@@ -65293,15 +65300,15 @@ function looksLikeRemoteErrorDocument(prefix) {
65293
65300
  }
65294
65301
  function normalizeCallerSha256(value) {
65295
65302
  if (value === void 0) return void 0;
65296
- const normalized = value.trim().toLowerCase();
65297
- if (!/^[a-f0-9]{64}$/.test(normalized)) {
65303
+ const normalized2 = value.trim().toLowerCase();
65304
+ if (!/^[a-f0-9]{64}$/.test(normalized2)) {
65298
65305
  throw new UrlDownloadError(
65299
65306
  "hash_mismatch",
65300
65307
  false,
65301
65308
  "Caller-provided SHA-256 checksum is malformed"
65302
65309
  );
65303
65310
  }
65304
- return normalized;
65311
+ return normalized2;
65305
65312
  }
65306
65313
  function expectedResponseSha256(response, callerSha256) {
65307
65314
  if (callerSha256) return { value: callerSha256, encoding: "hex", source: "caller" };
@@ -65406,7 +65413,7 @@ async function fetchToPartial(url, partialPath, controller, options) {
65406
65413
  });
65407
65414
  const readableStream = Readable.fromWeb(response.body);
65408
65415
  const fileStream = createWriteStream(partialPath, { flags: "wx" });
65409
- await pipeline(readableStream, inspector, fileStream);
65416
+ await pipeline(readableStream, inspector, fileStream, { signal: controller.signal });
65410
65417
  const localSize = statSync4(partialPath).size;
65411
65418
  const sha256Bytes = sha256.digest();
65412
65419
  const localSha256 = sha256Bytes.toString("hex");
@@ -65965,13 +65972,13 @@ function resolveAliasDisplayName2(alias) {
65965
65972
  return CANONICAL_FONT_DISPLAY_NAMES2[slug];
65966
65973
  }
65967
65974
  function isSafeMediaUrl(url) {
65968
- const normalized = url.replace(/[\u0000-\u0020]/g, "");
65969
- const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(normalized);
65975
+ const normalized2 = url.replace(/[\u0000-\u0020]/g, "");
65976
+ const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(normalized2);
65970
65977
  if (!scheme) return true;
65971
65978
  const proto = scheme[1]?.toLowerCase();
65972
65979
  if (!proto) return false;
65973
65980
  if (proto === "https" || proto === "http" || proto === "blob") return true;
65974
- if (proto === "data") return /^data:image\//i.test(normalized);
65981
+ if (proto === "data") return /^data:image\//i.test(normalized2);
65975
65982
  return false;
65976
65983
  }
65977
65984
  var CANVAS_DIMENSIONS2, VALID_CANVAS_RESOLUTIONS2, COMPOSITION_VARIABLE_TYPES2, FONT_ALIAS_MAP2, FONT_ALIAS_KEYS2, CANONICAL_FONT_DISPLAY_NAMES2, COMPOSITION_ATTRIBUTES4, CANONICAL_AUTHORED_TIMING_ATTRIBUTES4, DERIVED_TIMING_ATTRIBUTES4, LEGACY_TIMING_ATTRIBUTES4;
@@ -72813,10 +72820,60 @@ function hasCaptionStyles(styles) {
72813
72820
  return styles.some((s) => /\.caption[-_]?(?:group|word)/i.test(s.content));
72814
72821
  }
72815
72822
  function truncateSnippet(value, maxLength = 220) {
72816
- const normalized = value.replace(/\s+/g, " ").trim();
72817
- if (!normalized) return void 0;
72818
- if (normalized.length <= maxLength) return normalized;
72819
- return `${normalized.slice(0, maxLength - 3)}...`;
72823
+ const normalized2 = value.replace(/\s+/g, " ").trim();
72824
+ if (!normalized2) return void 0;
72825
+ if (normalized2.length <= maxLength) return normalized2;
72826
+ return `${normalized2.slice(0, maxLength - 3)}...`;
72827
+ }
72828
+ function normalized(source) {
72829
+ let text = "";
72830
+ const offsets = [];
72831
+ for (let i = 0; i < source.length; i++) {
72832
+ const char = source[i];
72833
+ if (/\s/.test(char)) {
72834
+ if (text.endsWith(" ")) continue;
72835
+ text += " ";
72836
+ } else text += char;
72837
+ offsets.push(i);
72838
+ }
72839
+ return { text, offsets };
72840
+ }
72841
+ function createSourceLocator(source) {
72842
+ const tags = parseHtmlStructure(source).tags;
72843
+ const searchable = source.split("");
72844
+ const parser = new Parser({
72845
+ oncomment() {
72846
+ searchable.fill("\0", parser.startIndex, parser.endIndex + 1);
72847
+ }
72848
+ });
72849
+ parser.write(source);
72850
+ parser.end();
72851
+ const normalizedSource = normalized(searchable.join(""));
72852
+ const at2 = (offset3) => {
72853
+ const before2 = source.slice(0, offset3);
72854
+ return {
72855
+ line: before2.split(/\r\n|\r|\n/).length,
72856
+ column: offset3 - Math.max(before2.lastIndexOf("\n"), before2.lastIndexOf("\r"))
72857
+ };
72858
+ };
72859
+ return (finding) => {
72860
+ if (finding.line !== void 0) return { line: finding.line, column: finding.column };
72861
+ if (finding.snippet) {
72862
+ const offset3 = snippetOffset(normalizedSource, finding.snippet);
72863
+ return offset3 === void 0 ? {} : at2(offset3);
72864
+ }
72865
+ const id = finding.elementId ?? /^#([\w-]+)$/.exec(finding.selector ?? "")?.[1];
72866
+ if (!id) return {};
72867
+ const matches2 = tags.filter((tag) => readDecodedAttr(tag.raw, "id") === id);
72868
+ return matches2.length === 1 ? at2(matches2[0].index) : {};
72869
+ };
72870
+ }
72871
+ function snippetOffset(source, snippet) {
72872
+ const needle = snippet.replace(/\s+/g, " ").trim().replace(/\.\.\.$/, "");
72873
+ if (!needle) return void 0;
72874
+ const index = source.text.indexOf(needle);
72875
+ if (index < 0 || source.text.indexOf(needle, index + 1) >= 0) return void 0;
72876
+ return source.offsets[index];
72820
72877
  }
72821
72878
  function buildLintContext(html, options = {}) {
72822
72879
  const rawSource = html || "";
@@ -73196,18 +73253,18 @@ function classNamesFromAttr(classAttr) {
73196
73253
  return classAttr.split(/\s+/).filter(Boolean);
73197
73254
  }
73198
73255
  function selectorTargetsManagedMedia(selector, mediaIndex) {
73199
- const normalized = selector.trim();
73200
- if (!normalized) return false;
73201
- if (mediaIndex.hasVideo && /\bvideo\b/i.test(normalized)) return true;
73202
- if (mediaIndex.hasAudio && /\baudio\b/i.test(normalized)) return true;
73256
+ const normalized2 = selector.trim();
73257
+ if (!normalized2) return false;
73258
+ if (mediaIndex.hasVideo && /\bvideo\b/i.test(normalized2)) return true;
73259
+ if (mediaIndex.hasAudio && /\baudio\b/i.test(normalized2)) return true;
73203
73260
  for (const mediaId of mediaIndex.ids) {
73204
73261
  const escapedId = escapeRegExp3(mediaId);
73205
- if (new RegExp(`#${escapedId}(?![\\w-])`).test(normalized) || normalized.includes(`[id="${mediaId}"]`) || normalized.includes(`[id='${mediaId}']`)) {
73262
+ if (new RegExp(`#${escapedId}(?![\\w-])`).test(normalized2) || normalized2.includes(`[id="${mediaId}"]`) || normalized2.includes(`[id='${mediaId}']`)) {
73206
73263
  return true;
73207
73264
  }
73208
73265
  }
73209
73266
  for (const className of mediaIndex.classes) {
73210
- if (new RegExp(`\\.${escapeRegExp3(className)}(?![\\w-])`).test(normalized)) {
73267
+ if (new RegExp(`\\.${escapeRegExp3(className)}(?![\\w-])`).test(normalized2)) {
73211
73268
  return true;
73212
73269
  }
73213
73270
  }
@@ -73525,8 +73582,8 @@ function readTagTiming(rawTag) {
73525
73582
  }
73526
73583
  function countPhysicalLines(source) {
73527
73584
  if (source.length === 0) return 0;
73528
- const normalized = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
73529
- const withoutFinalNewline = normalized.endsWith("\n") ? normalized.slice(0, -1) : normalized;
73585
+ const normalized2 = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
73586
+ const withoutFinalNewline = normalized2.endsWith("\n") ? normalized2.slice(0, -1) : normalized2;
73530
73587
  return withoutFinalNewline.split("\n").length;
73531
73588
  }
73532
73589
  function countStructuralLines(source) {
@@ -73539,8 +73596,8 @@ function isCaptionCue(tag) {
73539
73596
  }
73540
73597
  function isRegistrySourceFile(filePath) {
73541
73598
  if (!filePath) return false;
73542
- const normalized = filePath.replace(/\\/g, "/");
73543
- return /(?:^|\/)registry\/blocks\/([^/]+)\/\1\.html$/i.test(normalized);
73599
+ const normalized2 = filePath.replace(/\\/g, "/");
73600
+ return /(?:^|\/)registry\/blocks\/([^/]+)\/\1\.html$/i.test(normalized2);
73544
73601
  }
73545
73602
  function isRegistryInstalledFile(rawSource) {
73546
73603
  return /^\s*<!--\s*hyperframes-registry-item:[^>]*-->/i.test(rawSource.slice(0, 512));
@@ -73773,8 +73830,8 @@ function zeroValue(value) {
73773
73830
  return Number(value.trim()) === 0;
73774
73831
  }
73775
73832
  function isGsapColorProperty(property) {
73776
- const normalized = property.toLowerCase();
73777
- return !normalized.startsWith("--") && (normalized.endsWith("color") || normalized === "fill" || normalized === "stroke");
73833
+ const normalized2 = property.toLowerCase();
73834
+ return !normalized2.startsWith("--") && (normalized2.endsWith("color") || normalized2 === "fill" || normalized2 === "stroke");
73778
73835
  }
73779
73836
  function collectStaticCssVariableDefinitions(tags, styles) {
73780
73837
  const definitions = /* @__PURE__ */ new Set();
@@ -73901,10 +73958,10 @@ function styleHasHiddenInitialState(style) {
73901
73958
  function styleHasOpaqueBackground(style) {
73902
73959
  const background = readStyleProperty(style, "background") || readStyleProperty(style, "background-color");
73903
73960
  if (!background) return false;
73904
- const normalized = background.toLowerCase().replace(/\s+/g, "");
73905
- if (normalized === "transparent" || normalized === "none") return false;
73906
- if (/rgba?\([^)]*,0(?:\.0+)?\)$/.test(normalized)) return false;
73907
- if (/hsla?\([^)]*,0(?:\.0+)?\)$/.test(normalized)) return false;
73961
+ const normalized2 = background.toLowerCase().replace(/\s+/g, "");
73962
+ if (normalized2 === "transparent" || normalized2 === "none") return false;
73963
+ if (/rgba?\([^)]*,0(?:\.0+)?\)$/.test(normalized2)) return false;
73964
+ if (/hsla?\([^)]*,0(?:\.0+)?\)$/.test(normalized2)) return false;
73908
73965
  return true;
73909
73966
  }
73910
73967
  function styleLooksFullFrameOverlay(style) {
@@ -74272,9 +74329,9 @@ function elementLevelTokens(tokens, tagsByToken) {
74272
74329
  return expanded;
74273
74330
  }
74274
74331
  function isMultiComponentDasharray(value) {
74275
- const normalized = value.replace(/!important\s*$/i, "").trim();
74276
- if (!normalized || /^none$/i.test(normalized)) return false;
74277
- return normalized.split(/[\s,]+/).filter(Boolean).length >= 2;
74332
+ const normalized2 = value.replace(/!important\s*$/i, "").trim();
74333
+ if (!normalized2 || /^none$/i.test(normalized2)) return false;
74334
+ return normalized2.split(/[\s,]+/).filter(Boolean).length >= 2;
74278
74335
  }
74279
74336
  function gsapDasharrayValueLooksMultiComponent(valueSource) {
74280
74337
  const literal2 = valueSource.trim().match(/^(["'`])([\s\S]*)\1$/)?.[2];
@@ -74683,7 +74740,15 @@ function collectFindings(produced, seen, filePath, into) {
74683
74740
  async function lintHyperframeHtml(html, options = {}) {
74684
74741
  const startedAt = performance.now();
74685
74742
  const ctx = buildLintContext(html, options);
74686
- const { findings, timings } = await runRules(ctx, options.filePath);
74743
+ const { findings: rawFindings, timings } = await runRules(ctx, options.filePath);
74744
+ const locate = createSourceLocator(html);
74745
+ const findings = rawFindings.map((finding) => {
74746
+ if (finding.snippet && options.externalStyles?.some(
74747
+ (style) => style.content.replace(/\s+/g, " ").includes(finding.snippet.replace(/\.\.\.$/, ""))
74748
+ ))
74749
+ return finding;
74750
+ return { ...finding, ...locate(finding) };
74751
+ });
74687
74752
  const errorCount = findings.filter((f) => f.severity === "error").length;
74688
74753
  const warningCount = findings.filter((f) => f.severity === "warning").length;
74689
74754
  const infoCount = findings.filter((f) => f.severity === "info").length;
@@ -74701,6 +74766,7 @@ var init_dist3 = __esm({
74701
74766
  "../lint/dist/index.js"() {
74702
74767
  "use strict";
74703
74768
  init_esm6();
74769
+ init_esm6();
74704
74770
  import_postcss_selector_parser = __toESM(require_dist(), 1);
74705
74771
  init_dist();
74706
74772
  init_colorGradingContract();
@@ -77909,7 +77975,10 @@ function planCompositionAssembly(input) {
77909
77975
  ...toArray(assetHead?.querySelectorAll(SCRIPT_SELECTOR)),
77910
77976
  ...toArray(contentNode.querySelectorAll(SCRIPT_SELECTOR))
77911
77977
  ],
77912
- linkSources: toArray(head?.querySelectorAll(HOISTED_LINK_SELECTOR)),
77978
+ linkSources: [
77979
+ ...toArray(head?.querySelectorAll(HOISTED_LINK_SELECTOR)),
77980
+ ...toArray(contentNode.querySelectorAll(HOISTED_LINK_SELECTOR))
77981
+ ],
77913
77982
  variableDefaultCarriers: [documentElement, innerRoot].filter((carrier) => carrier != null)
77914
77983
  };
77915
77984
  }
@@ -77932,7 +78001,7 @@ function enumerateNestedCompositionHosts(assembledHost, ancestry) {
77932
78001
  }
77933
78002
  return { hosts, skipped };
77934
78003
  }
77935
- var COMPOSITION_ID_ATTR, COMPOSITION_SRC_ATTR, COMPOSITION_ROOT_SELECTOR, COMPOSITION_HOST_SELECTOR, STYLE_SELECTOR, SCRIPT_SELECTOR, HOISTED_LINK_SELECTOR, MAX_SUB_COMPOSITION_DEPTH;
78004
+ var COMPOSITION_ID_ATTR, COMPOSITION_SRC_ATTR, COMPOSITION_ROOT_SELECTOR, COMPOSITION_HOST_SELECTOR, STYLE_SELECTOR, SCRIPT_SELECTOR, HOISTED_LINK_SELECTOR, EXTRACTED_COMPOSITION_ASSET_SELECTOR, MAX_SUB_COMPOSITION_DEPTH;
77936
78005
  var init_compositionAssembly = __esm({
77937
78006
  "../core/dist/compiler/compositionAssembly.js"() {
77938
78007
  "use strict";
@@ -77943,6 +78012,7 @@ var init_compositionAssembly = __esm({
77943
78012
  STYLE_SELECTOR = "style";
77944
78013
  SCRIPT_SELECTOR = "script";
77945
78014
  HOISTED_LINK_SELECTOR = 'link[rel="stylesheet"], link[rel="preconnect"]';
78015
+ EXTRACTED_COMPOSITION_ASSET_SELECTOR = `${STYLE_SELECTOR}, ${SCRIPT_SELECTOR}, ${HOISTED_LINK_SELECTOR}`;
77946
78016
  MAX_SUB_COMPOSITION_DEPTH = 20;
77947
78017
  }
77948
78018
  });
@@ -77988,8 +78058,7 @@ function inlineSubCompositions(document2, hosts, options) {
77988
78058
  compId = hostEl.getAttribute("data-composition-id") || null;
77989
78059
  runtimeCompId = compId || "";
77990
78060
  }
77991
- const contentRoot = compDoc.querySelector("template");
77992
- const contentHtml = contentRoot ? contentRoot.innerHTML || "" : compDoc.body?.innerHTML || "";
78061
+ const { contentHtml, hasTemplate } = resolveSubCompositionContent(compHtml, compDoc);
77993
78062
  if (!contentHtml.trim()) {
77994
78063
  onMissingComposition?.(src);
77995
78064
  continue;
@@ -78003,7 +78072,7 @@ function inlineSubCompositions(document2, hosts, options) {
78003
78072
  contentNode: contentDoc,
78004
78073
  head: compDoc.head,
78005
78074
  documentElement: compDoc.documentElement,
78006
- hasTemplate: Boolean(contentRoot),
78075
+ hasTemplate,
78007
78076
  compositionId: compId
78008
78077
  });
78009
78078
  const innerRoot = plan2.innerRoot;
@@ -78086,7 +78155,7 @@ function inlineSubCompositions(document2, hosts, options) {
78086
78155
  }
78087
78156
  if (innerRoot) {
78088
78157
  innerRoot.setAttribute("data-composition-file", src);
78089
- for (const child of [...innerRoot.querySelectorAll("style, script")])
78158
+ for (const child of [...innerRoot.querySelectorAll(EXTRACTED_COMPOSITION_ASSET_SELECTOR)])
78090
78159
  child.remove();
78091
78160
  if (flattenInnerRoot) {
78092
78161
  const prepared = flattenInnerRoot(innerRoot);
@@ -78101,7 +78170,7 @@ function inlineSubCompositions(document2, hosts, options) {
78101
78170
  }
78102
78171
  }
78103
78172
  } else {
78104
- for (const child of [...contentDoc.querySelectorAll("style, script")])
78173
+ for (const child of [...contentDoc.querySelectorAll(EXTRACTED_COMPOSITION_ASSET_SELECTOR)])
78105
78174
  child.remove();
78106
78175
  const bodyHtml = contentDoc.body?.innerHTML || "";
78107
78176
  hostEl.innerHTML = bodyHtml || contentDoc.documentElement?.outerHTML || "";
@@ -92911,17 +92980,17 @@ function getSystemProfilerIndex() {
92911
92980
  const filePath = typeface.path;
92912
92981
  if (typeof filePath !== "string" || !FONT_EXT_RE.test(filePath))
92913
92982
  continue;
92914
- const normalized = normalizeName(family);
92983
+ const normalized2 = normalizeName(family);
92915
92984
  const ext = filePath.match(FONT_EXT_RE)?.[1] ?? "ttf";
92916
92985
  const entry = {
92917
- family: normalized,
92986
+ family: normalized2,
92918
92987
  path: filePath,
92919
92988
  format: extensionToFormat(ext),
92920
92989
  isRegular: isRegularWeight(filePath)
92921
92990
  };
92922
- const list = profilerCache.get(normalized) ?? [];
92991
+ const list = profilerCache.get(normalized2) ?? [];
92923
92992
  list.push(entry);
92924
- profilerCache.set(normalized, list);
92993
+ profilerCache.set(normalized2, list);
92925
92994
  }
92926
92995
  }
92927
92996
  } catch {
@@ -92959,12 +93028,12 @@ function inferWeightAndStyle(fileName) {
92959
93028
  return { weight: "400", style };
92960
93029
  }
92961
93030
  function locateSystemFontVariants(family) {
92962
- const normalized = normalizeName(family);
92963
- if (!normalized)
93031
+ const normalized2 = normalizeName(family);
93032
+ if (!normalized2)
92964
93033
  return [];
92965
93034
  const variants = [];
92966
93035
  const profilerIndex = getSystemProfilerIndex();
92967
- const profilerEntries = profilerIndex.get(normalized);
93036
+ const profilerEntries = profilerIndex.get(normalized2);
92968
93037
  if (profilerEntries && profilerEntries.length > 0) {
92969
93038
  for (const e of profilerEntries) {
92970
93039
  if (!isRegularFile(e.path) || !isPathBounded(e.path))
@@ -92977,7 +93046,7 @@ function locateSystemFontVariants(family) {
92977
93046
  }
92978
93047
  const allCandidates = [];
92979
93048
  for (const dir of fontDirectories()) {
92980
- allCandidates.push(...collectCandidatesFromDir(dir, normalized));
93049
+ allCandidates.push(...collectCandidatesFromDir(dir, normalized2));
92981
93050
  }
92982
93051
  for (const c of allCandidates) {
92983
93052
  const { weight, style } = inferWeightAndStyle(c.path);
@@ -93320,8 +93389,8 @@ function extractExistingFontFaces(html) {
93320
93389
  if (semicolon < 0) break;
93321
93390
  const end = html.indexOf("}", semicolon + 1);
93322
93391
  if (end < 0) break;
93323
- const normalized = normalizeFamilyName(html.slice(valueStart, semicolon));
93324
- if (normalized) families.add(normalized);
93392
+ const normalized2 = normalizeFamilyName(html.slice(valueStart, semicolon));
93393
+ if (normalized2) families.add(normalized2);
93325
93394
  opening.lastIndex = end + 1;
93326
93395
  }
93327
93396
  return families;
@@ -93334,10 +93403,10 @@ function extractRequestedFontFamilies(html) {
93334
93403
  declaration,
93335
93404
  customProperties
93336
93405
  )) {
93337
- const normalized = originalCase.toLowerCase();
93338
- if (!normalized || GENERIC_FAMILIES2.has(normalized)) continue;
93339
- if (normalized.startsWith("var(")) continue;
93340
- if (!requested.has(normalized)) requested.set(normalized, originalCase);
93406
+ const normalized2 = originalCase.toLowerCase();
93407
+ if (!normalized2 || GENERIC_FAMILIES2.has(normalized2)) continue;
93408
+ if (normalized2.startsWith("var(")) continue;
93409
+ if (!requested.has(normalized2)) requested.set(normalized2, originalCase);
93341
93410
  }
93342
93411
  }
93343
93412
  return requested;
@@ -94015,11 +94084,11 @@ function hasGifExtension(src) {
94015
94084
  function readLoopOverride(el) {
94016
94085
  const raw = el.getAttribute("data-loop");
94017
94086
  if (raw == null) return null;
94018
- const normalized = raw.trim().toLowerCase();
94019
- if (normalized === "" || normalized === "true" || normalized === "1" || normalized === "yes") {
94087
+ const normalized2 = raw.trim().toLowerCase();
94088
+ if (normalized2 === "" || normalized2 === "true" || normalized2 === "1" || normalized2 === "yes") {
94020
94089
  return true;
94021
94090
  }
94022
- if (normalized === "false" || normalized === "0" || normalized === "no") {
94091
+ if (normalized2 === "false" || normalized2 === "0" || normalized2 === "no") {
94023
94092
  return false;
94024
94093
  }
94025
94094
  return null;
@@ -94769,7 +94838,7 @@ var EmptyCompositionError = class extends Error {
94769
94838
  `${problems.length} composition file${problems.length === 1 ? "" : "s"} referenced by data-composition-src cannot be rendered:
94770
94839
  ${lines.join("\n")}
94771
94840
 
94772
- Check that each file referenced by data-composition-src contains valid HTML with a <template> or <body> containing a [data-composition-id] element. If a scene-authoring step is still running, wait for it to finish before referencing the file.`
94841
+ Check that each file referenced by data-composition-src contains valid HTML with a [data-composition-id] element in a <template>, <body>, or bare fragment. If a scene-authoring step is still running, wait for it to finish before referencing the file.`
94773
94842
  );
94774
94843
  this.name = "EmptyCompositionError";
94775
94844
  this.problems = problems;
@@ -102760,11 +102829,11 @@ function validateOutputResolutionOverride(body) {
102760
102829
  if (typeof body.outputResolution !== "string") {
102761
102830
  return 'outputResolution must be a string preset (e.g. "4k", "landscape-4k")';
102762
102831
  }
102763
- const normalized = normalizeResolutionFlag(body.outputResolution);
102764
- if (body.outputResolution.trim().length > 0 && normalized === void 0) {
102832
+ const normalized2 = normalizeResolutionFlag(body.outputResolution);
102833
+ if (body.outputResolution.trim().length > 0 && normalized2 === void 0) {
102765
102834
  return `Invalid outputResolution "${body.outputResolution}". Must be one of: landscape, portrait, landscape-4k, portrait-4k, square, square-4k (aliases: 1080p, 4k, \u2026).`;
102766
102835
  }
102767
- if (normalized !== void 0 && (body.format === "webm" || body.format === "mov")) {
102836
+ if (normalized2 !== void 0 && (body.format === "webm" || body.format === "mov")) {
102768
102837
  return `outputResolution is not supported with format "${body.format}" \u2014 the alpha (webm/mov) capture path can't supersample. Use format "mp4", or omit outputResolution to render at the composition's native dimensions.`;
102769
102838
  }
102770
102839
  return void 0;
@@ -103438,8 +103507,8 @@ async function runFontLocalize(io, localize) {
103438
103507
  }
103439
103508
 
103440
103509
  // src/version.ts
103441
- var VERSION = true ? "0.8.65" : "0.0.0-dev";
103442
- var PRODUCER_VERSION = true ? "0.8.65" : "0.0.0-dev";
103510
+ var VERSION = true ? "0.8.67" : "0.0.0-dev";
103511
+ var PRODUCER_VERSION = true ? "0.8.67" : "0.0.0-dev";
103443
103512
 
103444
103513
  // src/fontLocalizeCli.ts
103445
103514
  async function readStdin() {