hyperframes 0.8.67 → 0.8.68

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.
@@ -31227,13 +31227,13 @@ var require_lib2 = __commonJS({
31227
31227
  DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.",
31228
31228
  DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement.",
31229
31229
  EnumBooleanMemberNotInitialized: ({
31230
- memberName: memberName2,
31230
+ memberName: memberName3,
31231
31231
  enumName
31232
- }) => `Boolean enum members need to be initialized. Use either \`${memberName2} = true,\` or \`${memberName2} = false,\` in enum \`${enumName}\`.`,
31232
+ }) => `Boolean enum members need to be initialized. Use either \`${memberName3} = true,\` or \`${memberName3} = false,\` in enum \`${enumName}\`.`,
31233
31233
  EnumDuplicateMemberName: ({
31234
- memberName: memberName2,
31234
+ memberName: memberName3,
31235
31235
  enumName
31236
- }) => `Enum member names need to be unique, but the name \`${memberName2}\` has already been used before in enum \`${enumName}\`.`,
31236
+ }) => `Enum member names need to be unique, but the name \`${memberName3}\` has already been used before in enum \`${enumName}\`.`,
31237
31237
  EnumInconsistentMemberValues: ({
31238
31238
  enumName
31239
31239
  }) => `Enum \`${enumName}\` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.`,
@@ -31246,26 +31246,26 @@ var require_lib2 = __commonJS({
31246
31246
  }) => `Supplied enum type is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`,
31247
31247
  EnumInvalidMemberInitializerPrimaryType: ({
31248
31248
  enumName,
31249
- memberName: memberName2,
31249
+ memberName: memberName3,
31250
31250
  explicitType
31251
- }) => `Enum \`${enumName}\` has type \`${explicitType}\`, so the initializer of \`${memberName2}\` needs to be a ${explicitType} literal.`,
31251
+ }) => `Enum \`${enumName}\` has type \`${explicitType}\`, so the initializer of \`${memberName3}\` needs to be a ${explicitType} literal.`,
31252
31252
  EnumInvalidMemberInitializerSymbolType: ({
31253
31253
  enumName,
31254
- memberName: memberName2
31255
- }) => `Symbol enum members cannot be initialized. Use \`${memberName2},\` in enum \`${enumName}\`.`,
31254
+ memberName: memberName3
31255
+ }) => `Symbol enum members cannot be initialized. Use \`${memberName3},\` in enum \`${enumName}\`.`,
31256
31256
  EnumInvalidMemberInitializerUnknownType: ({
31257
31257
  enumName,
31258
- memberName: memberName2
31259
- }) => `The enum member initializer for \`${memberName2}\` needs to be a literal (either a boolean, number, or string) in enum \`${enumName}\`.`,
31258
+ memberName: memberName3
31259
+ }) => `The enum member initializer for \`${memberName3}\` needs to be a literal (either a boolean, number, or string) in enum \`${enumName}\`.`,
31260
31260
  EnumInvalidMemberName: ({
31261
31261
  enumName,
31262
- memberName: memberName2,
31262
+ memberName: memberName3,
31263
31263
  suggestion
31264
- }) => `Enum member names cannot start with lowercase 'a' through 'z'. Instead of using \`${memberName2}\`, consider using \`${suggestion}\`, in enum \`${enumName}\`.`,
31264
+ }) => `Enum member names cannot start with lowercase 'a' through 'z'. Instead of using \`${memberName3}\`, consider using \`${suggestion}\`, in enum \`${enumName}\`.`,
31265
31265
  EnumNumberMemberNotInitialized: ({
31266
31266
  enumName,
31267
- memberName: memberName2
31268
- }) => `Number enum members need to be initialized, e.g. \`${memberName2} = 1\` in enum \`${enumName}\`.`,
31267
+ memberName: memberName3
31268
+ }) => `Number enum members need to be initialized, e.g. \`${memberName3} = 1\` in enum \`${enumName}\`.`,
31269
31269
  EnumStringMemberInconsistentlyInitialized: ({
31270
31270
  enumName
31271
31271
  }) => `String enum members need to consistently either all use initializers, or use no initializers, in enum \`${enumName}\`.`,
@@ -33262,10 +33262,10 @@ var require_lib2 = __commonJS({
33262
33262
  }
33263
33263
  flowEnumErrorBooleanMemberNotInitialized(loc, {
33264
33264
  enumName,
33265
- memberName: memberName2
33265
+ memberName: memberName3
33266
33266
  }) {
33267
33267
  this.raise(FlowErrors.EnumBooleanMemberNotInitialized, loc, {
33268
- memberName: memberName2,
33268
+ memberName: memberName3,
33269
33269
  enumName
33270
33270
  });
33271
33271
  }
@@ -33377,28 +33377,28 @@ var require_lib2 = __commonJS({
33377
33377
  id,
33378
33378
  init
33379
33379
  } = this.flowEnumMemberRaw();
33380
- const memberName2 = id.name;
33381
- if (memberName2 === "") {
33380
+ const memberName3 = id.name;
33381
+ if (memberName3 === "") {
33382
33382
  continue;
33383
33383
  }
33384
- if (/^[a-z]/.test(memberName2)) {
33384
+ if (/^[a-z]/.test(memberName3)) {
33385
33385
  this.raise(FlowErrors.EnumInvalidMemberName, id, {
33386
- memberName: memberName2,
33387
- suggestion: memberName2[0].toUpperCase() + memberName2.slice(1),
33386
+ memberName: memberName3,
33387
+ suggestion: memberName3[0].toUpperCase() + memberName3.slice(1),
33388
33388
  enumName
33389
33389
  });
33390
33390
  }
33391
- if (seenNames.has(memberName2)) {
33391
+ if (seenNames.has(memberName3)) {
33392
33392
  this.raise(FlowErrors.EnumDuplicateMemberName, id, {
33393
- memberName: memberName2,
33393
+ memberName: memberName3,
33394
33394
  enumName
33395
33395
  });
33396
33396
  }
33397
- seenNames.add(memberName2);
33397
+ seenNames.add(memberName3);
33398
33398
  const context = {
33399
33399
  enumName,
33400
33400
  explicitType,
33401
- memberName: memberName2
33401
+ memberName: memberName3
33402
33402
  };
33403
33403
  memberNode.id = id;
33404
33404
  switch (init.type) {
@@ -50287,7 +50287,7 @@ function resolveAliasDisplayName(alias) {
50287
50287
  if (!slug) return void 0;
50288
50288
  return CANONICAL_FONT_DISPLAY_NAMES[slug];
50289
50289
  }
50290
- var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, PROPERTY_GROUPS, PROP_TO_GROUP, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, OK, HTML_BODY_CSS_WIDTH_FIRST_RE, HTML_BODY_CSS_HEIGHT_FIRST_RE, VIEWPORT_META_SIZE_RE, FONT_ALIAS_MAP, FONT_ALIAS_KEYS, CANONICAL_FONT_DISPLAY_NAMES;
50290
+ var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, PROPERTY_GROUPS, PROP_TO_GROUP, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, OK, HTML_BODY_CSS_WIDTH_FIRST_RE, HTML_BODY_CSS_HEIGHT_FIRST_RE, FONT_ALIAS_MAP, FONT_ALIAS_KEYS, CANONICAL_FONT_DISPLAY_NAMES;
50291
50291
  var init_dist = __esm({
50292
50292
  "../parsers/dist/index.js"() {
50293
50293
  "use strict";
@@ -50367,7 +50367,6 @@ var init_dist = __esm({
50367
50367
  OK = { ok: true };
50368
50368
  HTML_BODY_CSS_WIDTH_FIRST_RE = /(html\s*,\s*body\s*\{[^}]*?width:\s*)(\d+)px([^}]*?height:\s*)(\d+)px/i;
50369
50369
  HTML_BODY_CSS_HEIGHT_FIRST_RE = /(html\s*,\s*body\s*\{[^}]*?height:\s*)(\d+)px([^}]*?width:\s*)(\d+)px/i;
50370
- VIEWPORT_META_SIZE_RE = /(<meta[^>]*name=["']viewport["'][^>]*content=["']width=)(\d+)(,\s*height=)(\d+)/i;
50371
50370
  FONT_ALIAS_MAP = {
50372
50371
  // ── Canonical bundled fonts (self-referencing) ────────────────────────
50373
50372
  inter: "inter",
@@ -65981,12 +65980,84 @@ function isSafeMediaUrl(url) {
65981
65980
  if (proto === "data") return /^data:image\//i.test(normalized2);
65982
65981
  return false;
65983
65982
  }
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;
65983
+ function parseProgram(script) {
65984
+ try {
65985
+ return parse7(script, { ecmaVersion: "latest", sourceType: "script" });
65986
+ } catch {
65987
+ return parse7(script, { ecmaVersion: "latest", sourceType: "module" });
65988
+ }
65989
+ }
65990
+ function literalString2(node) {
65991
+ if (node?.type === "Literal" && typeof node.value === "string") return node.value;
65992
+ if (node?.type === "TemplateLiteral" && node.expressions?.length === 0) {
65993
+ return node.quasis?.[0]?.value?.cooked;
65994
+ }
65995
+ return void 0;
65996
+ }
65997
+ function memberName2(node) {
65998
+ if (node?.type !== "MemberExpression") return void 0;
65999
+ if (!node.computed && node.property?.type === "Identifier") return node.property.name;
66000
+ return literalString2(node.property);
66001
+ }
66002
+ function lookupSelector2(node, bindings) {
66003
+ if (node?.type === "Identifier") return bindings.get(node.name);
66004
+ if (node?.type !== "CallExpression" || node.callee?.type !== "MemberExpression") {
66005
+ return void 0;
66006
+ }
66007
+ const method = memberName2(node.callee);
66008
+ if (method !== "getElementById" && method !== "querySelector") return void 0;
66009
+ const value = literalString2(node.arguments?.[0]);
66010
+ if (!value) return void 0;
66011
+ return method === "getElementById" ? `#${value}` : value;
66012
+ }
66013
+ function extractMediaSrcMutations2(script) {
66014
+ try {
66015
+ const ast = parseProgram(script);
66016
+ const bindings = /* @__PURE__ */ new Map();
66017
+ simple(ast, {
66018
+ VariableDeclarator(node) {
66019
+ if (node.id?.type !== "Identifier") return;
66020
+ const selector = lookupSelector2(node.init, bindings);
66021
+ if (selector) bindings.set(node.id.name, selector);
66022
+ }
66023
+ });
66024
+ const mutations = [];
66025
+ simple(ast, {
66026
+ AssignmentExpression(node) {
66027
+ if (node.operator !== "=" || memberName2(node.left) !== "src") return;
66028
+ const selector = lookupSelector2(node.left.object, bindings);
66029
+ if (!selector) return;
66030
+ mutations.push({
66031
+ selector,
66032
+ operation: "src_assignment",
66033
+ raw: script.slice(node.start, node.end)
66034
+ });
66035
+ },
66036
+ CallExpression(node) {
66037
+ if (memberName2(node.callee) !== "setAttribute") return;
66038
+ if (literalString2(node.arguments?.[0])?.toLowerCase() !== "src") return;
66039
+ const selector = lookupSelector2(node.callee.object, bindings);
66040
+ if (!selector) return;
66041
+ mutations.push({
66042
+ selector,
66043
+ operation: "set_attribute",
66044
+ raw: script.slice(node.start, node.end)
66045
+ });
66046
+ }
66047
+ });
66048
+ return mutations;
66049
+ } catch {
66050
+ return [];
66051
+ }
66052
+ }
66053
+ 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, HTML_BODY_CSS_WIDTH_FIRST_RE2, HTML_BODY_CSS_HEIGHT_FIRST_RE2, VIEWPORT_META_SIZE_RE;
65985
66054
  var init_composition = __esm({
65986
66055
  "../parsers/dist/composition.js"() {
65987
66056
  "use strict";
65988
66057
  init_acorn();
65989
66058
  init_walk();
66059
+ init_acorn();
66060
+ init_walk();
65990
66061
  CANVAS_DIMENSIONS2 = {
65991
66062
  landscape: { width: 1920, height: 1080 },
65992
66063
  portrait: { width: 1080, height: 1920 },
@@ -66125,6 +66196,9 @@ var init_composition = __esm({
66125
66196
  COMPOSITION_ATTRIBUTES4.derivedEnd,
66126
66197
  COMPOSITION_ATTRIBUTES4.legacyTrack
66127
66198
  ]);
66199
+ HTML_BODY_CSS_WIDTH_FIRST_RE2 = /(html\s*,\s*body\s*\{[^}]*?width:\s*)(\d+)px([^}]*?height:\s*)(\d+)px/i;
66200
+ HTML_BODY_CSS_HEIGHT_FIRST_RE2 = /(html\s*,\s*body\s*\{[^}]*?height:\s*)(\d+)px([^}]*?width:\s*)(\d+)px/i;
66201
+ VIEWPORT_META_SIZE_RE = /(<meta[^>]*name=["']viewport["'][^>]*content=["']width=)(\d+)(,\s*height=)(\d+)/i;
66128
66202
  }
66129
66203
  });
66130
66204
 
@@ -70930,7 +71004,7 @@ function getObjectArrayKeyframeTiming(durations) {
70930
71004
  )
70931
71005
  };
70932
71006
  }
70933
- function parseProgram(script) {
71007
+ function parseProgram3(script) {
70934
71008
  try {
70935
71009
  return parse7(script, {
70936
71010
  ecmaVersion: "latest",
@@ -72087,7 +72161,7 @@ function parseGsapScriptAcornForWrite(script) {
72087
72161
  }
72088
72162
  function parseGsapScriptAcorn(script) {
72089
72163
  try {
72090
- const ast = parseProgram(script);
72164
+ const ast = parseProgram3(script);
72091
72165
  const scope = collectScopeBindings(ast);
72092
72166
  const detection = findTimelineVar(ast, scope);
72093
72167
  const ref2 = detection.ref ?? { kind: "identifier", name: "tl" };
@@ -72135,7 +72209,7 @@ function parseGsapScriptAcorn(script) {
72135
72209
  }
72136
72210
  function gsapScriptMotionPathFirstUseIndex(script) {
72137
72211
  try {
72138
- const ast = parseProgram(script);
72212
+ const ast = parseProgram3(script);
72139
72213
  const scope = collectScopeBindings(ast);
72140
72214
  const identifierBindings = collectIdentifierBindingIndex(ast);
72141
72215
  const timelineRef = findTimelineVar(ast, scope).ref;
@@ -72319,6 +72393,7 @@ var init_gsapParserAcorn = __esm({
72319
72393
  // ../lint/dist/index.js
72320
72394
  import postcss2 from "postcss";
72321
72395
  import postcss22 from "postcss";
72396
+ import postcss3 from "postcss";
72322
72397
  function parseHtmlStructure(source) {
72323
72398
  const tags = [];
72324
72399
  const blocks = { script: [], style: [] };
@@ -72363,6 +72438,7 @@ function parseHtmlStructure(source) {
72363
72438
  blocks[name].push({
72364
72439
  attrs: block.attrs,
72365
72440
  content: source.slice(block.contentStart, parser.startIndex),
72441
+ contentStart: block.contentStart,
72366
72442
  raw: source.slice(block.index, parser.endIndex + 1),
72367
72443
  index: block.index
72368
72444
  });
@@ -72512,11 +72588,17 @@ function readTimelineRegistryTopLevelKeys(source) {
72512
72588
  function getInlineScriptSyntaxError(source) {
72513
72589
  if (!source.trim()) return null;
72514
72590
  try {
72515
- new Function(source);
72591
+ parse7(source, {
72592
+ ecmaVersion: "latest",
72593
+ sourceType: "script",
72594
+ allowReturnOutsideFunction: true
72595
+ });
72516
72596
  return null;
72517
72597
  } catch (error) {
72518
- if (error instanceof Error) return error.message;
72519
- return String(error);
72598
+ return {
72599
+ message: error instanceof Error ? error.message : String(error),
72600
+ offset: error instanceof SyntaxError && "pos" in error && typeof error.pos === "number" ? error.pos : void 0
72601
+ };
72520
72602
  }
72521
72603
  }
72522
72604
  function stripStringLiterals(source) {
@@ -72788,7 +72870,7 @@ function stripCssComments(source) {
72788
72870
  }
72789
72871
  return out;
72790
72872
  }
72791
- function stripHtmlCommentsOnce(source) {
72873
+ function stripHtmlCommentsOnce(source, removed) {
72792
72874
  let out = "";
72793
72875
  let i = 0;
72794
72876
  for (; ; ) {
@@ -72797,14 +72879,17 @@ function stripHtmlCommentsOnce(source) {
72797
72879
  const end = source.indexOf("-->", start + 4);
72798
72880
  if (end < 0) return out + source.slice(i);
72799
72881
  out += source.slice(i, start);
72882
+ removed?.(start, end + 3);
72800
72883
  i = end + 3;
72801
72884
  }
72802
72885
  }
72803
- function stripHtmlComments(source) {
72886
+ function stripHtmlComments(source, pass) {
72804
72887
  let out = source;
72805
72888
  for (let prev = ""; prev !== out; ) {
72806
72889
  prev = out;
72807
- out = stripHtmlCommentsOnce(out);
72890
+ const ranges = [];
72891
+ out = stripHtmlCommentsOnce(out, pass ? (start, end) => ranges.push([start, end]) : void 0);
72892
+ if (ranges.length) pass?.(ranges);
72808
72893
  }
72809
72894
  return out;
72810
72895
  }
@@ -72875,9 +72960,39 @@ function snippetOffset(source, snippet) {
72875
72960
  if (index < 0 || source.text.indexOf(needle, index + 1) >= 0) return void 0;
72876
72961
  return source.offsets[index];
72877
72962
  }
72963
+ function mappedHtmlSource(original) {
72964
+ let offsets;
72965
+ const source = stripHtmlComments(original, (ranges) => {
72966
+ const previous = offsets;
72967
+ const length = (previous?.length ?? original.length + 1) - ranges.reduce((n, [a, b]) => n + b - a, 0);
72968
+ offsets = new Uint32Array(length);
72969
+ let target = 0;
72970
+ let start = 0;
72971
+ const spans = [
72972
+ ...ranges,
72973
+ [previous ? previous.length : original.length + 1, 0]
72974
+ ];
72975
+ for (const [a, b] of spans) {
72976
+ for (let i = start; i < a; i++) offsets[target++] = previous ? previous[i] : i;
72977
+ start = b;
72978
+ }
72979
+ });
72980
+ return { source, originalOffset: (index) => offsets ? offsets[index] : index };
72981
+ }
72982
+ function sourcePosition(source, offset3, file) {
72983
+ if (!Number.isInteger(offset3) || offset3 < 0 || offset3 > source.length) return {};
72984
+ const before2 = source.slice(0, offset3);
72985
+ return {
72986
+ ...file ? { file } : {},
72987
+ line: before2.split(/\r\n|\r|\n/).length,
72988
+ column: offset3 - Math.max(before2.lastIndexOf("\n"), before2.lastIndexOf("\r"))
72989
+ };
72990
+ }
72878
72991
  function buildLintContext(html, options = {}) {
72879
72992
  const rawSource = html || "";
72880
- let source = stripHtmlComments(rawSource);
72993
+ const mapped = mappedHtmlSource(rawSource);
72994
+ let source = mapped.source;
72995
+ let sourceStart = 0;
72881
72996
  const initialStructure = parseHtmlStructure(source);
72882
72997
  const templateTags = initialStructure.tags.filter(
72883
72998
  (tag) => tag.name === "template" && tag.closeIndex != null
@@ -72890,7 +73005,8 @@ function buildLintContext(html, options = {}) {
72890
73005
  const template = templateTags[0];
72891
73006
  let structure = initialStructure;
72892
73007
  if (template && !findRootTag(sourceWithoutTemplates)) {
72893
- source = source.slice(template.index + template.raw.length, template.closeIndex);
73008
+ sourceStart = template.index + template.raw.length;
73009
+ source = source.slice(sourceStart, template.closeIndex);
72894
73010
  structure = parseHtmlStructure(source);
72895
73011
  }
72896
73012
  const tags = structure.tags;
@@ -72900,14 +73016,23 @@ function buildLintContext(html, options = {}) {
72900
73016
  attrs: `href="${style.href}"`,
72901
73017
  content: style.content,
72902
73018
  raw: style.content,
72903
- index: -1
73019
+ index: -1,
73020
+ file: style.file ?? style.href
72904
73021
  }))
72905
73022
  ];
72906
73023
  const scripts = structure.scripts;
72907
73024
  const compositionIds = collectCompositionIds(tags);
72908
73025
  const rootTag = findRootTag(source, tags);
72909
73026
  const rootCompositionId = readDecodedAttr(rootTag?.raw || "", "data-composition-id");
73027
+ const locate = (block, offset3) => {
73028
+ if (offset3 === void 0 || offset3 < 0 || offset3 > block.content.length) return {};
73029
+ if (block.index === -1) return sourcePosition(block.content, offset3, block.file);
73030
+ if (block.contentStart === void 0) return {};
73031
+ const originalOffset = mapped.originalOffset(sourceStart + block.contentStart + offset3);
73032
+ return originalOffset === void 0 ? {} : sourcePosition(rawSource, originalOffset, options.filePath);
73033
+ };
72910
73034
  return {
73035
+ locate,
72911
73036
  source,
72912
73037
  rawSource,
72913
73038
  tags,
@@ -73090,12 +73215,12 @@ function findVisibleMarkupCommentLeak(source) {
73090
73215
  return null;
73091
73216
  }
73092
73217
  function readHtmlBodyCssSize(source) {
73093
- const widthFirst = source.match(HTML_BODY_CSS_WIDTH_FIRST_RE);
73218
+ const widthFirst = source.match(HTML_BODY_CSS_WIDTH_FIRST_RE2);
73094
73219
  if (widthFirst) {
73095
73220
  const [, , width = "", , height = ""] = widthFirst;
73096
73221
  return { width, height };
73097
73222
  }
73098
- const heightFirst = source.match(HTML_BODY_CSS_HEIGHT_FIRST_RE);
73223
+ const heightFirst = source.match(HTML_BODY_CSS_HEIGHT_FIRST_RE2);
73099
73224
  if (heightFirst) {
73100
73225
  const [, , height = "", , width = ""] = heightFirst;
73101
73226
  return { width, height };
@@ -73139,6 +73264,20 @@ function describeRootDimensionsDrift(source, dataWidth, dataHeight) {
73139
73264
  fixHint: "update html/body CSS and the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`"
73140
73265
  };
73141
73266
  }
73267
+ function cssErrorOffset(source, error) {
73268
+ if (error.input && "offset" in error.input && typeof error.input.offset === "number")
73269
+ return error.input.offset;
73270
+ const { line, column } = error;
73271
+ if (line === void 0 || column === void 0) return void 0;
73272
+ let offset3 = 0;
73273
+ let currentLine = 1;
73274
+ for (const match of source.matchAll(/\n/g)) {
73275
+ if (currentLine >= line) break;
73276
+ offset3 = match.index + 1;
73277
+ currentLine++;
73278
+ }
73279
+ return currentLine === line ? offset3 + column - 1 : void 0;
73280
+ }
73142
73281
  function tweensVolumeInSameCall(script, id) {
73143
73282
  const selector = new RegExp(`#${escapeRegExp3(id)}(?![\\w-])`, "g");
73144
73283
  for (let hit = selector.exec(script); hit; hit = selector.exec(script)) {
@@ -73398,7 +73537,7 @@ function findRuntimeMediaSrcMutationFindings(ctx) {
73398
73537
  const { document: document2 } = parseHTML(ctx.source);
73399
73538
  const findings = [];
73400
73539
  for (const script of ctx.scripts) {
73401
- for (const mutation of extractMediaSrcMutations(script.content)) {
73540
+ for (const mutation of extractMediaSrcMutations2(script.content)) {
73402
73541
  let targets;
73403
73542
  try {
73404
73543
  const id = /^#[A-Za-z_][\w-]*$/.test(mutation.selector) ? mutation.selector.slice(1) : null;
@@ -73577,6 +73716,40 @@ function findAudioGroupCarveAttrFindings(ctx) {
73577
73716
  }
73578
73717
  return findings;
73579
73718
  }
73719
+ function callsFor(script) {
73720
+ const cached2 = callIndexes.get(script);
73721
+ if (cached2) return cached2;
73722
+ const calls = [];
73723
+ try {
73724
+ const ast = parse7(script.content, {
73725
+ ecmaVersion: "latest",
73726
+ sourceType: "script",
73727
+ allowReturnOutsideFunction: true
73728
+ });
73729
+ simple(ast, {
73730
+ CallExpression: (node) => {
73731
+ calls.push(node);
73732
+ }
73733
+ });
73734
+ } catch {
73735
+ }
73736
+ calls.sort((a, b) => a.start - b.start);
73737
+ callIndexes.set(script, calls);
73738
+ return calls;
73739
+ }
73740
+ function gsapCallOffset(script, method) {
73741
+ return callsFor(script).find(
73742
+ ({ callee }) => callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "gsap" && callee.property.type === "Identifier" && callee.property.name === method
73743
+ )?.start;
73744
+ }
73745
+ function containingCallOffset(script, tokenOffset) {
73746
+ let start;
73747
+ for (const call of callsFor(script)) {
73748
+ if (call.start > tokenOffset) break;
73749
+ if (call.end > tokenOffset) start = call.start;
73750
+ }
73751
+ return start;
73752
+ }
73580
73753
  function readTagTiming(rawTag) {
73581
73754
  return readClipTiming({ getAttribute: (name) => readAttr(rawTag, name) });
73582
73755
  }
@@ -74074,7 +74247,7 @@ function scanScriptsForRegexMatches(scripts, pattern, options) {
74074
74247
  content.length,
74075
74248
  match.index + match[0].length + options.contextAfter
74076
74249
  );
74077
- hits.push({ match, snippet: content.slice(contextStart, contextEnd) });
74250
+ hits.push({ match, snippet: content.slice(contextStart, contextEnd), script });
74078
74251
  }
74079
74252
  }
74080
74253
  return hits;
@@ -74581,6 +74754,26 @@ function collectGoogleFontFamilies(source, styles) {
74581
74754
  }
74582
74755
  return families;
74583
74756
  }
74757
+ function uniqueFontLocation(styles, families, locate) {
74758
+ const locations = [];
74759
+ for (const style of styles) {
74760
+ try {
74761
+ postcss3.parse(style.content).walkDecls(/^font-family$/i, (decl) => {
74762
+ let parent = decl.parent;
74763
+ while (parent) {
74764
+ if (parent.type === "atrule" && parent.name.toLowerCase() === "font-face") return;
74765
+ parent = parent.parent;
74766
+ }
74767
+ if (!decl.value.split(",").some((part) => families.includes(normalizeUsedFontName(part) ?? "")))
74768
+ return;
74769
+ locations.push(locate(style, decl.source?.start?.offset));
74770
+ });
74771
+ } catch {
74772
+ return {};
74773
+ }
74774
+ }
74775
+ return locations.length === 1 ? locations[0] : {};
74776
+ }
74584
74777
  function parseTiming(raw) {
74585
74778
  const startStr = readAttr(raw, "data-start");
74586
74779
  if (startStr === null) return null;
@@ -74734,7 +74927,7 @@ function collectFindings(produced, seen, filePath, into) {
74734
74927
  const dedupeKey = dedupeKeyFor(finding);
74735
74928
  if (seen.has(dedupeKey)) continue;
74736
74929
  seen.add(dedupeKey);
74737
- into.push(filePath ? { ...finding, file: filePath } : finding);
74930
+ into.push(filePath ? { ...finding, file: finding.file ?? filePath } : finding);
74738
74931
  }
74739
74932
  }
74740
74933
  async function lintHyperframeHtml(html, options = {}) {
@@ -74743,6 +74936,12 @@ async function lintHyperframeHtml(html, options = {}) {
74743
74936
  const { findings: rawFindings, timings } = await runRules(ctx, options.filePath);
74744
74937
  const locate = createSourceLocator(html);
74745
74938
  const findings = rawFindings.map((finding) => {
74939
+ if (finding.line !== void 0 || finding.code === "invalid_inline_script_syntax" || finding.code === "non_deterministic_code" || [
74940
+ "gsap_infinite_repeat",
74941
+ "gsap_repeat_ceil_overshoot",
74942
+ "gsap_repeat_floor_unclamped"
74943
+ ].includes(finding.code))
74944
+ return finding;
74746
74945
  if (finding.snippet && options.externalStyles?.some(
74747
74946
  (style) => style.content.replace(/\s+/g, " ").includes(finding.snippet.replace(/\.\.\.$/, ""))
74748
74947
  ))
@@ -74761,17 +74960,20 @@ async function lintHyperframeHtml(html, options = {}) {
74761
74960
  timings: { totalMs: performance.now() - startedAt, ...timings }
74762
74961
  };
74763
74962
  }
74764
- 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, CLIP_MEDIA_TAGS, 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;
74963
+ 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, callIndexes, 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, CLIP_MEDIA_TAGS, 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;
74765
74964
  var init_dist3 = __esm({
74766
74965
  "../lint/dist/index.js"() {
74767
74966
  "use strict";
74768
74967
  init_esm6();
74769
74968
  init_esm6();
74969
+ init_acorn();
74770
74970
  import_postcss_selector_parser = __toESM(require_dist(), 1);
74771
- init_dist();
74971
+ init_composition();
74772
74972
  init_colorGradingContract();
74773
- init_dist();
74973
+ init_composition();
74774
74974
  init_esm10();
74975
+ init_acorn();
74976
+ init_walk();
74775
74977
  init_composition();
74776
74978
  init_compositionContract();
74777
74979
  init_compositionDuration();
@@ -74994,7 +75196,7 @@ var init_dist3 = __esm({
74994
75196
  return findings;
74995
75197
  },
74996
75198
  // CSS selector safety
74997
- ({ styles }) => {
75199
+ ({ styles, locate }) => {
74998
75200
  const findings = [];
74999
75201
  const reportedRepeatedIds = /* @__PURE__ */ new Set();
75000
75202
  const reportedHiddenStyleSelectors = /* @__PURE__ */ new Set();
@@ -75004,6 +75206,10 @@ var init_dist3 = __esm({
75004
75206
  root = postcss2.parse(style.content);
75005
75207
  } catch (error) {
75006
75208
  findings.push({
75209
+ ...locate(
75210
+ style,
75211
+ error instanceof postcss2.CssSyntaxError ? cssErrorOffset(style.content, error) : void 0
75212
+ ),
75007
75213
  code: "css_parse_error",
75008
75214
  severity: "error",
75009
75215
  message: `CSS parse error: ${error instanceof Error ? error.message : "unknown"}`
@@ -75069,7 +75275,7 @@ var init_dist3 = __esm({
75069
75275
  ];
75070
75276
  },
75071
75277
  // invalid_inline_script_syntax (JS parse error)
75072
- ({ scripts }) => {
75278
+ ({ scripts, locate }) => {
75073
75279
  const findings = [];
75074
75280
  for (const script of scripts) {
75075
75281
  const attrs = script.attrs || "";
@@ -75080,9 +75286,10 @@ var init_dist3 = __esm({
75080
75286
  const syntaxError = getInlineScriptSyntaxError(script.content);
75081
75287
  if (!syntaxError) continue;
75082
75288
  findings.push({
75289
+ ...locate(script, syntaxError.offset),
75083
75290
  code: "invalid_inline_script_syntax",
75084
75291
  severity: "error",
75085
- message: `Inline script has invalid syntax: ${syntaxError}`,
75292
+ message: `Inline script has invalid syntax: ${syntaxError.message}`,
75086
75293
  fixHint: "Fix the inline script syntax before render verification.",
75087
75294
  snippet: truncateSnippet(script.content)
75088
75295
  });
@@ -75148,7 +75355,7 @@ var init_dist3 = __esm({
75148
75355
  return findings;
75149
75356
  },
75150
75357
  // non_deterministic_code
75151
- ({ scripts }) => {
75358
+ ({ scripts, locate }) => {
75152
75359
  const findings = [];
75153
75360
  const patterns = [
75154
75361
  {
@@ -75199,8 +75406,10 @@ var init_dist3 = __esm({
75199
75406
  const withoutComments = stripJsComments(script.content);
75200
75407
  const executable = stripStringLiterals(withoutComments);
75201
75408
  for (const { pattern, label, hint, scansStrings } of patterns) {
75202
- if (pattern.test(scansStrings ? withoutComments : executable)) {
75409
+ const match = pattern.exec(scansStrings ? withoutComments : executable);
75410
+ if (match) {
75203
75411
  findings.push({
75412
+ ...locate(script, match.index),
75204
75413
  code: "non_deterministic_code",
75205
75414
  severity: "error",
75206
75415
  message: `Script contains \`${label}\` which produces non-deterministic output. Renders may differ between frames or runs.`,
@@ -75631,6 +75840,7 @@ var init_dist3 = __esm({
75631
75840
  findAudioGroupCarveAttrFindings
75632
75841
  ];
75633
75842
  AUDIO_GROUP_TIMING_ATTRS = ["data-start", "data-duration", "data-track-index"];
75843
+ callIndexes = /* @__PURE__ */ new WeakMap();
75634
75844
  MAX_COMPOSITION_LINES = 300;
75635
75845
  MAX_TIMED_ELEMENTS_PER_TRACK = 3;
75636
75846
  TRACK_DENSITY_EXEMPT_TAGS = /* @__PURE__ */ new Set(["audio", "script", "style", "video"]);
@@ -76763,19 +76973,20 @@ ${right.raw}`)
76763
76973
  return findings;
76764
76974
  },
76765
76975
  // gsap_infinite_repeat
76766
- ({ scripts, rootTag }) => {
76976
+ ({ scripts, rootTag, locate }) => {
76767
76977
  const findings = [];
76768
76978
  const declaredDuration = Number.parseFloat(
76769
76979
  rootTag ? readAttr(rootTag.raw, "data-duration") ?? "" : ""
76770
76980
  );
76771
76981
  const hasFiniteCompositionWindow = Number.isFinite(declaredDuration) && declaredDuration > 0;
76772
76982
  const pattern = /repeat\s*:\s*-1(?!\d)/g;
76773
- for (const { snippet } of scanScriptsForRegexMatches(scripts, pattern, {
76983
+ for (const { snippet, match, script } of scanScriptsForRegexMatches(scripts, pattern, {
76774
76984
  stripComments: true,
76775
76985
  contextBefore: 60,
76776
76986
  contextAfter: 60
76777
76987
  })) {
76778
76988
  findings.push({
76989
+ ...locate(script, containingCallOffset(script, match.index)),
76779
76990
  code: "gsap_infinite_repeat",
76780
76991
  severity: hasFiniteCompositionWindow ? "warning" : "error",
76781
76992
  message: hasFiniteCompositionWindow ? `GSAP tween uses \`repeat: -1\` (infinite), but the composition declares a finite ${declaredDuration}s window. HyperFrames clips deterministic seeking and export to that explicit duration.` : "GSAP tween uses `repeat: -1` (infinite) without a finite composition `data-duration`. The timeline can report an unbounded duration and make render planning fail.",
@@ -76786,15 +76997,16 @@ ${right.raw}`)
76786
76997
  return findings;
76787
76998
  },
76788
76999
  // gsap_repeat_ceil_overshoot
76789
- ({ scripts }) => {
77000
+ ({ scripts, locate }) => {
76790
77001
  const findings = [];
76791
77002
  const pattern = /repeat\s*:\s*Math\.ceil\s*\([^)]+\)\s*-\s*1/g;
76792
- for (const { snippet } of scanScriptsForRegexMatches(scripts, pattern, {
77003
+ for (const { snippet, match, script } of scanScriptsForRegexMatches(scripts, pattern, {
76793
77004
  stripComments: false,
76794
77005
  contextBefore: 40,
76795
77006
  contextAfter: 40
76796
77007
  })) {
76797
77008
  findings.push({
77009
+ ...locate(script, containingCallOffset(script, match.index)),
76798
77010
  code: "gsap_repeat_ceil_overshoot",
76799
77011
  severity: "warning",
76800
77012
  message: "GSAP repeat calculation uses `Math.ceil` which can overshoot the composition duration. For example, Math.ceil(10.5 / 2) - 1 = 5 repeats \u2192 6 cycles \xD7 2s = 12s, exceeding 10.5s.",
@@ -76805,15 +77017,16 @@ ${right.raw}`)
76805
77017
  return findings;
76806
77018
  },
76807
77019
  // gsap_repeat_floor_unclamped
76808
- ({ scripts }) => {
77020
+ ({ scripts, locate }) => {
76809
77021
  const findings = [];
76810
77022
  const pattern = /repeat\s*:\s*Math\.floor\s*\([^)]+\)\s*-\s*1/g;
76811
- for (const { snippet } of scanScriptsForRegexMatches(scripts, pattern, {
77023
+ for (const { snippet, match, script } of scanScriptsForRegexMatches(scripts, pattern, {
76812
77024
  stripComments: false,
76813
77025
  contextBefore: 40,
76814
77026
  contextAfter: 40
76815
77027
  })) {
76816
77028
  findings.push({
77029
+ ...locate(script, containingCallOffset(script, match.index)),
76817
77030
  code: "gsap_repeat_floor_unclamped",
76818
77031
  severity: "warning",
76819
77032
  message: "GSAP repeat calculation can evaluate to -1 when the composition is shorter than one cycle, which GSAP interprets as an infinite repeat.",
@@ -76824,7 +77037,7 @@ ${right.raw}`)
76824
77037
  return findings;
76825
77038
  },
76826
77039
  // gsap_timeline_not_registered
76827
- ({ scripts, rawSource, options }) => {
77040
+ ({ scripts, rawSource, options, locate }) => {
76828
77041
  const findings = [];
76829
77042
  const canInheritFromHost = options.isSubComposition || rawSource.trimStart().toLowerCase().startsWith("<template");
76830
77043
  for (const script of scripts) {
@@ -76833,6 +77046,7 @@ ${right.raw}`)
76833
77046
  const hasRegistration = WINDOW_TIMELINE_ASSIGN_PATTERN.test(content) || TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN.test(content);
76834
77047
  if (hasRegistration || canInheritFromHost) continue;
76835
77048
  findings.push({
77049
+ ...locate(script, gsapCallOffset(script, "timeline")),
76836
77050
  code: "gsap_timeline_not_registered",
76837
77051
  severity: "error",
76838
77052
  message: "GSAP timeline is created but never registered in window.__timelines. The runtime discovers timelines from this registry \u2014 without registration, animations will not play during preview or render.",
@@ -77820,7 +78034,7 @@ ${other.raw}`)
77820
78034
  ];
77821
78035
  },
77822
78036
  // font_family_without_font_face
77823
- ({ styles, source, rawSource, options }) => {
78037
+ ({ styles, source, rawSource, options, locate }) => {
77824
78038
  if (isRegistrySourceFile(options.filePath) || isRegistryInstalledFile(rawSource)) return [];
77825
78039
  const findings = [];
77826
78040
  const declared = extractFontFaceFamilies(styles);
@@ -77831,6 +78045,7 @@ ${other.raw}`)
77831
78045
  );
77832
78046
  if (undeclared.length === 0) return findings;
77833
78047
  findings.push({
78048
+ ...uniqueFontLocation(styles, undeclared, locate),
77834
78049
  code: "font_family_without_font_face",
77835
78050
  severity: "error",
77836
78051
  message: `Font ${undeclared.length === 1 ? "family" : "families"} used without @font-face declaration: ${undeclared.join(", ")}. These are not in the auto-resolved font list, so the renderer cannot supply them automatically. Text will fall back to a generic font, producing incorrect typography in the video.`,
@@ -93068,7 +93283,7 @@ function dedupeVariants(variants) {
93068
93283
  init_esm10();
93069
93284
  init_fontData_generated();
93070
93285
  init_fontCompression();
93071
- import postcss3 from "postcss";
93286
+ import postcss4 from "postcss";
93072
93287
  var GENERIC_FAMILIES2 = /* @__PURE__ */ new Set([
93073
93288
  "sans-serif",
93074
93289
  "serif",
@@ -93127,7 +93342,7 @@ function systemPrimaryReplacement(value, deterministicPrimary) {
93127
93342
  }
93128
93343
  function parseCssRoot(css) {
93129
93344
  try {
93130
- return postcss3.parse(css);
93345
+ return postcss4.parse(css);
93131
93346
  } catch {
93132
93347
  return null;
93133
93348
  }
@@ -103507,8 +103722,8 @@ async function runFontLocalize(io, localize) {
103507
103722
  }
103508
103723
 
103509
103724
  // src/version.ts
103510
- var VERSION = true ? "0.8.67" : "0.0.0-dev";
103511
- var PRODUCER_VERSION = true ? "0.8.67" : "0.0.0-dev";
103725
+ var VERSION = true ? "0.8.68" : "0.0.0-dev";
103726
+ var PRODUCER_VERSION = true ? "0.8.68" : "0.0.0-dev";
103512
103727
 
103513
103728
  // src/fontLocalizeCli.ts
103514
103729
  async function readStdin() {