hyperframes 0.8.141 → 0.8.143

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.
Files changed (200) hide show
  1. package/dist/{add-KH2CF4FD.js → add-Q5EYDUAY.js} +18 -17
  2. package/dist/{animatedGifPrep-QO4BSKR7.js → animatedGifPrep-H2DUQEZ3.js} +15 -15
  3. package/dist/{asset-4RDZILVJ.js → asset-C7JBYYX4.js} +4 -4
  4. package/dist/{assetCataloger-WGR4LYYN.js → assetCataloger-FRO4G6OU.js} +8 -7
  5. package/dist/{auth-WYQCOYE5.js → auth-FRWLCO36.js} +5 -4
  6. package/dist/{autoUpdate-PC5TN3NL.js → autoUpdate-E4OZXQK6.js} +2 -2
  7. package/dist/{backgroundChecks-7M3T44EP.js → backgroundChecks-FSUVHN5L.js} +3 -3
  8. package/dist/backgroundChecksWorker.js +3 -3
  9. package/dist/{batchRender-GOLLOE4V.js → batchRender-4U73BYTU.js} +11 -10
  10. package/dist/{beats-XJ7WP6QS.js → beats-U6KJWF35.js} +32 -28
  11. package/dist/{benchmark-HCGFBEZJ.js → benchmark-5ONT7V7B.js} +15 -14
  12. package/dist/{browser-VQKO2FKG.js → browser-R4DU46IE.js} +4 -4
  13. package/dist/{bundleWithLocalizedFonts-FH7PHTTX.js → bundleWithLocalizedFonts-VH55VOAL.js} +2 -2
  14. package/dist/{capture-TFZZSF6F.js → capture-26G2DPSI.js} +83 -41
  15. package/dist/{capture-XD3P3YQR.js → capture-OGQAEYKO.js} +24 -8
  16. package/dist/{catalog-4S33QWJJ.js → catalog-RKORTIUE.js} +19 -18
  17. package/dist/{catch-up-RW7YXXNT.js → catch-up-4OBERRQO.js} +5 -5
  18. package/dist/{check-XVTRRN4Y.js → check-P2XDN57S.js} +89 -85
  19. package/dist/{checkBrowser-HZXJ2EDU.js → checkBrowser-NTGJGAEA.js} +42 -42
  20. package/dist/{chunk-AVWEIOEN.js → chunk-2LBBHMKT.js} +1 -1
  21. package/dist/{chunk-E6SDW5FV.js → chunk-33RZPZ4K.js} +192 -45
  22. package/dist/{chunk-6IFXWJDX.js → chunk-3NE7ZYU2.js} +2 -2
  23. package/dist/{chunk-TQFG7HTI.js → chunk-3RM2ETQT.js} +0 -168
  24. package/dist/{chunk-PFCFR3KZ.js → chunk-442JNXRM.js} +1 -1
  25. package/dist/{chunk-6E6CM7WS.js → chunk-4M4EC7JX.js} +19 -12
  26. package/dist/{chunk-HKCNZITN.js → chunk-4OA4LDTU.js} +2 -2
  27. package/dist/{chunk-XTFJOR3K.js → chunk-4SFGME7K.js} +1 -1
  28. package/dist/{chunk-34TXESM7.js → chunk-5FISWJ37.js} +12 -4
  29. package/dist/{chunk-JYYOAKHS.js → chunk-6IIGT7BX.js} +1 -1
  30. package/dist/chunk-6TPZSTCL.js +3681 -0
  31. package/dist/{chunk-P6E4HFFU.js → chunk-6XMFEICO.js} +263 -75
  32. package/dist/{chunk-6Q6FR4KH.js → chunk-7UYBQ6NF.js} +296 -89
  33. package/dist/{chunk-BRITLL56.js → chunk-B4P5VDFQ.js} +1 -1
  34. package/dist/{chunk-U7E736AJ.js → chunk-BFDJ63J5.js} +32 -14
  35. package/dist/{chunk-WCJGTLPF.js → chunk-BHVFTYSI.js} +6 -3
  36. package/dist/{chunk-IO7ZIDRP.js → chunk-BT27OYYX.js} +53 -12
  37. package/dist/{chunk-KFH6UD26.js → chunk-BYK73CR7.js} +4 -4
  38. package/dist/{chunk-L3JSAB4L.js → chunk-CLOH4LIB.js} +3 -3
  39. package/dist/{chunk-R7UDXKI3.js → chunk-DF2BHILQ.js} +3 -3
  40. package/dist/{chunk-246MOR5U.js → chunk-DKSDVDXG.js} +175 -162
  41. package/dist/{chunk-35RSNI77.js → chunk-F26LCYRY.js} +42 -34
  42. package/dist/{chunk-5Z63TBTX.js → chunk-FH7WODJH.js} +1 -1
  43. package/dist/{chunk-NORZWWLK.js → chunk-FVYXDXEV.js} +2 -2
  44. package/dist/{chunk-YURXPGAM.js → chunk-GNBGPUJ7.js} +6 -8
  45. package/dist/{chunk-RVCWIIZ7.js → chunk-GV5R5B7Q.js} +1 -1
  46. package/dist/{chunk-GS6FE3IW.js → chunk-HC7EVDEL.js} +1 -1
  47. package/dist/{chunk-K2GOFLTX.js → chunk-HLYOEIWM.js} +14 -6
  48. package/dist/{chunk-XDSOIJC3.js → chunk-HMT2RPZU.js} +6 -6
  49. package/dist/{chunk-IKVBTDLO.js → chunk-HW4AKJ5F.js} +1 -1
  50. package/dist/{chunk-OLDDJS3S.js → chunk-I7QGQAZM.js} +8 -8
  51. package/dist/{chunk-JFKL3WAE.js → chunk-IWFLMU2N.js} +104 -19
  52. package/dist/{chunk-IHFUKJOR.js → chunk-K2FLNJVB.js} +8 -2
  53. package/dist/chunk-KJJLA674.js +121 -0
  54. package/dist/{chunk-XWVGSEUT.js → chunk-KO5QBV73.js} +1 -1
  55. package/dist/{chunk-INI3TM6I.js → chunk-KQLGTGE5.js} +3 -3
  56. package/dist/{chunk-E4BSCXMU.js → chunk-LVX6NK36.js} +3 -3
  57. package/dist/{chunk-BM5PX3DJ.js → chunk-LW6HO6U3.js} +4 -4
  58. package/dist/{chunk-OZUQF4NB.js → chunk-MQZVBHEY.js} +123 -8
  59. package/dist/{chunk-IV7EI5E2.js → chunk-N3DQEVSI.js} +2 -2
  60. package/dist/{chunk-A4KQZXZI.js → chunk-NE55C6S5.js} +4 -2
  61. package/dist/{chunk-EDYBFSPE.js → chunk-OBXQRJWQ.js} +7 -10
  62. package/dist/{chunk-RCFCZT5O.js → chunk-OSSHSIMD.js} +1 -1
  63. package/dist/chunk-P36MALQF.js +15 -0
  64. package/dist/{chunk-EKA4ZZBI.js → chunk-P7THMINS.js} +3 -3
  65. package/dist/{chunk-3NBKW2QJ.js → chunk-PAGIICKN.js} +2 -2
  66. package/dist/{chunk-O3SKIXQK.js → chunk-PJU63L6W.js} +1 -1
  67. package/dist/{chunk-RPYPW5NN.js → chunk-POLR33RB.js} +20 -13
  68. package/dist/{chunk-7M4KAPAA.js → chunk-PUGIRFPX.js} +2 -2
  69. package/dist/{chunk-7XTZVLE6.js → chunk-QFN7NVWM.js} +1 -1
  70. package/dist/{chunk-D2KNWIQ6.js → chunk-QFSCCQIR.js} +1 -1
  71. package/dist/{chunk-J5IPIQU2.js → chunk-QRKLPWEX.js} +1 -1
  72. package/dist/{chunk-N77KD7ZZ.js → chunk-QVYVUCWD.js} +1 -1
  73. package/dist/{chunk-GK4AIFIH.js → chunk-SDYDNHEE.js} +34 -3
  74. package/dist/{chunk-2NCHQUPX.js → chunk-SQLK7SJL.js} +1 -1
  75. package/dist/{chunk-PMRBLBUP.js → chunk-T42U2W2R.js} +14 -2
  76. package/dist/{chunk-Q65ZQFF2.js → chunk-TAMQYQGJ.js} +1 -1
  77. package/dist/{chunk-PXSM4HPB.js → chunk-U3X3TPBW.js} +1 -1
  78. package/dist/{chunk-3A5AAPMP.js → chunk-UICWP23D.js} +1 -1
  79. package/dist/{chunk-A7YQNIQT.js → chunk-UM2GRYM3.js} +113 -10
  80. package/dist/{chunk-TC2FBZJZ.js → chunk-VIVBA6E6.js} +2 -2
  81. package/dist/{chunk-W6HTOVHU.js → chunk-W35EKBS6.js} +2 -2
  82. package/dist/{chunk-YEIFI443.js → chunk-WPNE5NEP.js} +1 -1
  83. package/dist/{chunk-WY5OODN5.js → chunk-XONFUK3M.js} +3693 -28
  84. package/dist/{chunk-IYFKBFTW.js → chunk-Y6QL2LGO.js} +8 -5
  85. package/dist/{chunk-THXFSPLV.js → chunk-ZIRIDSDB.js} +1 -1
  86. package/dist/chunk-ZLW2V65P.js +209 -0
  87. package/dist/{chunk-4BB7V6AI.js → chunk-ZQQ3SEIE.js} +33 -32
  88. package/dist/{clean-L2E4VD57.js → clean-YHGPY33K.js} +23 -23
  89. package/dist/cli.js +57 -159
  90. package/dist/{cloud-IDUQRYLO.js → cloud-DOFI5ISR.js} +4 -4
  91. package/dist/{cloudrun-R3JXWXGG.js → cloudrun-KTZ4XDHL.js} +13 -12
  92. package/dist/commands/contrast-audit.browser.js +60 -4
  93. package/dist/commands/layout-audit.browser.js +88 -20
  94. package/dist/{compare-VYBWSP3Y.js → compare-SMMIZN2C.js} +37 -37
  95. package/dist/{compiler-ACHWOU5N.js → compiler-TEXQWW6N.js} +14 -11
  96. package/dist/{component-PYYV2V3F.js → component-B3GCNGSS.js} +5 -5
  97. package/dist/{compositions-B5GQSXH7.js → compositions-OQNZZTKF.js} +38 -34
  98. package/dist/{delete-EAX2U3WI.js → delete-EL5LVSEP.js} +6 -6
  99. package/dist/{deterministicFonts-F6WIVL2W.js → deterministicFonts-U2BIMGPG.js} +3 -3
  100. package/dist/{dist-NZSQCYOF.js → dist-5UVIRMSM.js} +7 -7
  101. package/dist/{dist-ROUDWGLO.js → dist-XN234YFQ.js} +41 -39
  102. package/dist/{doctor-PJX7MLFG.js → doctor-UOL3OI2A.js} +17 -17
  103. package/dist/{dom-IROKGVJI.js → dom-37K6YOH4.js} +2 -2
  104. package/dist/{events-SBC54MHO.js → events-K2DB2PBC.js} +2 -2
  105. package/dist/{events-YFFXKAQQ.js → events-NIZBS6S7.js} +3 -3
  106. package/dist/{feedback-UETLWREV.js → feedback-QMP4E6L7.js} +16 -15
  107. package/dist/{figma-QDSJPIRW.js → figma-2AUJRNVC.js} +3 -3
  108. package/dist/fontLocalizeCli.js +18 -18
  109. package/dist/{get-B5TS6C7H.js → get-P5NC7SRM.js} +6 -6
  110. package/dist/{gpuPolicy-LYOVBAJP.js → gpuPolicy-7N5MCE2G.js} +15 -15
  111. package/dist/{grade-compare-LBIHMAUN.js → grade-compare-HV5AFZ6P.js} +37 -37
  112. package/dist/{help-XBP6A6LT.js → help-3TSTXBLN.js} +1 -1
  113. package/dist/{history-2S42ZXKL.js → history-D65XFJ6D.js} +6 -6
  114. package/dist/hyperframe-runtime.js +25 -25
  115. package/dist/hyperframe.manifest.json +1 -1
  116. package/dist/hyperframe.runtime.iife.js +25 -25
  117. package/dist/hyperframes-player.global.js +3 -3
  118. package/dist/hyperframes-slideshow.global.js +23 -23
  119. package/dist/{info-I2VDAWT7.js → info-TXV7MLFO.js} +17 -16
  120. package/dist/{init-BGHSDODI.js → init-OSDMJZJV.js} +38 -38
  121. package/dist/{inspect-MZK5B5RP.js → inspect-RQQSAYIJ.js} +38 -38
  122. package/dist/{installer-LL4QAKFW.js → installer-CDOB32HE.js} +11 -10
  123. package/dist/{keyframes-2EBF7OSS.js → keyframes-V75Q6GRM.js} +10 -10
  124. package/dist/{lambda-XKFPAOFE.js → lambda-RODV4RCX.js} +12 -11
  125. package/dist/{layout-TP5ERKEF.js → layout-IZAI5SFC.js} +38 -38
  126. package/dist/{lint-FQ6CEI7E.js → lint-PLXOXY5R.js} +14 -14
  127. package/dist/{lintProject-LM3XZRPZ.js → lintProject-OQ6H6XBR.js} +7 -7
  128. package/dist/{list-FRNUJXZ3.js → list-BQBPNKDZ.js} +7 -7
  129. package/dist/{login-C25QU3BQ.js → login-NP6F4FHC.js} +20 -24
  130. package/dist/{logout-GJXZQKOA.js → logout-B4KS4A7S.js} +6 -6
  131. package/dist/{manager-DXB7JDHU.js → manager-GXYF4AVO.js} +2 -2
  132. package/dist/{manager-524RPYO7.js → manager-RFZNG5YT.js} +2 -2
  133. package/dist/{media-treatment-DCANGWSV.js → media-treatment-PXGMZ4A4.js} +55 -34
  134. package/dist/{models-GOD6ARB3.js → models-CEZM6XZ7.js} +17 -17
  135. package/dist/{motionShot-FSKETANX.js → motionShot-R4GHYWYM.js} +25 -25
  136. package/dist/{normalize-IGLHCWTF.js → normalize-H6KUHHEI.js} +18 -7
  137. package/dist/{normalize-audio-C2IM7OID.js → normalize-audio-MQ7NFCOV.js} +10 -6
  138. package/dist/{open-VVISXIII.js → open-AKQTGNXF.js} +5 -5
  139. package/dist/{pipeline-7YHZPYIS.js → pipeline-SYJYP2RM.js} +17 -17
  140. package/dist/{play-DSELK7G3.js → play-NBH4B7PL.js} +31 -30
  141. package/dist/{present-N72YFDKP.js → present-XAX55CFS.js} +26 -26
  142. package/dist/{preview-XTYN4NJ2.js → preview-OLANKNFA.js} +26 -26
  143. package/dist/{producer-NDCU3MHK.js → producer-Q6YNZZUJ.js} +1 -1
  144. package/dist/{projectConfig-MH4QU4AC.js → projectConfig-EM26P45P.js} +13 -12
  145. package/dist/{publication-KUSHI5MG.js → publication-OXWJZKSX.js} +8 -7
  146. package/dist/{publish-3XEEFWMF.js → publish-4VBWP2UB.js} +23 -22
  147. package/dist/{refresh-MFITBIKV.js → refresh-PVHBEABE.js} +2 -2
  148. package/dist/{remove-background-2QKJ7XOD.js → remove-background-REB7427G.js} +19 -19
  149. package/dist/{render-75E342ZU.js → render-3CVZ2SZG.js} +13 -12
  150. package/dist/{render-S73DW4KK.js → render-K25YOG3M.js} +22 -21
  151. package/dist/{render-2DVYTVLQ.js → render-TSE75QUL.js} +35 -35
  152. package/dist/{render-batch-YURBS54Q.js → render-batch-GGUOK3DS.js} +13 -12
  153. package/dist/{renderCancellation-373ASJTO.js → renderCancellation-PZRWB53I.js} +15 -15
  154. package/dist/renderSetupWorker.js +7 -7
  155. package/dist/{resolver-FE3GBZ4T.js → resolver-S5VK6UCB.js} +10 -9
  156. package/dist/{screenshotCapture-ECBTLCU6.js → screenshotCapture-TEUIWXWN.js} +53 -33
  157. package/dist/{sherpa-B2D3AGP6.js → sherpa-LVIUEAGF.js} +18 -18
  158. package/dist/skills/hyperframes-cli/references/cloud.md +1 -1
  159. package/dist/skills/hyperframes-cli/references/doctor-browser.md +24 -1
  160. package/dist/skills/media-use/references/grading.md +4 -2
  161. package/dist/skills/media-use/scripts/lib/cache.mjs +28 -14
  162. package/dist/skills/media-use/scripts/lib/cache.test.mjs +110 -0
  163. package/dist/skills/media-use/scripts/lib/duck.mjs +2 -1
  164. package/dist/skills/media-use/scripts/lib/duck.test.mjs +87 -0
  165. package/dist/skills/media-use/scripts/lib/probe.mjs +6 -1
  166. package/dist/skills/media-use/scripts/lib/probe.test.mjs +73 -0
  167. package/dist/skills/media-use/scripts/lib/words.mjs +1 -1
  168. package/dist/{skills-ICJ22CZZ.js → skills-I65FU5HD.js} +5 -5
  169. package/dist/{skillsUpdateCheck-GXZN56I5.js → skillsUpdateCheck-J57RNNIV.js} +3 -3
  170. package/dist/{slideshow-EJ4IMY6P.js → slideshow-4OJEPWNZ.js} +1 -1
  171. package/dist/{snapshot-XHKOAWF4.js → snapshot-YROOGY22.js} +42 -39
  172. package/dist/{src-I7UC3JTL.js → src-JO5JOV7Y.js} +16 -14
  173. package/dist/{src-74PFDTDX.js → src-X426BZAG.js} +17 -17
  174. package/dist/{staticProjectServer-2DGKD6TF.js → staticProjectServer-5VMBS262.js} +23 -23
  175. package/dist/{status-JA6SKQVH.js → status-LXPGSSKY.js} +6 -4
  176. package/dist/studio/assets/{hyperframes-player-5Vx2AiUz.js → hyperframes-player-BXSuksFh.js} +3 -3
  177. package/dist/studio/assets/{index-BAnh7cSQ.js → index-BgOVCqjo.js} +1 -1
  178. package/dist/studio/assets/{index-P8fgj_Xa.js → index-FgyO_5Kv.js} +1 -1
  179. package/dist/studio/assets/{index-C0thd4eM.js → index-J7jpL4pj.js} +157 -157
  180. package/dist/studio/index.html +1 -1
  181. package/dist/studio/index.js +148 -175
  182. package/dist/studio/index.js.map +1 -1
  183. package/dist/{studio-api-PROBO7JG.js → studio-api-VRBZUGAE.js} +22 -18
  184. package/dist/{studioServer-ID6UV2NE.js → studioServer-DBNKZ6I6.js} +50 -50
  185. package/dist/{synthesize-77PTU6C5.js → synthesize-C3IWDAXF.js} +2 -2
  186. package/dist/{telemetry-65LFHIWH.js → telemetry-CXAX3TO3.js} +3 -3
  187. package/dist/{timeline-6UV3JJXD.js → timeline-VQ34WH7J.js} +91 -70
  188. package/dist/{tokens-HIL4TZXI.js → tokens-62R7VFAZ.js} +4 -4
  189. package/dist/{transcribe-TIO6W3EQ.js → transcribe-7KR7IPJA.js} +18 -18
  190. package/dist/{transcribe-V7F6QDSN.js → transcribe-XOHPPL2O.js} +11 -11
  191. package/dist/{tts-TOHSPWEG.js → tts-MUV42JXT.js} +6 -6
  192. package/dist/{updateCheck-GZELANMA.js → updateCheck-POYNH3B5.js} +2 -2
  193. package/dist/{upgrade-BX3KDDZJ.js → upgrade-NBNOT7J2.js} +2 -2
  194. package/dist/{urlDownloader-R76OHFIE.js → urlDownloader-3NS63A7B.js} +14 -14
  195. package/dist/{validate-7UX4I443.js → validate-Y2QDHAEP.js} +40 -28
  196. package/dist/{video-RVGYEFQU.js → video-SJDMTSTL.js} +15 -15
  197. package/package.json +1 -1
  198. package/dist/chunk-24OWOBQH.js +0 -3656
  199. package/dist/chunk-SYKKFAUW.js +0 -3711
  200. /package/dist/{chunk-HBBJFK6I.js → chunk-APDLWWFG.js} +0 -0
package/dist/cli.js CHANGED
@@ -9,8 +9,10 @@ import {
9
9
  registerRunningCli
10
10
  } from "./chunk-NXMYHJAL.js";
11
11
  import {
12
- isTextFile
13
- } from "./chunk-K4WKGXRC.js";
12
+ assertKnownFlags,
13
+ resolveExtraPositionals
14
+ } from "./chunk-KJJLA674.js";
15
+ import "./chunk-K4WKGXRC.js";
14
16
  import {
15
17
  isRenderSucceeded
16
18
  } from "./chunk-L3YOGIPG.js";
@@ -34,7 +36,7 @@ import {
34
36
  } from "./chunk-ISN5GRYI.js";
35
37
  import {
36
38
  VERSION
37
- } from "./chunk-W6HTOVHU.js";
39
+ } from "./chunk-W35EKBS6.js";
38
40
  import "./chunk-M2WBOQ2Q.js";
39
41
 
40
42
  // src/cli.ts
@@ -42,110 +44,6 @@ import { dirname, join, resolve } from "path";
42
44
  import { fileURLToPath } from "url";
43
45
  import { existsSync } from "fs";
44
46
 
45
- // src/utils/reject-extra-positionals.ts
46
- var ACCEPTS_EXTRA_POSITIONALS = /* @__PURE__ */ new Set([
47
- "compare",
48
- "figma asset",
49
- "skills update",
50
- "timeline set"
51
- ]);
52
- var JOINS_EXTRA_POSITIONALS = /* @__PURE__ */ new Set(["catalog", "tts"]);
53
- var EXTRA_POSITIONAL_HINTS = {
54
- add: "Run add once per item, or pass a single tag to install every item tagged with it."
55
- };
56
- function wantsJson(value) {
57
- return value === true || typeof value === "string" && value !== "false" && value !== "0";
58
- }
59
- function declaredArgs(cmd) {
60
- const raw = cmd.args;
61
- return raw && typeof raw === "object" ? raw : {};
62
- }
63
- function usageLine(path, args) {
64
- const parts = ["hyperframes", path];
65
- let hasOptions = false;
66
- for (const [name, def] of Object.entries(args)) {
67
- if (def.type !== "positional") {
68
- hasOptions = true;
69
- continue;
70
- }
71
- const optional = def.required === false || def.default !== void 0;
72
- parts.push(optional ? `[${name.toUpperCase()}]` : `<${name.toUpperCase()}>`);
73
- }
74
- if (hasOptions) parts.push("[OPTIONS]");
75
- return parts.join(" ");
76
- }
77
- function resolveExtraPositionals(cmd, path, parsed) {
78
- if (ACCEPTS_EXTRA_POSITIONALS.has(path)) return;
79
- const args = declaredArgs(cmd);
80
- const positionals = Object.entries(args).filter(([, def]) => def.type === "positional");
81
- const given = (Array.isArray(parsed?._) ? parsed._ : []).map(String);
82
- const extra = given.slice(positionals.length);
83
- if (extra.length === 0) return;
84
- const last = positionals.at(-1)?.[0];
85
- const words = given.slice(positionals.length - 1);
86
- const ttsFile = path === "tts" && isTextFile(words[0]);
87
- if (parsed && last && JOINS_EXTRA_POSITIONALS.has(path) && !ttsFile) {
88
- parsed[last] = words.join(" ");
89
- return;
90
- }
91
- const plural = extra.length === 1 ? "" : "s";
92
- const message = `Unexpected extra argument${plural} for hyperframes ${path}: ${extra.join(", ")}
93
- Usage: ${usageLine(path, args)}` + (EXTRA_POSITIONAL_HINTS[path] ? `
94
- ${EXTRA_POSITIONAL_HINTS[path]}` : "");
95
- if (wantsJson(parsed?.json)) console.log(JSON.stringify({ ok: false, error: message }));
96
- else console.error(message);
97
- throw new CliUsageError(
98
- `${extra.length} unexpected extra argument${plural} for hyperframes ${path}`,
99
- {
100
- presented: true
101
- }
102
- );
103
- }
104
-
105
- // src/utils/reject-unknown-flags.ts
106
- var ALWAYS_KNOWN = /* @__PURE__ */ new Set(["help", "h", "version", "v", "json"]);
107
- function nameVariants(name) {
108
- const kebab = name.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());
109
- const camel = name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
110
- return [name, kebab, camel];
111
- }
112
- function knownFlags(args) {
113
- const known = new Set(ALWAYS_KNOWN);
114
- for (const [name, def] of Object.entries(args ?? {})) {
115
- for (const v of nameVariants(name)) known.add(v);
116
- const alias = def?.alias;
117
- if (typeof alias === "string") known.add(alias);
118
- else if (Array.isArray(alias)) for (const a of alias) known.add(a);
119
- }
120
- return known;
121
- }
122
- function longFlagName(tok) {
123
- const name = tok.slice(2).split("=")[0] ?? "";
124
- return name.startsWith("no-") ? name.slice(3) : name;
125
- }
126
- function unknownFlagIn(tok, known) {
127
- if (tok === "-" || !tok.startsWith("-")) return null;
128
- if (tok.startsWith("--")) {
129
- const name = longFlagName(tok);
130
- return name && !known.has(name) ? `--${name}` : null;
131
- }
132
- for (const ch of tok.slice(1).split("=")[0] ?? "") {
133
- if (!known.has(ch)) return `-${ch}`;
134
- }
135
- return null;
136
- }
137
- function assertKnownFlags(cmd, rawArgs) {
138
- if (!Array.isArray(rawArgs)) return;
139
- const rawDef = cmd.args;
140
- const args = rawDef && typeof rawDef === "object" ? rawDef : void 0;
141
- const known = knownFlags(args);
142
- for (const tok of rawArgs) {
143
- if (tok === "--") break;
144
- const bad = unknownFlagIn(tok, known);
145
- if (bad) throw new Error(`Unknown flag: ${bad}`);
146
- }
147
- }
148
-
149
47
  // src/utils/command-failure-tracking.ts
150
48
  function trackCommandFailures(load) {
151
49
  return () => load().then((cmd) => wrapCommand(cmd, commandName(cmd)));
@@ -181,7 +79,7 @@ function wrapCommand(cmd, path) {
181
79
  }
182
80
  async function reportCommandFailure(command2, err) {
183
81
  try {
184
- const { trackCommandFailure } = await import("./events-YFFXKAQQ.js");
82
+ const { trackCommandFailure } = await import("./events-NIZBS6S7.js");
185
83
  trackCommandFailure(command2, err);
186
84
  } catch {
187
85
  }
@@ -253,54 +151,54 @@ async function assertStudioWorkspaceBuilt() {
253
151
  });
254
152
  }
255
153
  var commandLoaders = {
256
- init: () => import("./init-BGHSDODI.js").then((m) => m.default),
257
- add: () => import("./add-KH2CF4FD.js").then((m) => m.default),
258
- catalog: () => import("./catalog-4S33QWJJ.js").then((m) => m.default),
154
+ init: () => import("./init-OSDMJZJV.js").then((m) => m.default),
155
+ add: () => import("./add-Q5EYDUAY.js").then((m) => m.default),
156
+ catalog: () => import("./catalog-RKORTIUE.js").then((m) => m.default),
259
157
  "media-use": () => import("./media-use-4XXGABIL.js").then((m) => m.default),
260
- play: () => import("./play-DSELK7G3.js").then((m) => m.default),
261
- present: () => import("./present-N72YFDKP.js").then((m) => m.default),
262
- preview: () => assertStudioWorkspaceBuilt().then(() => import("./preview-XTYN4NJ2.js").then((m) => m.default)),
263
- publish: () => import("./publish-3XEEFWMF.js").then((m) => m.default),
264
- open: () => import("./open-VVISXIII.js").then((m) => m.default),
265
- "catch-up": () => import("./catch-up-RW7YXXNT.js").then((m) => m.default),
266
- render: () => import("./render-2DVYTVLQ.js").then((m) => m.default),
267
- lint: () => import("./lint-FQ6CEI7E.js").then((m) => m.default),
268
- check: () => import("./check-XVTRRN4Y.js").then((m) => m.default),
269
- beats: () => import("./beats-XJ7WP6QS.js").then((m) => m.default),
270
- "normalize-audio": () => import("./normalize-audio-C2IM7OID.js").then((m) => m.default),
271
- inspect: () => import("./inspect-MZK5B5RP.js").then((m) => m.default),
272
- keyframes: () => import("./keyframes-2EBF7OSS.js").then((m) => m.default),
273
- layout: () => import("./layout-TP5ERKEF.js").then((m) => m.default),
274
- info: () => import("./info-I2VDAWT7.js").then((m) => m.default),
275
- compositions: () => import("./compositions-B5GQSXH7.js").then((m) => m.default),
276
- timeline: () => import("./timeline-6UV3JJXD.js").then((m) => m.default),
277
- history: () => import("./history-2S42ZXKL.js").then((m) => m.default),
278
- benchmark: () => import("./benchmark-HCGFBEZJ.js").then((m) => m.default),
279
- browser: () => import("./browser-VQKO2FKG.js").then((m) => m.default),
280
- "remove-background": () => import("./remove-background-2QKJ7XOD.js").then((m) => m.default),
281
- transcribe: () => import("./transcribe-V7F6QDSN.js").then((m) => m.default),
158
+ play: () => import("./play-NBH4B7PL.js").then((m) => m.default),
159
+ present: () => import("./present-XAX55CFS.js").then((m) => m.default),
160
+ preview: () => assertStudioWorkspaceBuilt().then(() => import("./preview-OLANKNFA.js").then((m) => m.default)),
161
+ publish: () => import("./publish-4VBWP2UB.js").then((m) => m.default),
162
+ open: () => import("./open-AKQTGNXF.js").then((m) => m.default),
163
+ "catch-up": () => import("./catch-up-4OBERRQO.js").then((m) => m.default),
164
+ render: () => import("./render-TSE75QUL.js").then((m) => m.default),
165
+ lint: () => import("./lint-PLXOXY5R.js").then((m) => m.default),
166
+ check: () => import("./check-P2XDN57S.js").then((m) => m.default),
167
+ beats: () => import("./beats-U6KJWF35.js").then((m) => m.default),
168
+ "normalize-audio": () => import("./normalize-audio-MQ7NFCOV.js").then((m) => m.default),
169
+ inspect: () => import("./inspect-RQQSAYIJ.js").then((m) => m.default),
170
+ keyframes: () => import("./keyframes-V75Q6GRM.js").then((m) => m.default),
171
+ layout: () => import("./layout-IZAI5SFC.js").then((m) => m.default),
172
+ info: () => import("./info-TXV7MLFO.js").then((m) => m.default),
173
+ compositions: () => import("./compositions-OQNZZTKF.js").then((m) => m.default),
174
+ timeline: () => import("./timeline-VQ34WH7J.js").then((m) => m.default),
175
+ history: () => import("./history-D65XFJ6D.js").then((m) => m.default),
176
+ benchmark: () => import("./benchmark-5ONT7V7B.js").then((m) => m.default),
177
+ browser: () => import("./browser-R4DU46IE.js").then((m) => m.default),
178
+ "remove-background": () => import("./remove-background-REB7427G.js").then((m) => m.default),
179
+ transcribe: () => import("./transcribe-XOHPPL2O.js").then((m) => m.default),
282
180
  usage: () => import("./usage-EC3KFUIJ.js").then((m) => m.default),
283
- models: () => import("./models-GOD6ARB3.js").then((m) => m.default),
284
- tts: () => import("./tts-TOHSPWEG.js").then((m) => m.default),
181
+ models: () => import("./models-CEZM6XZ7.js").then((m) => m.default),
182
+ tts: () => import("./tts-MUV42JXT.js").then((m) => m.default),
285
183
  docs: () => import("./docs-MPOM3PHH.js").then((m) => m.default),
286
- doctor: () => import("./doctor-PJX7MLFG.js").then((m) => m.default),
287
- clean: () => import("./clean-L2E4VD57.js").then((m) => m.default),
288
- upgrade: () => import("./upgrade-BX3KDDZJ.js").then((m) => m.default),
289
- skills: () => import("./skills-ICJ22CZZ.js").then((m) => m.default),
290
- feedback: () => import("./feedback-UETLWREV.js").then((m) => m.default),
184
+ doctor: () => import("./doctor-UOL3OI2A.js").then((m) => m.default),
185
+ clean: () => import("./clean-YHGPY33K.js").then((m) => m.default),
186
+ upgrade: () => import("./upgrade-NBNOT7J2.js").then((m) => m.default),
187
+ skills: () => import("./skills-I65FU5HD.js").then((m) => m.default),
188
+ feedback: () => import("./feedback-QMP4E6L7.js").then((m) => m.default),
291
189
  telemetry: () => import("./telemetry-W5AKPI4R.js").then((m) => m.default),
292
- events: () => import("./events-SBC54MHO.js").then((m) => m.default),
293
- validate: () => import("./validate-7UX4I443.js").then((m) => m.default),
294
- snapshot: () => import("./snapshot-XHKOAWF4.js").then((m) => m.default),
295
- "media-treatment": () => import("./media-treatment-DCANGWSV.js").then((m) => m.mediaTreatmentCommand),
296
- "grade-compare": () => import("./grade-compare-LBIHMAUN.js").then((m) => m.default),
297
- compare: () => import("./compare-VYBWSP3Y.js").then((m) => m.default),
298
- capture: () => import("./capture-XD3P3YQR.js").then((m) => m.default),
299
- lambda: () => import("./lambda-XKFPAOFE.js").then((m) => m.default),
300
- cloudrun: () => import("./cloudrun-R3JXWXGG.js").then((m) => m.default),
301
- cloud: () => import("./cloud-IDUQRYLO.js").then((m) => m.default),
302
- auth: () => import("./auth-WYQCOYE5.js").then((m) => m.default),
303
- figma: () => import("./figma-QDSJPIRW.js").then((m) => m.default)
190
+ events: () => import("./events-K2DB2PBC.js").then((m) => m.default),
191
+ validate: () => import("./validate-Y2QDHAEP.js").then((m) => m.default),
192
+ snapshot: () => import("./snapshot-YROOGY22.js").then((m) => m.default),
193
+ "media-treatment": () => import("./media-treatment-PXGMZ4A4.js").then((m) => m.mediaTreatmentCommand),
194
+ "grade-compare": () => import("./grade-compare-HV5AFZ6P.js").then((m) => m.default),
195
+ compare: () => import("./compare-SMMIZN2C.js").then((m) => m.default),
196
+ capture: () => import("./capture-OGQAEYKO.js").then((m) => m.default),
197
+ lambda: () => import("./lambda-RODV4RCX.js").then((m) => m.default),
198
+ cloudrun: () => import("./cloudrun-KTZ4XDHL.js").then((m) => m.default),
199
+ cloud: () => import("./cloud-DOFI5ISR.js").then((m) => m.default),
200
+ auth: () => import("./auth-FRWLCO36.js").then((m) => m.default),
201
+ figma: () => import("./figma-2AUJRNVC.js").then((m) => m.default)
304
202
  };
305
203
  var subCommands = Object.fromEntries(
306
204
  Object.entries(commandLoaders).map(([name, load]) => [name, trackCommandFailures(load)])
@@ -324,7 +222,7 @@ var _printStalePinNotice;
324
222
  var _printSkillsUpdateNotice;
325
223
  var telemetryReady = Promise.resolve();
326
224
  if (!isHelp && command !== "telemetry" && command !== "events" && command !== "usage" && command !== "unknown") {
327
- telemetryReady = import("./telemetry-65LFHIWH.js").then((mod) => {
225
+ telemetryReady = import("./telemetry-CXAX3TO3.js").then((mod) => {
328
226
  _flushSync = mod.flushSync;
329
227
  _trackCliError = mod.trackCliError;
330
228
  _trackCommandResult = mod.trackCommandResult;
@@ -334,23 +232,23 @@ if (!isHelp && command !== "telemetry" && command !== "events" && command !== "u
334
232
  });
335
233
  }
336
234
  if (!isHelp && !hasJsonFlag && command !== "upgrade" && command !== "events" && command !== "telemetry" && command !== "skills" && command !== "usage") {
337
- import("./autoUpdate-PC5TN3NL.js").then((mod) => mod.reportCompletedUpdate()).catch(() => {
235
+ import("./autoUpdate-E4OZXQK6.js").then((mod) => mod.reportCompletedUpdate()).catch(() => {
338
236
  });
339
- import("./updateCheck-GZELANMA.js").then(async (mod) => {
237
+ import("./updateCheck-POYNH3B5.js").then(async (mod) => {
340
238
  _printUpdateNotice = mod.printUpdateNotice;
341
239
  _printStalePinNotice = mod.printStalePinNotice;
342
240
  const result = mod.cachedUpdateCheck();
343
241
  if (result.updateAvailable) {
344
- const auto = await import("./autoUpdate-PC5TN3NL.js").catch(() => null);
242
+ const auto = await import("./autoUpdate-E4OZXQK6.js").catch(() => null);
345
243
  auto?.scheduleBackgroundInstall(result.latest, result.current);
346
244
  }
347
245
  }).catch(() => {
348
246
  });
349
- import("./skillsUpdateCheck-GXZN56I5.js").then((mod) => {
247
+ import("./skillsUpdateCheck-J57RNNIV.js").then((mod) => {
350
248
  _printSkillsUpdateNotice = mod.printSkillsUpdateNotice;
351
249
  }).catch(() => {
352
250
  });
353
- import("./backgroundChecks-7M3T44EP.js").then((mod) => mod.launchBackgroundChecks()).catch(() => {
251
+ import("./backgroundChecks-FSUVHN5L.js").then((mod) => mod.launchBackgroundChecks()).catch(() => {
354
252
  });
355
253
  }
356
254
  var _appHistoryNotice = null;
@@ -468,7 +366,7 @@ process.on("unhandledRejection", (reason) => {
468
366
  emitCliErrorEvent("unhandled_rejection", error);
469
367
  });
470
368
  async function showUsage(cmd, parent) {
471
- const { showUsage: impl } = await import("./help-XBP6A6LT.js");
369
+ const { showUsage: impl } = await import("./help-3TSTXBLN.js");
472
370
  return impl(cmd, parent);
473
371
  }
474
372
  async function showRequestedUsage() {
@@ -55,10 +55,10 @@ ${c.bold("AUTH:")}
55
55
  var cloud_default = defineCommand({
56
56
  meta: { name: "cloud", description: "Render HyperFrames compositions on the HeyGen cloud" },
57
57
  subCommands: {
58
- render: () => import("./render-S73DW4KK.js").then((m) => m.default),
59
- list: () => import("./list-FRNUJXZ3.js").then((m) => m.default),
60
- get: () => import("./get-B5TS6C7H.js").then((m) => m.default),
61
- delete: () => import("./delete-EAX2U3WI.js").then((m) => m.default)
58
+ render: () => import("./render-K25YOG3M.js").then((m) => m.default),
59
+ list: () => import("./list-BQBPNKDZ.js").then((m) => m.default),
60
+ get: () => import("./get-P5NC7SRM.js").then((m) => m.default),
61
+ delete: () => import("./delete-EL5LVSEP.js").then((m) => m.default)
62
62
  },
63
63
  async run({ args }) {
64
64
  if (!args._?.[0]) console.log(HELP);
@@ -6,37 +6,38 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  parseOutputResolutionFlag
9
- } from "./chunk-D2KNWIQ6.js";
9
+ } from "./chunk-QFSCCQIR.js";
10
10
  import {
11
11
  reportVariableIssues,
12
12
  resolveVariablesArg,
13
13
  validateVariablesAgainstProject
14
- } from "./chunk-BM5PX3DJ.js";
14
+ } from "./chunk-LW6HO6U3.js";
15
15
  import {
16
16
  readAllowedCompositionFpsFromDir
17
- } from "./chunk-YEIFI443.js";
18
- import "./chunk-IHFUKJOR.js";
19
- import "./chunk-PFCFR3KZ.js";
17
+ } from "./chunk-WPNE5NEP.js";
18
+ import "./chunk-K2FLNJVB.js";
19
+ import "./chunk-442JNXRM.js";
20
20
  import {
21
21
  defineCommand
22
22
  } from "./chunk-S3S4TGEH.js";
23
23
  import {
24
24
  failCommand
25
25
  } from "./chunk-PBN6GBJE.js";
26
- import "./chunk-6E6CM7WS.js";
27
- import "./chunk-OZUQF4NB.js";
28
- import "./chunk-DPVXBVLL.js";
29
- import "./chunk-SYKKFAUW.js";
26
+ import "./chunk-4M4EC7JX.js";
27
+ import "./chunk-6TPZSTCL.js";
30
28
  import "./chunk-VC76R6W2.js";
31
29
  import "./chunk-YA62XGXS.js";
30
+ import "./chunk-MQZVBHEY.js";
32
31
  import "./chunk-OFQWTKPW.js";
32
+ import "./chunk-DPVXBVLL.js";
33
33
  import "./chunk-T76PLPD6.js";
34
34
  import "./chunk-FXMKHHPO.js";
35
35
  import "./chunk-RQVDTPGD.js";
36
- import "./chunk-TQFG7HTI.js";
37
- import "./chunk-GK4AIFIH.js";
36
+ import "./chunk-3RM2ETQT.js";
37
+ import "./chunk-ZLW2V65P.js";
38
+ import "./chunk-SDYDNHEE.js";
38
39
  import "./chunk-2PSPARWP.js";
39
- import "./chunk-PMRBLBUP.js";
40
+ import "./chunk-T42U2W2R.js";
40
41
  import {
41
42
  normalizeErrorMessage
42
43
  } from "./chunk-KNU5COPB.js";
@@ -104,7 +104,57 @@ window.__contrastAuditPrepare = function () {
104
104
  var CLIP_PROBE_COLS = [0.05, 0.25, 0.5, 0.75, 0.95];
105
105
  var CLIP_PROBE_ROWS = [0.25, 0.5, 0.75];
106
106
 
107
- function paintsAnyProbePoint(el, rect) {
107
+ var compositionBoxPaint = new WeakMap();
108
+ var COMPOSITION_BOX_TAGS = new Set(["DIV", "SECTION"]);
109
+
110
+ function hasContainerPaint(style) {
111
+ var background = parseColor(style.backgroundColor);
112
+ if (
113
+ style.backgroundColor &&
114
+ style.backgroundColor !== "transparent" &&
115
+ (!background || background[3] > 0)
116
+ )
117
+ return true;
118
+ if (
119
+ ["backgroundImage", "boxShadow", "filter", "backdropFilter"].some(function (property) {
120
+ return style[property] && style[property] !== "none";
121
+ })
122
+ )
123
+ return true;
124
+ if (parseFloat(style.outlineWidth) > 0 && style.outlineStyle !== "none") return true;
125
+ return ["Top", "Right", "Bottom", "Left"].some(function (side) {
126
+ return (
127
+ parseFloat(style["border" + side + "Width"]) > 0 &&
128
+ style["border" + side + "Style"] !== "none"
129
+ );
130
+ });
131
+ }
132
+
133
+ function isUnpaintedCompositionBox(el) {
134
+ if (!el || !el.matches("[data-composition-id], [data-hf-inner-root]")) return false;
135
+ if (!el.closest("[data-composition-id]")) return false;
136
+ if (
137
+ el.namespaceURI !== "http://www.w3.org/1999/xhtml" ||
138
+ !COMPOSITION_BOX_TAGS.has(el.tagName) ||
139
+ el.shadowRoot
140
+ )
141
+ return false;
142
+ if (compositionBoxPaint.has(el)) return !compositionBoxPaint.get(el);
143
+ var painted =
144
+ Array.from(el.childNodes).some(function (child) {
145
+ return child.nodeType === 3 && (child.textContent || "").trim().length > 0;
146
+ }) || hasContainerPaint(getComputedStyle(el));
147
+ if (!painted) {
148
+ painted = ["::before", "::after"].some(function (pseudo) {
149
+ var content = getComputedStyle(el, pseudo).content;
150
+ return content && content !== "none" && content !== "normal";
151
+ });
152
+ }
153
+ compositionBoxPaint.set(el, !!painted);
154
+ return !painted;
155
+ }
156
+
157
+ function paintsAnyProbePoint(el, rect, skipCompositionBoxes) {
108
158
  // Keep probe resolution aligned with layout-audit.browser.js. Edge strips
109
159
  // narrower than the nearest probe point are treated as clipped away to
110
160
  // avoid noisy typewriter pre-reveal contrast reports.
@@ -112,8 +162,14 @@ window.__contrastAuditPrepare = function () {
112
162
  for (var ri = 0; ri < CLIP_PROBE_ROWS.length; ri++) {
113
163
  var x = rect.left + rect.width * CLIP_PROBE_COLS[ci];
114
164
  var y = rect.top + rect.height * CLIP_PROBE_ROWS[ri];
115
- var hit = document.elementFromPoint(x, y);
116
- if (hit === el || el.contains(hit)) return true;
165
+ var hits =
166
+ skipCompositionBoxes && typeof document.elementsFromPoint === "function"
167
+ ? document.elementsFromPoint(x, y)
168
+ : [document.elementFromPoint(x, y)];
169
+ for (var hit of hits) {
170
+ if (hit === el || el.contains(hit)) return true;
171
+ if (!skipCompositionBoxes || !isUnpaintedCompositionBox(hit)) break;
172
+ }
117
173
  }
118
174
  }
119
175
  return false;
@@ -135,7 +191,7 @@ window.__contrastAuditPrepare = function () {
135
191
  function isIntentionallyOccluded(el, rect) {
136
192
  if (typeof document.elementFromPoint !== "function") return false;
137
193
  if (!el.closest || !el.closest("[data-layout-allow-occlusion]")) return false;
138
- return !paintsAnyProbePoint(el, rect);
194
+ return !paintsAnyProbePoint(el, rect, true);
139
195
  }
140
196
 
141
197
  var out = [];
@@ -454,7 +454,7 @@
454
454
  const overflow = {};
455
455
  if (overflowX > tolerance) overflow.right = round(overflowX);
456
456
  if (overflowY > tolerance) overflow.bottom = round(overflowY);
457
- const selector = selectorFor(element);
457
+ const selector = uniqueSelectorFor(element);
458
458
  const text = textContentFor(element);
459
459
  const rect = toRect(element.getBoundingClientRect());
460
460
  const fontSize = parsePx(style.fontSize);
@@ -537,7 +537,7 @@
537
537
  const textRect = unionRects(lineRects);
538
538
  if (!textRect) return [];
539
539
  const text = textContentFor(element, true);
540
- const selector = selectorFor(element);
540
+ const selector = uniqueSelectorFor(element);
541
541
  const issues = [];
542
542
 
543
543
  const container = nearestConstraint(element, root, rootRect);
@@ -568,7 +568,7 @@
568
568
  severity: "error",
569
569
  time,
570
570
  selector,
571
- containerSelector: selectorFor(container),
571
+ containerSelector: uniqueSelectorFor(container),
572
572
  text,
573
573
  message: "Text extends outside its nearest visual/container box.",
574
574
  rect: visibleTextRect,
@@ -591,7 +591,7 @@
591
591
  severity: "info",
592
592
  time,
593
593
  selector,
594
- containerSelector: selectorFor(root),
594
+ containerSelector: uniqueSelectorFor(root),
595
595
  text,
596
596
  message: "Text extends outside the composition canvas.",
597
597
  rect: textRect,
@@ -644,8 +644,8 @@
644
644
  code: "container_overflow",
645
645
  severity: "warning",
646
646
  time,
647
- selector: selectorFor(child),
648
- containerSelector: selectorFor(container),
647
+ selector: uniqueSelectorFor(child),
648
+ containerSelector: uniqueSelectorFor(container),
649
649
  message: checksEveryChild
650
650
  ? "Element extends outside a clipping layout container."
651
651
  : "Nowrap text is wider than its container.",
@@ -1163,6 +1163,73 @@
1163
1163
  };
1164
1164
  }
1165
1165
 
1166
+ function layoutOffset(element) {
1167
+ let left = 0;
1168
+ let top = 0;
1169
+ for (let current = element; current instanceof HTMLElement; current = current.offsetParent) {
1170
+ left += current.offsetLeft;
1171
+ top += current.offsetTop;
1172
+ if (current !== element) {
1173
+ left += current.clientLeft;
1174
+ top += current.clientTop;
1175
+ }
1176
+ }
1177
+ return { left, top };
1178
+ }
1179
+
1180
+ function ancestorBackgroundPaintsText(element, textRect) {
1181
+ // Chromium 150+ includes independently painted descendants in text masks;
1182
+ // older builds drop their glyphs: https://github.com/heygen-com/hyperframes/issues/5117.
1183
+ const chromium = window.navigator.userAgent.match(/(?:HeadlessChrome|Chrome)\/(\d+)/);
1184
+ if (!chromium || Number(chromium[1]) < 150 || !(element instanceof HTMLElement)) return false;
1185
+
1186
+ for (
1187
+ let ancestor = element.parentElement;
1188
+ ancestor instanceof HTMLElement;
1189
+ ancestor = ancestor.parentElement
1190
+ ) {
1191
+ const style = getComputedStyle(ancestor);
1192
+ const clips = splitTopLevelCommas(
1193
+ style.webkitBackgroundClip || style.backgroundClip || "border-box",
1194
+ ).map((clip) => clip.trim());
1195
+ if (!clips.includes("text")) continue;
1196
+ // Chromium builds the mask before descendant transforms, so moving the
1197
+ // child must not move its glyphs out of the mask for this check.
1198
+ const offset = layoutOffset(element);
1199
+ const parentOffset = layoutOffset(ancestor);
1200
+ const elementRect = element.getBoundingClientRect();
1201
+ const scaleX = elementRect.width > 0 ? element.offsetWidth / elementRect.width : 1;
1202
+ const scaleY = elementRect.height > 0 ? element.offsetHeight / elementRect.height : 1;
1203
+ const backgroundRect = rectFromOrigin(0, 0, ancestor.offsetWidth, ancestor.offsetHeight);
1204
+ const overlaps =
1205
+ element.offsetWidth > 0 && element.offsetHeight > 0
1206
+ ? textClientRects(element, true).some((rect) => {
1207
+ const layoutRect = rectFromOrigin(
1208
+ offset.left - parentOffset.left + (rect.left - elementRect.left) * scaleX,
1209
+ offset.top - parentOffset.top + (rect.top - elementRect.top) * scaleY,
1210
+ rect.width * scaleX,
1211
+ rect.height * scaleY,
1212
+ );
1213
+ return intersectionArea(layoutRect, backgroundRect) > 0;
1214
+ })
1215
+ : !overflowFor(textRect, ancestor.getBoundingClientRect(), 2);
1216
+ if (!overlaps) continue;
1217
+
1218
+ const images = splitTopLevelCommas(style.backgroundImage || "none");
1219
+ const imagePaints = images.some(
1220
+ (image, index) =>
1221
+ clips[index % clips.length] === "text" &&
1222
+ /(?:linear|radial|conic)-gradient\(/i.test(image) &&
1223
+ gradientMaxAlpha(image) > 0.05,
1224
+ );
1225
+ const colorPaints =
1226
+ clips[(images.length - 1) % clips.length] === "text" &&
1227
+ colorAlpha(style.backgroundColor || "rgba(0, 0, 0, 0)") > 0.05;
1228
+ if (imagePaints || colorPaints) return true;
1229
+ }
1230
+ return false;
1231
+ }
1232
+
1166
1233
  // Text whose glyphs paint with an effectively transparent fill renders
1167
1234
  // invisibly even though the element, its box, opacity and color all read as
1168
1235
  // present — so geometry/occlusion/contrast audits miss it (contrast reads
@@ -1194,11 +1261,12 @@
1194
1261
  // clipped text. If nothing paints, fall through and report it.
1195
1262
  if (paintsGlyphs) return null;
1196
1263
  }
1264
+ if (ancestorBackgroundPaintsText(element, textRect)) return null;
1197
1265
  return {
1198
1266
  code: "text_not_painted",
1199
1267
  severity: "error",
1200
1268
  time,
1201
- selector: selectorFor(element),
1269
+ selector: uniqueSelectorFor(element),
1202
1270
  text,
1203
1271
  message:
1204
1272
  "Text paints with an effectively transparent fill (-webkit-text-fill-color / color), so its glyphs are invisible.",
@@ -1242,8 +1310,8 @@
1242
1310
  code: "escaped_container",
1243
1311
  severity: "warning",
1244
1312
  time,
1245
- selector: selectorFor(element),
1246
- containerSelector: selectorFor(parent),
1313
+ selector: uniqueSelectorFor(element),
1314
+ containerSelector: uniqueSelectorFor(parent),
1247
1315
  text: textContentFor(element),
1248
1316
  message:
1249
1317
  "Positioned element renders far outside its offset parent — its coordinates were likely computed in a different frame (canvas/viewport pixels).",
@@ -1319,8 +1387,8 @@
1319
1387
  code: "panel_out_of_canvas",
1320
1388
  severity: rectArea(rect) >= rootArea * PANEL_HERO_AREA_FRACTION ? "warning" : "info",
1321
1389
  time,
1322
- selector: selectorFor(element),
1323
- containerSelector: selectorFor(root),
1390
+ selector: uniqueSelectorFor(element),
1391
+ containerSelector: uniqueSelectorFor(root),
1324
1392
  text: textContentFor(element).slice(0, 48),
1325
1393
  message: "Painted panel extends outside the composition canvas.",
1326
1394
  rect,
@@ -1436,8 +1504,8 @@
1436
1504
  code: "canvas_content_at_edge",
1437
1505
  severity: "warning",
1438
1506
  time,
1439
- selector: selectorFor(canvas),
1440
- containerSelector: selectorFor(root),
1507
+ selector: uniqueSelectorFor(canvas),
1508
+ containerSelector: uniqueSelectorFor(root),
1441
1509
  message: `Canvas content touches the frame edge (${sides.join(", ")}).`,
1442
1510
  rect,
1443
1511
  containerRect: rootRect,
@@ -1605,8 +1673,8 @@
1605
1673
  code: "connector_detached",
1606
1674
  severity: "warning",
1607
1675
  time,
1608
- selector: selectorFor(path),
1609
- containerSelector: selectorFor(svg),
1676
+ selector: uniqueSelectorFor(path),
1677
+ containerSelector: uniqueSelectorFor(svg),
1610
1678
  message: pasteBug
1611
1679
  ? `Connector path endpoints render ${gap}px from the nearest anchorable element, but the path's user-space coordinates would attach if read as screen pixels — screen/viewport numbers were likely written into SVG \`d\` without inverting the CTM.`
1612
1680
  : `Connector path endpoints render ${gap}px from the nearest anchorable element — a marked shaft that meets no node.`,
@@ -1743,9 +1811,9 @@
1743
1811
  code: "connector_orphan",
1744
1812
  severity: "warning",
1745
1813
  time,
1746
- selector: selectorFor(path),
1747
- containerSelector: selectorFor(svg),
1748
- message: `Connector shaft is visible while ${dark.length === 2 ? "both endpoints are" : `its endpoint ${selectorFor(dark[0].element)} is`} not on stage.`,
1814
+ selector: uniqueSelectorFor(path),
1815
+ containerSelector: uniqueSelectorFor(svg),
1816
+ message: `Connector shaft is visible while ${dark.length === 2 ? "both endpoints are" : `its endpoint ${uniqueSelectorFor(dark[0].element)} is`} not on stage.`,
1749
1817
  rect: toRect({
1750
1818
  left: Math.min(rendered.start.x, rendered.end.x),
1751
1819
  top: Math.min(rendered.start.y, rendered.end.y),
@@ -1925,7 +1993,7 @@
1925
1993
  const box = element.getBoundingClientRect();
1926
1994
  if (box.width * box.height <= 400) continue;
1927
1995
  samples.push({
1928
- selector: selectorFor(element),
1996
+ selector: uniqueSelectorFor(element),
1929
1997
  cx: round(box.left + box.width / 2),
1930
1998
  cy: round(box.top + box.height / 2),
1931
1999
  w: round(box.width),
@@ -2113,7 +2181,7 @@
2113
2181
  hubCache.set(svg, hub);
2114
2182
  }
2115
2183
  samples.push({
2116
- selector: selectorFor(element),
2184
+ selector: uniqueSelectorFor(element),
2117
2185
  ax: round(a.x),
2118
2186
  ay: round(a.y),
2119
2187
  bx: round(b.x),