@nodaro/shared 1.4.2

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 (665) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +32 -0
  3. package/dist/index.cjs +12506 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +12269 -0
  6. package/dist/index.d.ts +12269 -0
  7. package/dist/index.js +11831 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +54 -0
  10. package/src/__tests__/__snapshots__/prompt-builder-segments.test.ts.snap +65 -0
  11. package/src/__tests__/ai-avatar-pricing.test.ts +321 -0
  12. package/src/__tests__/apply-video-negative-prompt.test.ts +76 -0
  13. package/src/__tests__/attach-columns.test.ts +28 -0
  14. package/src/__tests__/audio-crossfade-curves.test.ts +33 -0
  15. package/src/__tests__/build-model-menu.test.ts +58 -0
  16. package/src/__tests__/character-aspect-defaults.test.ts +142 -0
  17. package/src/__tests__/character-mention-slug.test.ts +199 -0
  18. package/src/__tests__/character-reference-photo-kinds.test.ts +32 -0
  19. package/src/__tests__/character-usage-mode.test.ts +147 -0
  20. package/src/__tests__/character-variant-assets.test.ts +142 -0
  21. package/src/__tests__/character-voice.test.ts +130 -0
  22. package/src/__tests__/cinematic-avatar-pricing.test.ts +119 -0
  23. package/src/__tests__/combine-transitions.test.ts +137 -0
  24. package/src/__tests__/component-types.test.ts +87 -0
  25. package/src/__tests__/condition-variables.test.ts +98 -0
  26. package/src/__tests__/credit-identifiers.test.ts +811 -0
  27. package/src/__tests__/default-video-provider.test.ts +63 -0
  28. package/src/__tests__/entity-image-handle.test.ts +43 -0
  29. package/src/__tests__/entity-variants.test.ts +33 -0
  30. package/src/__tests__/fal-lip-sync-sets.test.ts +31 -0
  31. package/src/__tests__/featured-entities.test.ts +33 -0
  32. package/src/__tests__/film-pricing.test.ts +64 -0
  33. package/src/__tests__/filter-condition.test.ts +285 -0
  34. package/src/__tests__/freecut-protocol.test.ts +35 -0
  35. package/src/__tests__/generate-text-items.test.ts +19 -0
  36. package/src/__tests__/generated-results.test.ts +50 -0
  37. package/src/__tests__/graph-utils.test.ts +618 -0
  38. package/src/__tests__/group-aggregation.test.ts +83 -0
  39. package/src/__tests__/i18n-locale-completeness.test.ts +156 -0
  40. package/src/__tests__/image-critic-node.test.ts +86 -0
  41. package/src/__tests__/image-mask-mode.test.ts +16 -0
  42. package/src/__tests__/image-ref-limit.test.ts +78 -0
  43. package/src/__tests__/inpaint-region.test.ts +24 -0
  44. package/src/__tests__/input-field-map-parity.test.ts +30 -0
  45. package/src/__tests__/json-evaluator.test.ts +289 -0
  46. package/src/__tests__/json-path.test.ts +64 -0
  47. package/src/__tests__/lip-sync-pricing.test.ts +142 -0
  48. package/src/__tests__/list-merge.test.ts +96 -0
  49. package/src/__tests__/list-sort.test.ts +134 -0
  50. package/src/__tests__/llm-models.test.ts +445 -0
  51. package/src/__tests__/location-mention-slug.test.ts +246 -0
  52. package/src/__tests__/locations-coverage-critic-schema.test.ts +92 -0
  53. package/src/__tests__/loop-delimiter.test.ts +39 -0
  54. package/src/__tests__/lottie-slots.test.ts +245 -0
  55. package/src/__tests__/model-catalog-flux2-resolutions.test.ts +21 -0
  56. package/src/__tests__/model-constants-location.test.ts +20 -0
  57. package/src/__tests__/model-constants.test.ts +122 -0
  58. package/src/__tests__/model-tree.test.ts +86 -0
  59. package/src/__tests__/no-internal-imports.test.ts +25 -0
  60. package/src/__tests__/node-default-mappings.test.ts +175 -0
  61. package/src/__tests__/node-mappable-fields.test.ts +7 -0
  62. package/src/__tests__/node-preset-export.test.ts +46 -0
  63. package/src/__tests__/node-preset-extract.test.ts +166 -0
  64. package/src/__tests__/node-refs-canonical.test.ts +54 -0
  65. package/src/__tests__/node-refs-combine.test.ts +54 -0
  66. package/src/__tests__/node-refs.test.ts +187 -0
  67. package/src/__tests__/node-runtime-keys.test.ts +99 -0
  68. package/src/__tests__/object-aspect-defaults.test.ts +59 -0
  69. package/src/__tests__/parameter-node-value.test.ts +137 -0
  70. package/src/__tests__/pinterest-url.test.ts +35 -0
  71. package/src/__tests__/pipeline-chat.test.ts +110 -0
  72. package/src/__tests__/pipeline-validation.test.ts +98 -0
  73. package/src/__tests__/presentation-utils.test.ts +1137 -0
  74. package/src/__tests__/producer-types.test.ts +47 -0
  75. package/src/__tests__/prompt-length-limits.test.ts +156 -0
  76. package/src/__tests__/provider-directive-defaults.test.ts +46 -0
  77. package/src/__tests__/reduce-strategy-registry.test.ts +43 -0
  78. package/src/__tests__/reference-board-templates.test.ts +33 -0
  79. package/src/__tests__/reference-roles.test.ts +36 -0
  80. package/src/__tests__/resolve-field-mappings.test.ts +110 -0
  81. package/src/__tests__/resolve-pipeline-model.test.ts +76 -0
  82. package/src/__tests__/scene-node-types.test.ts +80 -0
  83. package/src/__tests__/scraper-actors.test.ts +67 -0
  84. package/src/__tests__/seedance-2-catalog.test.ts +18 -0
  85. package/src/__tests__/seedance-2-credit-id.test.ts +23 -0
  86. package/src/__tests__/seedance-aspects.test.ts +52 -0
  87. package/src/__tests__/selector.test.ts +1151 -0
  88. package/src/__tests__/settled-with-limit.test.ts +214 -0
  89. package/src/__tests__/social-media-specs.test.ts +129 -0
  90. package/src/__tests__/sub-workflow-validation.test.ts +88 -0
  91. package/src/__tests__/switchx-pricing.test.ts +28 -0
  92. package/src/__tests__/to-connected-references.test.ts +153 -0
  93. package/src/__tests__/utilities.test.ts +541 -0
  94. package/src/__tests__/video-analysis-pricing.test.ts +58 -0
  95. package/src/__tests__/video-analysis.test.ts +63 -0
  96. package/src/__tests__/video-audio-capability.test.ts +204 -0
  97. package/src/__tests__/video-gen-providers.test.ts +28 -0
  98. package/src/__tests__/video-mode-aliases.test.ts +150 -0
  99. package/src/__tests__/video-ref-limits.test.ts +72 -0
  100. package/src/__tests__/video-utils.test.ts +303 -0
  101. package/src/__tests__/voice-changer-models.test.ts +33 -0
  102. package/src/__tests__/workflow-export-strip.test.ts +46 -0
  103. package/src/ai-avatar-pricing.ts +213 -0
  104. package/src/ancestor-refs.ts +48 -0
  105. package/src/animals.ts +231 -0
  106. package/src/audio-crossfade-curves.ts +73 -0
  107. package/src/audio-fx-presets.ts +64 -0
  108. package/src/avatar-payload-validators.ts +214 -0
  109. package/src/caption-styles.ts +31 -0
  110. package/src/character-aspect-defaults.ts +102 -0
  111. package/src/character-facets.ts +37 -0
  112. package/src/character-mention-slug.ts +166 -0
  113. package/src/character-usage-mode.ts +109 -0
  114. package/src/character-variant-assets.ts +121 -0
  115. package/src/character-voice.ts +151 -0
  116. package/src/cinematic-avatar-pricing.ts +111 -0
  117. package/src/clone-utils.ts +46 -0
  118. package/src/combine-transitions.ts +482 -0
  119. package/src/community.ts +112 -0
  120. package/src/component-types.ts +127 -0
  121. package/src/condition-variables.ts +65 -0
  122. package/src/credit-estimators/index.ts +15 -0
  123. package/src/credit-estimators/video-utils.ts +165 -0
  124. package/src/credit-identifiers.ts +304 -0
  125. package/src/entity-approval-types.ts +31 -0
  126. package/src/entity-aspect-defaults.ts +82 -0
  127. package/src/entity-asset-types.ts +296 -0
  128. package/src/entity-image-handle.ts +36 -0
  129. package/src/extra-refs.ts +139 -0
  130. package/src/featured-entities.ts +136 -0
  131. package/src/film-pricing.ts +117 -0
  132. package/src/filter-condition.ts +250 -0
  133. package/src/flux2-pricing.ts +18 -0
  134. package/src/freecut-protocol.ts +52 -0
  135. package/src/furniture.ts +167 -0
  136. package/src/generate-text-items.ts +15 -0
  137. package/src/generated-results.ts +63 -0
  138. package/src/group-aggregation.ts +75 -0
  139. package/src/hint-graph-types.ts +18 -0
  140. package/src/i18n/action-fx.ar.ts +89 -0
  141. package/src/i18n/action-fx.de.ts +89 -0
  142. package/src/i18n/action-fx.es.ts +89 -0
  143. package/src/i18n/action-fx.fr.ts +89 -0
  144. package/src/i18n/action-fx.he.ts +89 -0
  145. package/src/i18n/action-fx.hi.ts +89 -0
  146. package/src/i18n/action-fx.ja.ts +89 -0
  147. package/src/i18n/action-fx.ko.ts +89 -0
  148. package/src/i18n/action-fx.pt-BR.ts +89 -0
  149. package/src/i18n/action-fx.ru.ts +89 -0
  150. package/src/i18n/action-fx.zh-CN.ts +89 -0
  151. package/src/i18n/aesthetic.ar.ts +170 -0
  152. package/src/i18n/aesthetic.de.ts +48 -0
  153. package/src/i18n/aesthetic.es.ts +169 -0
  154. package/src/i18n/aesthetic.fr.ts +52 -0
  155. package/src/i18n/aesthetic.he.ts +169 -0
  156. package/src/i18n/aesthetic.hi.ts +55 -0
  157. package/src/i18n/aesthetic.ja.ts +165 -0
  158. package/src/i18n/aesthetic.ko.ts +169 -0
  159. package/src/i18n/aesthetic.pt-BR.ts +148 -0
  160. package/src/i18n/aesthetic.ru.ts +155 -0
  161. package/src/i18n/aesthetic.zh-CN.ts +172 -0
  162. package/src/i18n/animals.ar.ts +145 -0
  163. package/src/i18n/animals.de.ts +144 -0
  164. package/src/i18n/animals.es.ts +158 -0
  165. package/src/i18n/animals.fr.ts +144 -0
  166. package/src/i18n/animals.he.ts +155 -0
  167. package/src/i18n/animals.hi.ts +157 -0
  168. package/src/i18n/animals.ja.ts +159 -0
  169. package/src/i18n/animals.ko.ts +159 -0
  170. package/src/i18n/animals.pt-BR.ts +157 -0
  171. package/src/i18n/animals.ru.ts +155 -0
  172. package/src/i18n/animals.zh-CN.ts +155 -0
  173. package/src/i18n/atmosphere.ar.ts +49 -0
  174. package/src/i18n/atmosphere.de.ts +47 -0
  175. package/src/i18n/atmosphere.es.ts +50 -0
  176. package/src/i18n/atmosphere.fr.ts +47 -0
  177. package/src/i18n/atmosphere.he.ts +47 -0
  178. package/src/i18n/atmosphere.hi.ts +49 -0
  179. package/src/i18n/atmosphere.ja.ts +49 -0
  180. package/src/i18n/atmosphere.ko.ts +49 -0
  181. package/src/i18n/atmosphere.pt-BR.ts +49 -0
  182. package/src/i18n/atmosphere.ru.ts +47 -0
  183. package/src/i18n/atmosphere.zh-CN.ts +152 -0
  184. package/src/i18n/backdrop.ar.ts +53 -0
  185. package/src/i18n/backdrop.de.ts +46 -0
  186. package/src/i18n/backdrop.es.ts +54 -0
  187. package/src/i18n/backdrop.fr.ts +52 -0
  188. package/src/i18n/backdrop.he.ts +51 -0
  189. package/src/i18n/backdrop.hi.ts +59 -0
  190. package/src/i18n/backdrop.ja.ts +61 -0
  191. package/src/i18n/backdrop.ko.ts +59 -0
  192. package/src/i18n/backdrop.pt-BR.ts +59 -0
  193. package/src/i18n/backdrop.ru.ts +57 -0
  194. package/src/i18n/backdrop.zh-CN.ts +57 -0
  195. package/src/i18n/camera-format.ar.ts +40 -0
  196. package/src/i18n/camera-format.de.ts +37 -0
  197. package/src/i18n/camera-format.es.ts +41 -0
  198. package/src/i18n/camera-format.fr.ts +37 -0
  199. package/src/i18n/camera-format.he.ts +37 -0
  200. package/src/i18n/camera-format.hi.ts +42 -0
  201. package/src/i18n/camera-format.ja.ts +37 -0
  202. package/src/i18n/camera-format.ko.ts +37 -0
  203. package/src/i18n/camera-format.pt-BR.ts +46 -0
  204. package/src/i18n/camera-format.ru.ts +42 -0
  205. package/src/i18n/camera-format.zh-CN.ts +42 -0
  206. package/src/i18n/camera-motions.ar.ts +86 -0
  207. package/src/i18n/camera-motions.de.ts +74 -0
  208. package/src/i18n/camera-motions.es.ts +86 -0
  209. package/src/i18n/camera-motions.fr.ts +86 -0
  210. package/src/i18n/camera-motions.he.ts +86 -0
  211. package/src/i18n/camera-motions.hi.ts +99 -0
  212. package/src/i18n/camera-motions.ja.ts +99 -0
  213. package/src/i18n/camera-motions.ko.ts +99 -0
  214. package/src/i18n/camera-motions.pt-BR.ts +99 -0
  215. package/src/i18n/camera-motions.ru.ts +99 -0
  216. package/src/i18n/camera-motions.zh-CN.ts +99 -0
  217. package/src/i18n/character-fx.ar.ts +72 -0
  218. package/src/i18n/character-fx.de.ts +72 -0
  219. package/src/i18n/character-fx.es.ts +72 -0
  220. package/src/i18n/character-fx.fr.ts +72 -0
  221. package/src/i18n/character-fx.he.ts +72 -0
  222. package/src/i18n/character-fx.hi.ts +72 -0
  223. package/src/i18n/character-fx.ja.ts +72 -0
  224. package/src/i18n/character-fx.ko.ts +72 -0
  225. package/src/i18n/character-fx.pt-BR.ts +72 -0
  226. package/src/i18n/character-fx.ru.ts +72 -0
  227. package/src/i18n/character-fx.zh-CN.ts +72 -0
  228. package/src/i18n/color-look.ar.ts +50 -0
  229. package/src/i18n/color-look.de.ts +47 -0
  230. package/src/i18n/color-look.es.ts +50 -0
  231. package/src/i18n/color-look.fr.ts +50 -0
  232. package/src/i18n/color-look.he.ts +49 -0
  233. package/src/i18n/color-look.hi.ts +52 -0
  234. package/src/i18n/color-look.ja.ts +54 -0
  235. package/src/i18n/color-look.ko.ts +54 -0
  236. package/src/i18n/color-look.pt-BR.ts +54 -0
  237. package/src/i18n/color-look.ru.ts +52 -0
  238. package/src/i18n/color-look.zh-CN.ts +53 -0
  239. package/src/i18n/composition-effects.ar.ts +26 -0
  240. package/src/i18n/composition-effects.de.ts +25 -0
  241. package/src/i18n/composition-effects.es.ts +27 -0
  242. package/src/i18n/composition-effects.fr.ts +25 -0
  243. package/src/i18n/composition-effects.he.ts +25 -0
  244. package/src/i18n/composition-effects.hi.ts +27 -0
  245. package/src/i18n/composition-effects.ja.ts +27 -0
  246. package/src/i18n/composition-effects.ko.ts +27 -0
  247. package/src/i18n/composition-effects.pt-BR.ts +25 -0
  248. package/src/i18n/composition-effects.ru.ts +82 -0
  249. package/src/i18n/composition-effects.zh-CN.ts +25 -0
  250. package/src/i18n/era.ar.ts +37 -0
  251. package/src/i18n/era.de.ts +34 -0
  252. package/src/i18n/era.es.ts +37 -0
  253. package/src/i18n/era.fr.ts +37 -0
  254. package/src/i18n/era.he.ts +36 -0
  255. package/src/i18n/era.hi.ts +39 -0
  256. package/src/i18n/era.ja.ts +41 -0
  257. package/src/i18n/era.ko.ts +39 -0
  258. package/src/i18n/era.pt-BR.ts +41 -0
  259. package/src/i18n/era.ru.ts +121 -0
  260. package/src/i18n/era.zh-CN.ts +39 -0
  261. package/src/i18n/exposure-settings.ar.ts +28 -0
  262. package/src/i18n/exposure-settings.de.ts +26 -0
  263. package/src/i18n/exposure-settings.es.ts +28 -0
  264. package/src/i18n/exposure-settings.fr.ts +29 -0
  265. package/src/i18n/exposure-settings.he.ts +28 -0
  266. package/src/i18n/exposure-settings.hi.ts +31 -0
  267. package/src/i18n/exposure-settings.ja.ts +31 -0
  268. package/src/i18n/exposure-settings.ko.ts +31 -0
  269. package/src/i18n/exposure-settings.pt-BR.ts +31 -0
  270. package/src/i18n/exposure-settings.ru.ts +31 -0
  271. package/src/i18n/exposure-settings.zh-CN.ts +31 -0
  272. package/src/i18n/framing.ar.ts +78 -0
  273. package/src/i18n/framing.de.ts +73 -0
  274. package/src/i18n/framing.es.ts +78 -0
  275. package/src/i18n/framing.fr.ts +78 -0
  276. package/src/i18n/framing.he.ts +77 -0
  277. package/src/i18n/framing.hi.ts +82 -0
  278. package/src/i18n/framing.ja.ts +84 -0
  279. package/src/i18n/framing.ko.ts +82 -0
  280. package/src/i18n/framing.pt-BR.ts +84 -0
  281. package/src/i18n/framing.ru.ts +82 -0
  282. package/src/i18n/framing.zh-CN.ts +82 -0
  283. package/src/i18n/furniture.ar.ts +92 -0
  284. package/src/i18n/furniture.de.ts +93 -0
  285. package/src/i18n/furniture.es.ts +101 -0
  286. package/src/i18n/furniture.fr.ts +93 -0
  287. package/src/i18n/furniture.he.ts +101 -0
  288. package/src/i18n/furniture.hi.ts +101 -0
  289. package/src/i18n/furniture.ja.ts +101 -0
  290. package/src/i18n/furniture.ko.ts +101 -0
  291. package/src/i18n/furniture.pt-BR.ts +101 -0
  292. package/src/i18n/furniture.ru.ts +101 -0
  293. package/src/i18n/furniture.zh-CN.ts +101 -0
  294. package/src/i18n/held-prop.ar.ts +74 -0
  295. package/src/i18n/held-prop.de.ts +65 -0
  296. package/src/i18n/held-prop.es.ts +83 -0
  297. package/src/i18n/held-prop.fr.ts +74 -0
  298. package/src/i18n/held-prop.he.ts +73 -0
  299. package/src/i18n/held-prop.hi.ts +82 -0
  300. package/src/i18n/held-prop.ja.ts +84 -0
  301. package/src/i18n/held-prop.ko.ts +84 -0
  302. package/src/i18n/held-prop.pt-BR.ts +84 -0
  303. package/src/i18n/held-prop.ru.ts +82 -0
  304. package/src/i18n/held-prop.zh-CN.ts +82 -0
  305. package/src/i18n/index.ts +208 -0
  306. package/src/i18n/instrumentation.ar.ts +195 -0
  307. package/src/i18n/instrumentation.de.ts +195 -0
  308. package/src/i18n/instrumentation.es.ts +195 -0
  309. package/src/i18n/instrumentation.fr.ts +195 -0
  310. package/src/i18n/instrumentation.he.ts +195 -0
  311. package/src/i18n/instrumentation.hi.ts +195 -0
  312. package/src/i18n/instrumentation.ja.ts +195 -0
  313. package/src/i18n/instrumentation.ko.ts +195 -0
  314. package/src/i18n/instrumentation.pt-BR.ts +195 -0
  315. package/src/i18n/instrumentation.ru.ts +195 -0
  316. package/src/i18n/instrumentation.zh-CN.ts +195 -0
  317. package/src/i18n/lens.ar.ts +24 -0
  318. package/src/i18n/lens.de.ts +24 -0
  319. package/src/i18n/lens.es.ts +24 -0
  320. package/src/i18n/lens.fr.ts +24 -0
  321. package/src/i18n/lens.he.ts +24 -0
  322. package/src/i18n/lens.hi.ts +24 -0
  323. package/src/i18n/lens.ja.ts +24 -0
  324. package/src/i18n/lens.ko.ts +24 -0
  325. package/src/i18n/lens.pt-BR.ts +24 -0
  326. package/src/i18n/lens.ru.ts +25 -0
  327. package/src/i18n/lens.zh-CN.ts +24 -0
  328. package/src/i18n/lighting.ar.ts +86 -0
  329. package/src/i18n/lighting.de.ts +84 -0
  330. package/src/i18n/lighting.es.ts +89 -0
  331. package/src/i18n/lighting.fr.ts +84 -0
  332. package/src/i18n/lighting.he.ts +88 -0
  333. package/src/i18n/lighting.hi.ts +90 -0
  334. package/src/i18n/lighting.ja.ts +90 -0
  335. package/src/i18n/lighting.ko.ts +90 -0
  336. package/src/i18n/lighting.pt-BR.ts +90 -0
  337. package/src/i18n/lighting.ru.ts +88 -0
  338. package/src/i18n/lighting.zh-CN.ts +92 -0
  339. package/src/i18n/loop-subject.ar.ts +39 -0
  340. package/src/i18n/loop-subject.de.ts +39 -0
  341. package/src/i18n/loop-subject.es.ts +39 -0
  342. package/src/i18n/loop-subject.fr.ts +39 -0
  343. package/src/i18n/loop-subject.he.ts +39 -0
  344. package/src/i18n/loop-subject.hi.ts +39 -0
  345. package/src/i18n/loop-subject.ja.ts +39 -0
  346. package/src/i18n/loop-subject.ko.ts +39 -0
  347. package/src/i18n/loop-subject.pt-BR.ts +39 -0
  348. package/src/i18n/loop-subject.ru.ts +39 -0
  349. package/src/i18n/loop-subject.zh-CN.ts +39 -0
  350. package/src/i18n/materials.ar.ts +80 -0
  351. package/src/i18n/materials.de.ts +80 -0
  352. package/src/i18n/materials.es.ts +87 -0
  353. package/src/i18n/materials.fr.ts +80 -0
  354. package/src/i18n/materials.he.ts +86 -0
  355. package/src/i18n/materials.hi.ts +86 -0
  356. package/src/i18n/materials.ja.ts +88 -0
  357. package/src/i18n/materials.ko.ts +88 -0
  358. package/src/i18n/materials.pt-BR.ts +88 -0
  359. package/src/i18n/materials.ru.ts +86 -0
  360. package/src/i18n/materials.zh-CN.ts +86 -0
  361. package/src/i18n/mood.ar.ts +61 -0
  362. package/src/i18n/mood.de.ts +61 -0
  363. package/src/i18n/mood.es.ts +66 -0
  364. package/src/i18n/mood.fr.ts +61 -0
  365. package/src/i18n/mood.he.ts +64 -0
  366. package/src/i18n/mood.hi.ts +66 -0
  367. package/src/i18n/mood.ja.ts +66 -0
  368. package/src/i18n/mood.ko.ts +66 -0
  369. package/src/i18n/mood.pt-BR.ts +64 -0
  370. package/src/i18n/mood.ru.ts +64 -0
  371. package/src/i18n/mood.zh-CN.ts +64 -0
  372. package/src/i18n/music-genre.ar.ts +302 -0
  373. package/src/i18n/music-genre.de.ts +302 -0
  374. package/src/i18n/music-genre.es.ts +302 -0
  375. package/src/i18n/music-genre.fr.ts +302 -0
  376. package/src/i18n/music-genre.he.ts +302 -0
  377. package/src/i18n/music-genre.hi.ts +302 -0
  378. package/src/i18n/music-genre.ja.ts +302 -0
  379. package/src/i18n/music-genre.ko.ts +302 -0
  380. package/src/i18n/music-genre.pt-BR.ts +302 -0
  381. package/src/i18n/music-genre.ru.ts +302 -0
  382. package/src/i18n/music-genre.zh-CN.ts +302 -0
  383. package/src/i18n/music-mood.ar.ts +75 -0
  384. package/src/i18n/music-mood.de.ts +75 -0
  385. package/src/i18n/music-mood.es.ts +75 -0
  386. package/src/i18n/music-mood.fr.ts +75 -0
  387. package/src/i18n/music-mood.he.ts +75 -0
  388. package/src/i18n/music-mood.hi.ts +75 -0
  389. package/src/i18n/music-mood.ja.ts +75 -0
  390. package/src/i18n/music-mood.ko.ts +75 -0
  391. package/src/i18n/music-mood.pt-BR.ts +75 -0
  392. package/src/i18n/music-mood.ru.ts +75 -0
  393. package/src/i18n/music-mood.zh-CN.ts +75 -0
  394. package/src/i18n/person.ar.ts +638 -0
  395. package/src/i18n/person.de.ts +629 -0
  396. package/src/i18n/person.es.ts +645 -0
  397. package/src/i18n/person.fr.ts +621 -0
  398. package/src/i18n/person.he.ts +656 -0
  399. package/src/i18n/person.hi.ts +654 -0
  400. package/src/i18n/person.ja.ts +662 -0
  401. package/src/i18n/person.ko.ts +662 -0
  402. package/src/i18n/person.pt-BR.ts +656 -0
  403. package/src/i18n/person.ru.ts +656 -0
  404. package/src/i18n/person.zh-CN.ts +656 -0
  405. package/src/i18n/photo-genre.ar.ts +58 -0
  406. package/src/i18n/photo-genre.de.ts +52 -0
  407. package/src/i18n/photo-genre.es.ts +64 -0
  408. package/src/i18n/photo-genre.fr.ts +58 -0
  409. package/src/i18n/photo-genre.he.ts +62 -0
  410. package/src/i18n/photo-genre.hi.ts +63 -0
  411. package/src/i18n/photo-genre.ja.ts +65 -0
  412. package/src/i18n/photo-genre.ko.ts +63 -0
  413. package/src/i18n/photo-genre.pt-BR.ts +65 -0
  414. package/src/i18n/photo-genre.ru.ts +63 -0
  415. package/src/i18n/photo-genre.zh-CN.ts +63 -0
  416. package/src/i18n/photographer.ar.ts +75 -0
  417. package/src/i18n/photographer.de.ts +74 -0
  418. package/src/i18n/photographer.es.ts +77 -0
  419. package/src/i18n/photographer.fr.ts +77 -0
  420. package/src/i18n/photographer.he.ts +78 -0
  421. package/src/i18n/photographer.hi.ts +80 -0
  422. package/src/i18n/photographer.ja.ts +84 -0
  423. package/src/i18n/photographer.ko.ts +84 -0
  424. package/src/i18n/photographer.pt-BR.ts +83 -0
  425. package/src/i18n/photographer.ru.ts +78 -0
  426. package/src/i18n/photographer.zh-CN.ts +78 -0
  427. package/src/i18n/pose.ar.ts +95 -0
  428. package/src/i18n/pose.de.ts +96 -0
  429. package/src/i18n/pose.es.ts +104 -0
  430. package/src/i18n/pose.fr.ts +96 -0
  431. package/src/i18n/pose.he.ts +104 -0
  432. package/src/i18n/pose.hi.ts +104 -0
  433. package/src/i18n/pose.ja.ts +104 -0
  434. package/src/i18n/pose.ko.ts +104 -0
  435. package/src/i18n/pose.pt-BR.ts +104 -0
  436. package/src/i18n/pose.ru.ts +104 -0
  437. package/src/i18n/pose.zh-CN.ts +104 -0
  438. package/src/i18n/post-process-effects.ar.ts +25 -0
  439. package/src/i18n/post-process-effects.de.ts +24 -0
  440. package/src/i18n/post-process-effects.es.ts +26 -0
  441. package/src/i18n/post-process-effects.fr.ts +24 -0
  442. package/src/i18n/post-process-effects.he.ts +24 -0
  443. package/src/i18n/post-process-effects.hi.ts +26 -0
  444. package/src/i18n/post-process-effects.ja.ts +26 -0
  445. package/src/i18n/post-process-effects.ko.ts +26 -0
  446. package/src/i18n/post-process-effects.pt-BR.ts +24 -0
  447. package/src/i18n/post-process-effects.ru.ts +24 -0
  448. package/src/i18n/post-process-effects.zh-CN.ts +24 -0
  449. package/src/i18n/render-quality.ar.ts +34 -0
  450. package/src/i18n/render-quality.de.ts +30 -0
  451. package/src/i18n/render-quality.es.ts +35 -0
  452. package/src/i18n/render-quality.fr.ts +34 -0
  453. package/src/i18n/render-quality.he.ts +33 -0
  454. package/src/i18n/render-quality.hi.ts +39 -0
  455. package/src/i18n/render-quality.ja.ts +39 -0
  456. package/src/i18n/render-quality.ko.ts +39 -0
  457. package/src/i18n/render-quality.pt-BR.ts +37 -0
  458. package/src/i18n/render-quality.ru.ts +37 -0
  459. package/src/i18n/render-quality.zh-CN.ts +37 -0
  460. package/src/i18n/seasons.ar.ts +10 -0
  461. package/src/i18n/seasons.de.ts +10 -0
  462. package/src/i18n/seasons.es.ts +10 -0
  463. package/src/i18n/seasons.fr.ts +10 -0
  464. package/src/i18n/seasons.he.ts +10 -0
  465. package/src/i18n/seasons.hi.ts +10 -0
  466. package/src/i18n/seasons.ja.ts +10 -0
  467. package/src/i18n/seasons.ko.ts +10 -0
  468. package/src/i18n/seasons.pt-BR.ts +10 -0
  469. package/src/i18n/seasons.ru.ts +10 -0
  470. package/src/i18n/seasons.zh-CN.ts +10 -0
  471. package/src/i18n/setting.ar.ts +73 -0
  472. package/src/i18n/setting.de.ts +73 -0
  473. package/src/i18n/setting.es.ts +77 -0
  474. package/src/i18n/setting.fr.ts +73 -0
  475. package/src/i18n/setting.he.ts +76 -0
  476. package/src/i18n/setting.hi.ts +76 -0
  477. package/src/i18n/setting.ja.ts +78 -0
  478. package/src/i18n/setting.ko.ts +76 -0
  479. package/src/i18n/setting.pt-BR.ts +78 -0
  480. package/src/i18n/setting.ru.ts +76 -0
  481. package/src/i18n/setting.zh-CN.ts +76 -0
  482. package/src/i18n/style.ar.ts +55 -0
  483. package/src/i18n/style.de.ts +54 -0
  484. package/src/i18n/style.es.ts +54 -0
  485. package/src/i18n/style.fr.ts +54 -0
  486. package/src/i18n/style.he.ts +54 -0
  487. package/src/i18n/style.hi.ts +54 -0
  488. package/src/i18n/style.ja.ts +54 -0
  489. package/src/i18n/style.ko.ts +54 -0
  490. package/src/i18n/style.pt-BR.ts +56 -0
  491. package/src/i18n/style.ru.ts +54 -0
  492. package/src/i18n/style.zh-CN.ts +54 -0
  493. package/src/i18n/styling.ar.ts +295 -0
  494. package/src/i18n/styling.de.ts +285 -0
  495. package/src/i18n/styling.es.ts +317 -0
  496. package/src/i18n/styling.fr.ts +285 -0
  497. package/src/i18n/styling.he.ts +307 -0
  498. package/src/i18n/styling.hi.ts +323 -0
  499. package/src/i18n/styling.ja.ts +317 -0
  500. package/src/i18n/styling.ko.ts +311 -0
  501. package/src/i18n/styling.pt-BR.ts +301 -0
  502. package/src/i18n/styling.ru.ts +301 -0
  503. package/src/i18n/styling.zh-CN.ts +307 -0
  504. package/src/i18n/temporal.ar.ts +31 -0
  505. package/src/i18n/temporal.de.ts +24 -0
  506. package/src/i18n/temporal.es.ts +27 -0
  507. package/src/i18n/temporal.fr.ts +28 -0
  508. package/src/i18n/temporal.he.ts +31 -0
  509. package/src/i18n/temporal.hi.ts +31 -0
  510. package/src/i18n/temporal.ja.ts +31 -0
  511. package/src/i18n/temporal.ko.ts +31 -0
  512. package/src/i18n/temporal.pt-BR.ts +31 -0
  513. package/src/i18n/temporal.ru.ts +31 -0
  514. package/src/i18n/temporal.zh-CN.ts +31 -0
  515. package/src/i18n/transitions.ar.ts +97 -0
  516. package/src/i18n/transitions.de.ts +97 -0
  517. package/src/i18n/transitions.es.ts +97 -0
  518. package/src/i18n/transitions.fr.ts +97 -0
  519. package/src/i18n/transitions.he.ts +97 -0
  520. package/src/i18n/transitions.hi.ts +97 -0
  521. package/src/i18n/transitions.ja.ts +97 -0
  522. package/src/i18n/transitions.ko.ts +97 -0
  523. package/src/i18n/transitions.pt-BR.ts +97 -0
  524. package/src/i18n/transitions.ru.ts +97 -0
  525. package/src/i18n/transitions.zh-CN.ts +97 -0
  526. package/src/i18n/types.ts +158 -0
  527. package/src/i18n/vehicles.ar.ts +137 -0
  528. package/src/i18n/vehicles.de.ts +125 -0
  529. package/src/i18n/vehicles.es.ts +138 -0
  530. package/src/i18n/vehicles.fr.ts +125 -0
  531. package/src/i18n/vehicles.he.ts +136 -0
  532. package/src/i18n/vehicles.hi.ts +138 -0
  533. package/src/i18n/vehicles.ja.ts +138 -0
  534. package/src/i18n/vehicles.ko.ts +138 -0
  535. package/src/i18n/vehicles.pt-BR.ts +136 -0
  536. package/src/i18n/vehicles.ru.ts +136 -0
  537. package/src/i18n/vehicles.zh-CN.ts +136 -0
  538. package/src/i18n/voice-character.ar.ts +126 -0
  539. package/src/i18n/voice-character.de.ts +126 -0
  540. package/src/i18n/voice-character.es.ts +126 -0
  541. package/src/i18n/voice-character.fr.ts +126 -0
  542. package/src/i18n/voice-character.he.ts +126 -0
  543. package/src/i18n/voice-character.hi.ts +126 -0
  544. package/src/i18n/voice-character.ja.ts +126 -0
  545. package/src/i18n/voice-character.ko.ts +126 -0
  546. package/src/i18n/voice-character.pt-BR.ts +126 -0
  547. package/src/i18n/voice-character.ru.ts +126 -0
  548. package/src/i18n/voice-character.zh-CN.ts +126 -0
  549. package/src/i18n/voice-delivery.ar.ts +77 -0
  550. package/src/i18n/voice-delivery.de.ts +77 -0
  551. package/src/i18n/voice-delivery.es.ts +77 -0
  552. package/src/i18n/voice-delivery.fr.ts +77 -0
  553. package/src/i18n/voice-delivery.he.ts +77 -0
  554. package/src/i18n/voice-delivery.hi.ts +77 -0
  555. package/src/i18n/voice-delivery.ja.ts +77 -0
  556. package/src/i18n/voice-delivery.ko.ts +77 -0
  557. package/src/i18n/voice-delivery.pt-BR.ts +77 -0
  558. package/src/i18n/voice-delivery.ru.ts +77 -0
  559. package/src/i18n/voice-delivery.zh-CN.ts +77 -0
  560. package/src/i18n/weapons.ar.ts +115 -0
  561. package/src/i18n/weapons.de.ts +114 -0
  562. package/src/i18n/weapons.es.ts +116 -0
  563. package/src/i18n/weapons.fr.ts +103 -0
  564. package/src/i18n/weapons.he.ts +114 -0
  565. package/src/i18n/weapons.hi.ts +116 -0
  566. package/src/i18n/weapons.ja.ts +116 -0
  567. package/src/i18n/weapons.ko.ts +116 -0
  568. package/src/i18n/weapons.pt-BR.ts +114 -0
  569. package/src/i18n/weapons.ru.ts +114 -0
  570. package/src/i18n/weapons.zh-CN.ts +114 -0
  571. package/src/image-critic-node.ts +61 -0
  572. package/src/image-critic-types.ts +40 -0
  573. package/src/index.ts +866 -0
  574. package/src/inject-upstream.ts +15 -0
  575. package/src/inpaint-region.ts +51 -0
  576. package/src/json-evaluator.ts +732 -0
  577. package/src/json-path.ts +52 -0
  578. package/src/lip-sync-pricing.ts +90 -0
  579. package/src/list-merge.ts +40 -0
  580. package/src/list-sort.ts +122 -0
  581. package/src/list-source-resolver.ts +50 -0
  582. package/src/llm-models.ts +245 -0
  583. package/src/location-mention-slug.ts +291 -0
  584. package/src/location-preset-catalog-map.ts +128 -0
  585. package/src/loop-delimiter.ts +73 -0
  586. package/src/lora-routing.ts +95 -0
  587. package/src/lottie-overlay-catalog.ts +175 -0
  588. package/src/lottie-slots.ts +309 -0
  589. package/src/model-catalog.ts +2386 -0
  590. package/src/model-constants.ts +1910 -0
  591. package/src/model-tree.ts +120 -0
  592. package/src/monetization.ts +15 -0
  593. package/src/multi-pick.ts +42 -0
  594. package/src/node-default-mappings.ts +262 -0
  595. package/src/node-mappable-fields.ts +70 -0
  596. package/src/node-preset-export.ts +56 -0
  597. package/src/node-preset-extract.ts +147 -0
  598. package/src/node-refs.ts +253 -0
  599. package/src/node-runtime-keys.ts +117 -0
  600. package/src/object-aspect-defaults.ts +72 -0
  601. package/src/object-picker-types.ts +22 -0
  602. package/src/parameter-node-value.ts +284 -0
  603. package/src/pinterest-url.ts +28 -0
  604. package/src/pipeline-chat.ts +72 -0
  605. package/src/pipeline-defaults.ts +318 -0
  606. package/src/pipeline-events.ts +162 -0
  607. package/src/pipeline-state-types.ts +196 -0
  608. package/src/pipeline-types.ts +647 -0
  609. package/src/pipeline-validation.ts +87 -0
  610. package/src/presentation-types.ts +23 -0
  611. package/src/presentation-utils.ts +397 -0
  612. package/src/producer-types.ts +188 -0
  613. package/src/progress-curve.ts +99 -0
  614. package/src/provider-directive-defaults.ts +69 -0
  615. package/src/reduce-strategy-registry.ts +121 -0
  616. package/src/reference-board-templates.ts +81 -0
  617. package/src/reference-roles.ts +153 -0
  618. package/src/reference-sheet/__tests__/board-to-column.test.ts +20 -0
  619. package/src/reference-sheet/__tests__/catalog.test.ts +50 -0
  620. package/src/reference-sheet/__tests__/cost.test.ts +38 -0
  621. package/src/reference-sheet/__tests__/no-drift.test.ts +28 -0
  622. package/src/reference-sheet/__tests__/panel-plan.test.ts +61 -0
  623. package/src/reference-sheet/__tests__/panel-prompts.test.ts +17 -0
  624. package/src/reference-sheet/__tests__/plan-generation.test.ts +72 -0
  625. package/src/reference-sheet/__tests__/presets.test.ts +54 -0
  626. package/src/reference-sheet/__tests__/types.test.ts +24 -0
  627. package/src/reference-sheet/catalog.ts +144 -0
  628. package/src/reference-sheet/cost.ts +37 -0
  629. package/src/reference-sheet/credit-id.ts +7 -0
  630. package/src/reference-sheet/index.ts +8 -0
  631. package/src/reference-sheet/panel-plan.ts +65 -0
  632. package/src/reference-sheet/panel-prompts.ts +14 -0
  633. package/src/reference-sheet/plan-generation.ts +79 -0
  634. package/src/reference-sheet/presets.ts +77 -0
  635. package/src/reference-sheet/types.ts +92 -0
  636. package/src/repeat-types.ts +97 -0
  637. package/src/resolve-field-mappings.ts +119 -0
  638. package/src/route-filter.ts +80 -0
  639. package/src/scene-helper-types.ts +249 -0
  640. package/src/scene-node-types.ts +281 -0
  641. package/src/scraper-actors.ts +57 -0
  642. package/src/scraper-output-schemas.ts +25 -0
  643. package/src/seasons.ts +45 -0
  644. package/src/selector.ts +864 -0
  645. package/src/settled-with-limit.ts +42 -0
  646. package/src/shot-element.ts +43 -0
  647. package/src/social-media-specs.ts +121 -0
  648. package/src/social-post.ts +24 -0
  649. package/src/sub-workflow-validation.ts +78 -0
  650. package/src/supported-fonts.ts +40 -0
  651. package/src/surround.ts +113 -0
  652. package/src/switchx-pricing.ts +33 -0
  653. package/src/text-separators.ts +59 -0
  654. package/src/to-connected-references.ts +77 -0
  655. package/src/types.ts +272 -0
  656. package/src/variant-job-id.ts +17 -0
  657. package/src/vehicles.ts +213 -0
  658. package/src/video-analysis-pricing.ts +74 -0
  659. package/src/video-analysis.ts +127 -0
  660. package/src/video-duration.ts +25 -0
  661. package/src/voice-changer-models.ts +36 -0
  662. package/src/voice-matcher-types.ts +37 -0
  663. package/src/voices.ts +92 -0
  664. package/src/weapons.ts +190 -0
  665. package/src/workflow-export.ts +153 -0
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Built-in Lottie Overlay catalog — single source of truth.
3
+ *
4
+ * The Lottie Overlay node ships a curated set of 12 animations the overlay LLM
5
+ * can pick from. They were originally served from the third-party lottie.host
6
+ * CDN, which went dead (origin returns 403) and broke every catalog-based
7
+ * overlay render in production. The replacements were authored with our own
8
+ * Lottie engine, baked (slots resolved, no `sid` refs), and are now self-hosted
9
+ * on the Nodaro CDN at `https://cdn.nodaro.ai/lottie-catalog/<slug>.json`.
10
+ *
11
+ * This module is the ONE place the catalog lives:
12
+ * - `LOTTIE_OVERLAY_CATALOG` feeds the overlay system prompt (the LLM's menu).
13
+ * - `LEGACY_LOTTIE_HOST_REMAP` + `resolveLottieOverlaySrc` heal saved overlay
14
+ * plans at render time — a plan authored before the cut-over still points at
15
+ * a dead lottie.host URL, so the renderer rewrites it to its self-hosted
16
+ * replacement before fetching.
17
+ */
18
+
19
+ export interface LottieOverlayCatalogEntry {
20
+ /** Stable system key — the R2 object is `lottie-catalog/<slug>.json`. */
21
+ readonly slug: string
22
+ /** Display name — mirrors the original prompt's catalog labels. */
23
+ readonly name: string
24
+ /** Catalog group (drives the grouped layout in the system prompt). */
25
+ readonly group:
26
+ | "Celebration"
27
+ | "Social / Reactions"
28
+ | "UI / Indicators"
29
+ | "Ambient / Decorative"
30
+ /** One placement-intent line for the overlay LLM. */
31
+ readonly description: string
32
+ /** Public CDN URL: `https://cdn.nodaro.ai/lottie-catalog/<slug>.json`. */
33
+ readonly url: string
34
+ /** Whether the animation is continuous (loop) or a one-shot effect. */
35
+ readonly loop: boolean
36
+ }
37
+
38
+ const CDN_BASE = "https://cdn.nodaro.ai/lottie-catalog"
39
+
40
+ export const LOTTIE_OVERLAY_CATALOG: readonly LottieOverlayCatalogEntry[] = [
41
+ // ── Celebration ────────────────────────────────────────────────────────────
42
+ {
43
+ slug: "confetti-burst",
44
+ name: "Confetti burst",
45
+ group: "Celebration",
46
+ description: "Multicolor confetti shower — large coverage at a celebratory peak; one-shot.",
47
+ url: `${CDN_BASE}/confetti-burst.json`,
48
+ loop: false,
49
+ },
50
+ {
51
+ slug: "fireworks",
52
+ name: "Fireworks",
53
+ group: "Celebration",
54
+ description: "Bursting fireworks against the sky — big-moment payoff over the upper frame; one-shot.",
55
+ url: `${CDN_BASE}/fireworks.json`,
56
+ loop: false,
57
+ },
58
+ {
59
+ slug: "party-popper",
60
+ name: "Party popper",
61
+ group: "Celebration",
62
+ description: "Party popper streamers from a corner — a quick celebratory accent; one-shot.",
63
+ url: `${CDN_BASE}/party-popper.json`,
64
+ loop: false,
65
+ },
66
+ {
67
+ slug: "stars-sparkle",
68
+ name: "Stars sparkle",
69
+ group: "Celebration",
70
+ description: "Twinkling stars/sparkles — small accent over a highlight; loops.",
71
+ url: `${CDN_BASE}/stars-sparkle.json`,
72
+ loop: true,
73
+ },
74
+ // ── Social / Reactions ──────────────────────────────────────────────────────
75
+ {
76
+ slug: "heart-pulse",
77
+ name: "Heart pulse",
78
+ group: "Social / Reactions",
79
+ description: "Pulsing heart reaction — medium size at a corner or edge; loops.",
80
+ url: `${CDN_BASE}/heart-pulse.json`,
81
+ loop: true,
82
+ },
83
+ {
84
+ slug: "thumbs-up",
85
+ name: "Thumbs up",
86
+ group: "Social / Reactions",
87
+ description: "Thumbs-up approval reaction — medium size, pops in once; one-shot.",
88
+ url: `${CDN_BASE}/thumbs-up.json`,
89
+ loop: false,
90
+ },
91
+ {
92
+ slug: "fire-flame",
93
+ name: "Fire emoji",
94
+ group: "Social / Reactions",
95
+ description: "Flickering flame reaction (“this is fire”) — small size at an edge; loops.",
96
+ url: `${CDN_BASE}/fire-flame.json`,
97
+ loop: true,
98
+ },
99
+ // ── UI / Indicators ─────────────────────────────────────────────────────────
100
+ {
101
+ slug: "loading-spinner",
102
+ name: "Loading spinner",
103
+ group: "UI / Indicators",
104
+ description: "Circular loading spinner — small, centered, signals progress; loops.",
105
+ url: `${CDN_BASE}/loading-spinner.json`,
106
+ loop: true,
107
+ },
108
+ {
109
+ slug: "checkmark-success",
110
+ name: "Checkmark success",
111
+ group: "UI / Indicators",
112
+ description: "Animated success checkmark — small, marks a completed/correct moment; one-shot.",
113
+ url: `${CDN_BASE}/checkmark-success.json`,
114
+ loop: false,
115
+ },
116
+ {
117
+ slug: "arrow-pointer",
118
+ name: "Arrow pointer",
119
+ group: "UI / Indicators",
120
+ description: "Animated arrow drawing attention to a spot — small, timed to a key area; loops.",
121
+ url: `${CDN_BASE}/arrow-pointer.json`,
122
+ loop: true,
123
+ },
124
+ // ── Ambient / Decorative ────────────────────────────────────────────────────
125
+ {
126
+ slug: "floating-particles",
127
+ name: "Floating particles",
128
+ group: "Ambient / Decorative",
129
+ description: "Soft drifting particles — large coverage, low opacity, full-duration ambience; loops.",
130
+ url: `${CDN_BASE}/floating-particles.json`,
131
+ loop: true,
132
+ },
133
+ {
134
+ slug: "glowing-ring",
135
+ name: "Glowing ring",
136
+ group: "Ambient / Decorative",
137
+ description: "Pulsing glowing ring/halo — decorative accent around a focal point; loops.",
138
+ url: `${CDN_BASE}/glowing-ring.json`,
139
+ loop: true,
140
+ },
141
+ ] as const
142
+
143
+ /**
144
+ * Dead lottie.host URLs (origin returns 403) → their replacement catalog URLs.
145
+ * Heals saved plans at render time. The keys are copied EXACTLY from the
146
+ * original `lottie-overlay-system.ts` prompt — they are the literal `src`
147
+ * strings the overlay LLM emitted before the cut-over.
148
+ */
149
+ export const LEGACY_LOTTIE_HOST_REMAP: Readonly<Record<string, string>> = {
150
+ // Celebration
151
+ "https://lottie.host/d7313e87-e4c9-4e0d-8e03-c3a59e87d8fb/TjHnrCGBjI.json": `${CDN_BASE}/confetti-burst.json`,
152
+ "https://lottie.host/d5cad0dd-4e93-4bbe-b023-e94a04bc1581/JHEZMrqfMk.json": `${CDN_BASE}/fireworks.json`,
153
+ "https://lottie.host/0060c9cd-75da-42d5-af7c-1a191fa8a8fd/c1xHMRnGTO.json": `${CDN_BASE}/party-popper.json`,
154
+ "https://lottie.host/c04a2758-a1d9-40a9-b81f-6f3e4e13a88c/xKCYDU2w0O.json": `${CDN_BASE}/stars-sparkle.json`,
155
+ // Social / Reactions
156
+ "https://lottie.host/44c9e8d1-856c-4641-bfbe-d0e2a5c9850e/GIBsMSIkkq.json": `${CDN_BASE}/heart-pulse.json`,
157
+ "https://lottie.host/9a611d56-1f35-4f51-9fa4-6a4daa6b8714/EH71MjHKPD.json": `${CDN_BASE}/thumbs-up.json`,
158
+ "https://lottie.host/66db1de9-c1a8-4d0b-bb03-47a8932a8a86/q5JBGQ8fxu.json": `${CDN_BASE}/fire-flame.json`,
159
+ // UI / Indicators
160
+ "https://lottie.host/b03d748c-3b4a-4c07-a10c-e9eb3c967349/eMVAVEnb5x.json": `${CDN_BASE}/loading-spinner.json`,
161
+ "https://lottie.host/3ffaab4a-58b0-4a72-9f1c-5eaa484d8c88/g27v7IPaJc.json": `${CDN_BASE}/checkmark-success.json`,
162
+ "https://lottie.host/6f831c6e-693a-4d1d-90a0-d7e2b3f00e68/PFj0MwSPrj.json": `${CDN_BASE}/arrow-pointer.json`,
163
+ // Ambient / Decorative
164
+ "https://lottie.host/9c8e1aef-f8e5-4ce8-bc80-1647ffb0724d/mNDClfKJVB.json": `${CDN_BASE}/floating-particles.json`,
165
+ "https://lottie.host/b5d3e7e7-40bc-44fa-9a53-78b98ad66e80/pQVdNsVDmQ.json": `${CDN_BASE}/glowing-ring.json`,
166
+ }
167
+
168
+ /**
169
+ * Resolve an overlay `src` through the legacy remap: a dead lottie.host URL is
170
+ * rewritten to its self-hosted replacement; everything else (already-migrated
171
+ * catalog URLs, user-provided assets) passes through unchanged.
172
+ */
173
+ export function resolveLottieOverlaySrc(src: string): string {
174
+ return LEGACY_LOTTIE_HOST_REMAP[src] ?? src
175
+ }
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Lottie slot substitution — single source of truth (design §5).
3
+ *
4
+ * A slotted property is an object containing a `sid` key (canonically exactly
5
+ * `{"sid": "name"}`; tolerantly also the annotation form `{a, k, sid}`). The
6
+ * slot manifest maps sid → { p: <whatever belongs at the reference position> }.
7
+ * Overrides map sid → raw value (what UI controls write).
8
+ *
9
+ * KEY CONVENTION: a slot's `p` is, by design, EXACTLY what belongs at the
10
+ * reference position — and we substitute it VERBATIM, never auto-wrapping it in
11
+ * an `{a:0,k:...}` envelope. At a property position (a fill color, a shape size)
12
+ * that means `p` is a property object like `{"a":0,"k":[1,0,0,1]}`. At a RAW
13
+ * position inside a text document — `layers[].t.d.k[0].s.t`, where lottie-web's
14
+ * `buildFinalText` iterates string characters — `p` is a BARE string, e.g.
15
+ * `{ "nameText": { "p": "John Smith" } }` substitutes the string `"John Smith"`
16
+ * straight onto `s.t`. (Auto-wrapping there produced `{a:0,k:"John Smith"}` and
17
+ * broke text rendering — the defect this contract fixes.)
18
+ *
19
+ * An override is wrapped ONLY when it lands on a property-object default: the
20
+ * `{...p, k: override}` form preserves the default's envelope (animated/static
21
+ * flags). On a raw default (or a missing slot) the override is substituted
22
+ * verbatim too — so a raw text override stays a bare string.
23
+ *
24
+ * Substitution is renderer-agnostic: we replace every sid node ourselves and
25
+ * never rely on lottie-web's version-dependent native slot support.
26
+ */
27
+
28
+ type JsonRecord = Record<string, unknown>
29
+
30
+ function isPlainObject(v: unknown): v is JsonRecord {
31
+ return typeof v === "object" && v !== null && !Array.isArray(v)
32
+ }
33
+
34
+ /** True when `p` already looks like a lottie animated-property object. */
35
+ function isPropertyObject(v: unknown): v is JsonRecord {
36
+ return isPlainObject(v) && "k" in v
37
+ }
38
+
39
+ function resolveSlotNode(
40
+ node: JsonRecord,
41
+ slots: JsonRecord,
42
+ overrides: JsonRecord,
43
+ ): unknown {
44
+ const sid = node.sid as string
45
+ const slot = slots[sid]
46
+ const slotP = isPlainObject(slot) ? (slot as JsonRecord).p : undefined
47
+ const override = overrides[sid]
48
+
49
+ if (override !== undefined) {
50
+ // Wrap into the default's property-object envelope when the default IS one
51
+ // (preserves animated/static flags); otherwise substitute the raw override
52
+ // verbatim — a raw text override must stay a bare string at `s.t`.
53
+ if (isPropertyObject(slotP)) return { ...slotP, k: structuredClone(override) }
54
+ return structuredClone(override)
55
+ }
56
+ if (slotP !== undefined) {
57
+ // `p` is by convention exactly what belongs at the reference position —
58
+ // substitute it verbatim, never auto-wrap (a bare string stays a string).
59
+ return structuredClone(slotP)
60
+ }
61
+ // No slot, no override — leave the node as-is (validator rule #6 should
62
+ // prevent this; belt-and-braces for hand-fed documents).
63
+ return node
64
+ }
65
+
66
+ function walk(value: unknown, slots: JsonRecord, overrides: JsonRecord): unknown {
67
+ if (Array.isArray(value)) {
68
+ return value.map((item) => walk(item, slots, overrides))
69
+ }
70
+ if (isPlainObject(value)) {
71
+ if (typeof value.sid === "string") {
72
+ const resolved = resolveSlotNode(value, slots, overrides)
73
+ // The original node comes back only in the missing-slot case; replacements
74
+ // are leaf property objects and need no further walking.
75
+ if (resolved === value) {
76
+ const copy: JsonRecord = {}
77
+ for (const [k, v] of Object.entries(value)) copy[k] = walk(v, slots, overrides)
78
+ return copy
79
+ }
80
+ return resolved
81
+ }
82
+ const copy: JsonRecord = {}
83
+ for (const [k, v] of Object.entries(value)) copy[k] = walk(v, slots, overrides)
84
+ return copy
85
+ }
86
+ return value
87
+ }
88
+
89
+ /** Pure: returns a new document; never mutates inputs. */
90
+ export function applySlots(
91
+ lottie: JsonRecord,
92
+ slots: JsonRecord | undefined,
93
+ overrides: JsonRecord | undefined,
94
+ ): JsonRecord {
95
+ return walk(lottie, slots ?? {}, overrides ?? {}) as JsonRecord
96
+ }
97
+
98
+ // ── Playback normalization ───────────────────────────────────────────────────
99
+ //
100
+ // lottie-web computes a layer's local time as `frame - layer.st` and gates the
101
+ // layer on `local >= ip && local < op`. A layer missing `st` yields NaN, fails
102
+ // the gate, and stays `display:none` forever — the document "loads" (DOMLoaded
103
+ // fires) but every frame renders blank (prod incident 2026-06-12: all authored
104
+ // lottie renders came out as empty frames in headless Chrome). `st` and `sr`
105
+ // are spec-optional with defaults, so documents routinely omit them; complete
106
+ // them at the playback boundary so any source — authored plan, baked export,
107
+ // catalog asset, external URL — renders. Mutates `doc` in place and returns it
108
+ // (callers pass freshly fetched or freshly copied documents).
109
+
110
+ export function normalizeLottieLayers<T>(doc: T): T {
111
+ if (!isPlainObject(doc)) return doc
112
+ const fix = (layers: unknown): void => {
113
+ if (!Array.isArray(layers)) return
114
+ for (const layer of layers) {
115
+ if (!isPlainObject(layer)) continue
116
+ if (typeof layer.st !== "number") layer.st = 0
117
+ if (typeof layer.sr !== "number") layer.sr = 1
118
+ }
119
+ }
120
+ fix((doc as JsonRecord).layers)
121
+ const assets = (doc as JsonRecord).assets
122
+ if (Array.isArray(assets)) {
123
+ for (const asset of assets) {
124
+ if (isPlainObject(asset)) fix(asset.layers)
125
+ }
126
+ }
127
+ return doc
128
+ }
129
+
130
+ // ── Slot control descriptors (Phase 2 — UI mapping) ──────────────────────────
131
+ //
132
+ // A slot manifest entry is `{ p: <whatever belongs at the reference position> }`
133
+ // (Amendment 1). `describeSlotControl` unwraps that envelope to the editable raw
134
+ // value and classifies it into the control kind the config panel should render.
135
+ // `p` is either a property object `{a, k}` (colors, sizes, scalars) whose `k`
136
+ // holds the value, or a bare raw value (text strings live unwrapped at `s.t`).
137
+
138
+ export type SlotControlKind = "color" | "text" | "number" | "point"
139
+ export interface SlotControlDescriptor {
140
+ kind: SlotControlKind
141
+ value: unknown
142
+ }
143
+
144
+ /**
145
+ * Unwraps a slot entry to its editable raw value and classifies it:
146
+ * {p:{a:0,k:[1,0,0,1]}} → { kind:"color", value:[1,0,0,1] }
147
+ * {p:"John"} → { kind:"text", value:"John" }
148
+ * {p:{a:0,k:42}} → { kind:"number", value:42 }
149
+ * {p:{a:0,k:[10,20]}} → { kind:"point", value:[10,20] }
150
+ * Animated property objects (`a:1`) and anything that doesn't map to a known
151
+ * control kind return null (no editable control).
152
+ */
153
+ export function describeSlotControl(slot: unknown): SlotControlDescriptor | null {
154
+ if (!isPlainObject(slot)) return null
155
+ const p = (slot as JsonRecord).p
156
+ let value: unknown = p
157
+ if (isPropertyObject(p)) {
158
+ if ((p as JsonRecord).a === 1) return null
159
+ value = (p as JsonRecord).k
160
+ }
161
+ if (typeof value === "string") return { kind: "text", value }
162
+ if (typeof value === "number") return { kind: "number", value }
163
+ if (
164
+ Array.isArray(value) &&
165
+ value.length === 4 &&
166
+ value.every((n) => typeof n === "number" && n >= 0 && n <= 1)
167
+ ) {
168
+ return { kind: "color", value }
169
+ }
170
+ if (Array.isArray(value) && value.length === 2 && value.every((n) => typeof n === "number")) {
171
+ return { kind: "point", value }
172
+ }
173
+ return null
174
+ }
175
+
176
+ function clamp01(n: number): number {
177
+ if (Number.isNaN(n)) return 0
178
+ return n < 0 ? 0 : n > 1 ? 1 : n
179
+ }
180
+
181
+ function toHexByte(component: number): string {
182
+ return Math.round(clamp01(component) * 255)
183
+ .toString(16)
184
+ .padStart(2, "0")
185
+ }
186
+
187
+ /**
188
+ * RGBA array (components 0..1) → hex string. The alpha component is omitted
189
+ * when it is exactly 1 (`[1,0,0,1]` → `"#ff0000"`); otherwise an 8-digit hex is
190
+ * emitted (`[0,1,0,0.5]` → `"#00ff0080"`). Output is always lowercase.
191
+ */
192
+ export function rgbaArrayToHex(rgba: number[]): string {
193
+ const [r = 0, g = 0, b = 0, a = 1] = rgba
194
+ const base = `#${toHexByte(r)}${toHexByte(g)}${toHexByte(b)}`
195
+ return a >= 1 ? base : `${base}${toHexByte(a)}`
196
+ }
197
+
198
+ /**
199
+ * Hex string → RGBA array (components 0..1). Accepts `#rgb`, `#rrggbb`, and
200
+ * `#rrggbbaa`; alpha defaults to 1 when absent. Leading `#` is optional.
201
+ */
202
+ export function hexToRgbaArray(hex: string): number[] {
203
+ let h = hex.trim().replace(/^#/, "")
204
+ if (h.length === 3) {
205
+ h = h
206
+ .split("")
207
+ .map((c) => c + c)
208
+ .join("")
209
+ }
210
+ const r = parseInt(h.slice(0, 2), 16) / 255
211
+ const g = parseInt(h.slice(2, 4), 16) / 255
212
+ const b = parseInt(h.slice(4, 6), 16) / 255
213
+ const a = h.length >= 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1
214
+ return [r, g, b, a]
215
+ }
216
+
217
+ /** Manifest sids in insertion order (drives the slot-control list ordering). */
218
+ export function listSlotSids(slots: Record<string, unknown>): string[] {
219
+ return Object.keys(slots ?? {})
220
+ }
221
+
222
+ // ── Slot → app-field derivation (Phase 3 — single source of truth) ────────────
223
+ //
224
+ // `deriveLottieSlotFields` turns a lottie-graphic plan's slot manifest into
225
+ // ExposableField-shaped descriptors. ONE function feeds three surfaces: the
226
+ // editor's publish picker, the published-app runtime, and the backend MCP
227
+ // schema extractor — so the set of slots an app exposes can never drift between
228
+ // them. It deliberately mirrors `describeSlotControl`'s classification (the
229
+ // editor's live slot controls use the same source of truth).
230
+
231
+ /** Prefix for the synthetic field key of a derived slot field: `slot:<sid>`. */
232
+ export const LOTTIE_SLOT_FIELD_PREFIX = "slot:"
233
+
234
+ /** "primaryColor" → "Primary Color"; "bar_size" → "Bar Size". */
235
+ export function humanizeSlotSid(sid: string): string {
236
+ return sid
237
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
238
+ .replace(/[_-]+/g, " ")
239
+ .replace(/\s+/g, " ")
240
+ .trim()
241
+ .replace(/\b\w/g, (c) => c.toUpperCase())
242
+ }
243
+
244
+ /** ExposableField-shaped descriptor derived from one slot. */
245
+ export interface LottieSlotField {
246
+ /** Synthetic field key: `slot:<sid>`. */
247
+ key: string
248
+ /** Humanized sid (camelCase / snake_case → Title Case). */
249
+ label: string
250
+ /** Maps onto the `ExposableField.type` members used in apps. */
251
+ type: "color" | "text" | "slider"
252
+ min?: number
253
+ max?: number
254
+ step?: number
255
+ /** Hex string for color; raw value for text/number. */
256
+ defaultValue?: unknown
257
+ }
258
+
259
+ /**
260
+ * Derive ExposableField-shaped descriptors from a motion-graphics node's plan.
261
+ *
262
+ * Returns [] unless `motionPlan.planType === "lottie-graphic"` and `slots` is a
263
+ * non-empty object — the elements engine and absent plans expose nothing.
264
+ *
265
+ * Per slot, via `describeSlotControl`:
266
+ * - color → `{ type: "color", defaultValue: rgbaArrayToHex(value) }`
267
+ * - text → `{ type: "text", defaultValue: value }`
268
+ * - number → `{ type: "slider", min, max, step, defaultValue: value }`
269
+ * (0–1 values → 0..1 step 0.01; larger → 0..ceil(value*2) step 1)
270
+ * - point / null → SKIPPED. Point-kind slots are intentionally not exposed in
271
+ * apps (no paired-number card; positions are rarely end-user-meaningful).
272
+ */
273
+ export function deriveLottieSlotFields(
274
+ motionPlan: Record<string, unknown> | undefined,
275
+ ): LottieSlotField[] {
276
+ if (!motionPlan || motionPlan.planType !== "lottie-graphic") return []
277
+ const slots = motionPlan.slots
278
+ if (!isPlainObject(slots)) return []
279
+
280
+ const fields: LottieSlotField[] = []
281
+ for (const [sid, slot] of Object.entries(slots)) {
282
+ const control = describeSlotControl(slot)
283
+ if (!control) continue
284
+ const base = { key: `${LOTTIE_SLOT_FIELD_PREFIX}${sid}`, label: humanizeSlotSid(sid) }
285
+
286
+ if (control.kind === "color") {
287
+ fields.push({
288
+ ...base,
289
+ type: "color",
290
+ defaultValue: rgbaArrayToHex(control.value as number[]),
291
+ })
292
+ } else if (control.kind === "text") {
293
+ fields.push({ ...base, type: "text", defaultValue: control.value })
294
+ } else if (control.kind === "number") {
295
+ const value = Number(control.value)
296
+ const isUnit = value <= 1
297
+ fields.push({
298
+ ...base,
299
+ type: "slider",
300
+ min: 0,
301
+ max: isUnit ? 1 : Math.ceil(value * 2) || 100,
302
+ step: isUnit ? 0.01 : 1,
303
+ defaultValue: control.value,
304
+ })
305
+ }
306
+ // point / unrecognized kinds are intentionally not exposed.
307
+ }
308
+ return fields
309
+ }