@nodaro/shared 1.4.1

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,42 @@
1
+ /**
2
+ * Like Promise.allSettled but limits how many tasks run concurrently.
3
+ * Uses a worker-pool pattern so a new task starts as soon as a slot frees up.
4
+ * When `cancelledRef` is provided and becomes truthy, remaining un-started
5
+ * tasks are skipped (already-running tasks continue to completion/rejection).
6
+ */
7
+ export async function settledWithLimit<T>(
8
+ tasks: (() => Promise<T>)[],
9
+ limit: number,
10
+ cancelledRef?: { cancelled: boolean },
11
+ ): Promise<PromiseSettledResult<T>[]> {
12
+ const results: PromiseSettledResult<T>[] = new Array(tasks.length)
13
+ let nextIndex = 0
14
+
15
+ const cancelledError = new Error("Execution cancelled")
16
+
17
+ async function worker(): Promise<void> {
18
+ while (nextIndex < tasks.length) {
19
+ if (cancelledRef?.cancelled) break
20
+ const idx = nextIndex++
21
+ try {
22
+ const value = await tasks[idx]()
23
+ results[idx] = { status: "fulfilled", value }
24
+ } catch (reason) {
25
+ results[idx] = { status: "rejected", reason }
26
+ }
27
+ }
28
+ }
29
+
30
+ const workers = Array.from(
31
+ { length: Math.min(limit, tasks.length) },
32
+ () => worker(),
33
+ )
34
+ await Promise.all(workers)
35
+
36
+ // Fill any un-started slots (from cancellation) with a shared rejection
37
+ for (let i = 0; i < results.length; i++) {
38
+ if (!results[i]) results[i] = { status: "rejected", reason: cancelledError }
39
+ }
40
+
41
+ return results
42
+ }
@@ -0,0 +1,43 @@
1
+ import type { SupportedFontName } from "./supported-fonts.js"
2
+
3
+ export interface ShotTextElement {
4
+ readonly id: string
5
+ readonly type: "text"
6
+ readonly text: string
7
+ readonly fontFamily?: SupportedFontName
8
+ readonly fontSize: number
9
+ readonly fontWeight?: 300 | 400 | 700 | 900
10
+ readonly color?: string
11
+ readonly x: number
12
+ readonly y: number
13
+ readonly letterSpacing?: number
14
+ readonly opacity?: number
15
+ readonly dir?: "rtl" | "ltr"
16
+ }
17
+ export interface ShotShapeElement {
18
+ readonly id: string
19
+ readonly type: "shape"
20
+ readonly shape: "rectangle" | "circle" | "line"
21
+ readonly fill?: string
22
+ readonly stroke?: string
23
+ readonly strokeWidth?: number
24
+ readonly x: number
25
+ readonly y: number
26
+ readonly width: number
27
+ readonly height: number
28
+ readonly cornerRadius?: number
29
+ readonly opacity?: number
30
+ }
31
+ export interface ShotImageElement {
32
+ readonly id: string
33
+ readonly type: "image"
34
+ readonly src: string
35
+ readonly x: number
36
+ readonly y: number
37
+ readonly width: number
38
+ readonly height: number
39
+ readonly fit?: "contain" | "cover"
40
+ readonly radius?: number
41
+ readonly opacity?: number
42
+ }
43
+ export type ShotElement = ShotTextElement | ShotShapeElement | ShotImageElement
@@ -0,0 +1,121 @@
1
+ export type SocialMediaPlatform = "instagram" | "tiktok" | "x" | "youtube" | "facebook" | "linkedin" | "telegram"
2
+
3
+ export type SocialMediaContentType =
4
+ | "feed-square" | "feed-portrait" | "feed-landscape" | "story-reel" // Instagram
5
+ | "video" // TikTok
6
+ | "image-landscape" | "image-square" | "x-video" // X
7
+ | "short" // YouTube
8
+ | "fb-feed-portrait" | "reel" // Facebook
9
+ | "li-image-landscape" | "li-image-square" | "li-video" // LinkedIn
10
+
11
+ export interface SocialMediaSpec {
12
+ readonly platform: SocialMediaPlatform
13
+ readonly contentType: SocialMediaContentType
14
+ readonly label: string
15
+ readonly width: number
16
+ readonly height: number
17
+ readonly maxDurationSeconds: number | null // null = image only (no duration limit)
18
+ readonly textLimit: number
19
+ readonly isVideo: boolean
20
+ }
21
+
22
+ export const PLATFORM_SPECS: Record<string, SocialMediaSpec> = {
23
+ "instagram:feed-square": {
24
+ platform: "instagram", contentType: "feed-square", label: "Feed Square",
25
+ width: 1080, height: 1080, maxDurationSeconds: 60, textLimit: 2200, isVideo: true,
26
+ },
27
+ "instagram:feed-portrait": {
28
+ platform: "instagram", contentType: "feed-portrait", label: "Feed Portrait",
29
+ width: 1080, height: 1350, maxDurationSeconds: 60, textLimit: 2200, isVideo: true,
30
+ },
31
+ "instagram:feed-landscape": {
32
+ platform: "instagram", contentType: "feed-landscape", label: "Feed Landscape",
33
+ width: 1080, height: 566, maxDurationSeconds: 60, textLimit: 2200, isVideo: true,
34
+ },
35
+ "instagram:story-reel": {
36
+ platform: "instagram", contentType: "story-reel", label: "Story / Reel",
37
+ width: 1080, height: 1920, maxDurationSeconds: 180, textLimit: 2200, isVideo: true,
38
+ },
39
+ "tiktok:video": {
40
+ platform: "tiktok", contentType: "video", label: "Video",
41
+ width: 1080, height: 1920, maxDurationSeconds: 600, textLimit: 4000, isVideo: true,
42
+ },
43
+ "x:image-landscape": {
44
+ platform: "x", contentType: "image-landscape", label: "Image Landscape",
45
+ width: 1200, height: 675, maxDurationSeconds: null, textLimit: 280, isVideo: false,
46
+ },
47
+ "x:image-square": {
48
+ platform: "x", contentType: "image-square", label: "Image Square",
49
+ width: 1080, height: 1080, maxDurationSeconds: null, textLimit: 280, isVideo: false,
50
+ },
51
+ "x:x-video": {
52
+ platform: "x", contentType: "x-video", label: "Video",
53
+ width: 1920, height: 1080, maxDurationSeconds: 140, textLimit: 280, isVideo: true,
54
+ },
55
+ "youtube:short": {
56
+ platform: "youtube", contentType: "short", label: "Short",
57
+ width: 1080, height: 1920, maxDurationSeconds: 180, textLimit: 5000, isVideo: true,
58
+ },
59
+ "facebook:fb-feed-portrait": {
60
+ platform: "facebook", contentType: "fb-feed-portrait", label: "Feed Portrait",
61
+ width: 1080, height: 1350, maxDurationSeconds: null, textLimit: 63206, isVideo: false,
62
+ },
63
+ "facebook:reel": {
64
+ platform: "facebook", contentType: "reel", label: "Reel",
65
+ width: 1080, height: 1920, maxDurationSeconds: 90, textLimit: 63206, isVideo: true,
66
+ },
67
+ "linkedin:li-image-landscape": {
68
+ platform: "linkedin", contentType: "li-image-landscape", label: "Image Landscape",
69
+ width: 1200, height: 627, maxDurationSeconds: null, textLimit: 3000, isVideo: false,
70
+ },
71
+ "linkedin:li-image-square": {
72
+ platform: "linkedin", contentType: "li-image-square", label: "Image Square",
73
+ width: 1080, height: 1080, maxDurationSeconds: null, textLimit: 3000, isVideo: false,
74
+ },
75
+ "linkedin:li-video": {
76
+ platform: "linkedin", contentType: "li-video", label: "Video",
77
+ width: 1920, height: 1080, maxDurationSeconds: 600, textLimit: 3000, isVideo: true,
78
+ },
79
+ }
80
+
81
+ export const CONTENT_TYPES_BY_PLATFORM: Record<SocialMediaPlatform, ReadonlyArray<{ key: string; label: string }>> = {
82
+ instagram: [
83
+ { key: "instagram:feed-square", label: "Feed Square (1080×1080)" },
84
+ { key: "instagram:feed-portrait", label: "Feed Portrait (1080×1350)" },
85
+ { key: "instagram:feed-landscape", label: "Feed Landscape (1080×566)" },
86
+ { key: "instagram:story-reel", label: "Story / Reel (1080×1920)" },
87
+ ],
88
+ tiktok: [
89
+ { key: "tiktok:video", label: "Video (1080×1920)" },
90
+ ],
91
+ x: [
92
+ { key: "x:image-landscape", label: "Image Landscape (1200×675)" },
93
+ { key: "x:image-square", label: "Image Square (1080×1080)" },
94
+ { key: "x:x-video", label: "Video (1920×1080)" },
95
+ ],
96
+ youtube: [
97
+ { key: "youtube:short", label: "Short (1080×1920)" },
98
+ ],
99
+ facebook: [
100
+ { key: "facebook:fb-feed-portrait", label: "Feed Portrait (1080×1350)" },
101
+ { key: "facebook:reel", label: "Reel (1080×1920)" },
102
+ ],
103
+ linkedin: [
104
+ { key: "linkedin:li-image-landscape", label: "Image Landscape (1200×627)" },
105
+ { key: "linkedin:li-image-square", label: "Image Square (1080×1080)" },
106
+ { key: "linkedin:li-video", label: "Video (1920×1080)" },
107
+ ],
108
+ telegram: [
109
+ { key: "telegram:message", label: "Message (text)" },
110
+ ],
111
+ }
112
+
113
+ export const PLATFORM_LABELS: Record<SocialMediaPlatform, string> = {
114
+ instagram: "Instagram",
115
+ tiktok: "TikTok",
116
+ x: "X (Twitter)",
117
+ youtube: "YouTube",
118
+ facebook: "Facebook",
119
+ linkedin: "LinkedIn",
120
+ telegram: "Telegram",
121
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Shared constants for social post nodes.
3
+ *
4
+ * Used by both the frontend DAG executor and backend orchestrator so input
5
+ * routing + API validation agree on which node types are social posts and
6
+ * on Instagram's carousel item limits.
7
+ */
8
+
9
+ /** Node types that publish to a social platform via POST /v1/social/publish. */
10
+ export const SOCIAL_POST_NODE_TYPES = new Set([
11
+ "instagram-post",
12
+ "tiktok-post",
13
+ "youtube-upload",
14
+ "linkedin-post",
15
+ "x-post",
16
+ "facebook-post",
17
+ "telegram-post",
18
+ ])
19
+
20
+ /** Instagram carousel limits per Meta Graph API.
21
+ * Meta's documented limit is 10 items; sending >10 fails at container
22
+ * creation with "(#100) too little or too many attachments". */
23
+ export const INSTAGRAM_CAROUSEL_MIN_ITEMS = 2
24
+ export const INSTAGRAM_CAROUSEL_MAX_ITEMS = 10
@@ -0,0 +1,78 @@
1
+ export interface SubWorkflowPort {
2
+ readonly id: string
3
+ readonly name: string
4
+ readonly mediaType: "text" | "image" | "video" | "audio" | "any"
5
+ }
6
+
7
+ interface BoundaryNode {
8
+ readonly id: string
9
+ readonly type: string
10
+ readonly data: { readonly routeId?: string; readonly ports?: readonly SubWorkflowPort[] }
11
+ }
12
+
13
+ export type ValidationError =
14
+ | { code: "missing_output_for_route"; routeId: string; inputNodeId: string }
15
+ | { code: "missing_input_for_route"; routeId: string; outputNodeId: string }
16
+ | { code: "route_has_no_output_ports"; routeId: string; outputNodeId: string }
17
+ | { code: "duplicate_route_id"; routeId: string; nodeIds: readonly string[] }
18
+
19
+ export type ValidationResult =
20
+ | { ok: true }
21
+ | { ok: false; errors: readonly ValidationError[] }
22
+
23
+ export function validateSubWorkflowRoutes(
24
+ nodes: readonly BoundaryNode[],
25
+ ): ValidationResult {
26
+ const inputs = nodes.filter((n) => n.type === "sub-workflow-input")
27
+ const outputs = nodes.filter((n) => n.type === "sub-workflow-output")
28
+
29
+ if (inputs.length === 0 && outputs.length === 0) return { ok: true }
30
+
31
+ const errors: ValidationError[] = []
32
+
33
+ // 1. Duplicate routeIds within input or output lists
34
+ const groupByRoute = (list: readonly BoundaryNode[]) => {
35
+ const map = new Map<string, BoundaryNode[]>()
36
+ for (const n of list) {
37
+ const r = n.data.routeId
38
+ if (!r) continue
39
+ const bucket = map.get(r) ?? []
40
+ bucket.push(n)
41
+ map.set(r, bucket)
42
+ }
43
+ return map
44
+ }
45
+ for (const [routeId, group] of groupByRoute(inputs)) {
46
+ if (group.length > 1) errors.push({ code: "duplicate_route_id", routeId, nodeIds: group.map((g) => g.id) })
47
+ }
48
+ for (const [routeId, group] of groupByRoute(outputs)) {
49
+ if (group.length > 1) errors.push({ code: "duplicate_route_id", routeId, nodeIds: group.map((g) => g.id) })
50
+ }
51
+
52
+ // 2. Every input routeId must have a matching output
53
+ const outputByRoute = new Map(outputs.map((o) => [o.data.routeId, o] as const))
54
+ for (const inputNode of inputs) {
55
+ const routeId = inputNode.data.routeId
56
+ if (!routeId) continue
57
+ const matchingOutput = outputByRoute.get(routeId)
58
+ if (!matchingOutput) {
59
+ errors.push({ code: "missing_output_for_route", routeId, inputNodeId: inputNode.id })
60
+ continue
61
+ }
62
+ if (!matchingOutput.data.ports || matchingOutput.data.ports.length === 0) {
63
+ errors.push({ code: "route_has_no_output_ports", routeId, outputNodeId: matchingOutput.id })
64
+ }
65
+ }
66
+
67
+ // 3. Every output routeId must have a matching input
68
+ const inputByRoute = new Map(inputs.map((i) => [i.data.routeId, i] as const))
69
+ for (const outputNode of outputs) {
70
+ const routeId = outputNode.data.routeId
71
+ if (!routeId) continue
72
+ if (!inputByRoute.has(routeId)) {
73
+ errors.push({ code: "missing_input_for_route", routeId, outputNodeId: outputNode.id })
74
+ }
75
+ }
76
+
77
+ return errors.length === 0 ? { ok: true } : { ok: false, errors }
78
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Canonical list of font display names supported by the Remotion renderer.
3
+ *
4
+ * Single source of truth shared by:
5
+ * - the backend Zod schemas (`z.enum(SUPPORTED_FONT_NAMES)`), which CANNOT
6
+ * import `@nodaro/remotion` (its font-registry pulls the render runtime +
7
+ * `@remotion/google-fonts` side-effects into a validation path), and
8
+ * - `packages/remotion/src/lib/font-registry.ts`, which loads each face and
9
+ * is kept in lock-step with this tuple by a compile-time `satisfies` guard.
10
+ *
11
+ * Order/spelling MUST match the keys of the `fonts` object in font-registry.ts.
12
+ */
13
+ export const SUPPORTED_FONT_NAMES = [
14
+ "Inter",
15
+ "Roboto",
16
+ "Open Sans",
17
+ "Montserrat",
18
+ "Poppins",
19
+ "Raleway",
20
+ "Nunito",
21
+ "Lato",
22
+ "Playfair Display",
23
+ "Merriweather",
24
+ "Lora",
25
+ "EB Garamond",
26
+ "Bebas Neue",
27
+ "Oswald",
28
+ "Anton",
29
+ "Dancing Script",
30
+ "Pacifico",
31
+ "Caveat",
32
+ "Roboto Mono",
33
+ "Fira Code",
34
+ "Rubik",
35
+ "Heebo",
36
+ "Cairo",
37
+ "Tajawal",
38
+ ] as const
39
+
40
+ export type SupportedFontName = (typeof SUPPORTED_FONT_NAMES)[number]
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Surround continuation — shared single source of truth.
3
+ *
4
+ * The Location 360° "look-around" builds each ring view (45°, 90°, …) as an
5
+ * image-to-image continuation of the previous view. The platform forces
6
+ * geometric continuity by handing the model a half-done frame: one edge holds
7
+ * the previous view's carried pixels, the rest is flat gray, and the model is
8
+ * asked to paint the gray region.
9
+ *
10
+ * This module owns the bits that are pure and reused across the route Zod
11
+ * schema, the SDK input type, and the worker: the direction enum, the carried
12
+ * fraction defaults, and the fill prompt. The geometry math + sharp compositing
13
+ * + color harmonization live backend-side (they need `sharp`).
14
+ */
15
+
16
+ /**
17
+ * The carry/paint axis for a continuation.
18
+ *
19
+ * PAN (horizontal — half-carry continuation):
20
+ * - `right` — turning right: the new frame's LEFT edge continues the previous
21
+ * view's RIGHT edge, so the carried band sits on the LEFT, painted on the RIGHT.
22
+ * - `left` — turning left: the new frame's RIGHT edge continues the previous
23
+ * view's LEFT edge, so the carried band sits on the RIGHT, painted on the LEFT.
24
+ * (Mirror of `right`. Lets studio chain BOTH ways from a keyframe, capping
25
+ * chain depth so quality doesn't compound down a long one-way chain.)
26
+ *
27
+ * TILT (vertical — thin-strip, subject-driven re-render):
28
+ * - `up` — tilting straight up: render the open SKY overhead. A thin strip of
29
+ * the establishing shot's TOP edge is carried into the new frame's BOTTOM for
30
+ * a soft horizon transition; the rest is painted as sky (NOT a mirrored
31
+ * landscape).
32
+ * - `down` — tilting straight down: render the GROUND below. A thin strip of the
33
+ * BOTTOM edge is carried into the new frame's TOP.
34
+ */
35
+ export const SURROUND_DIRECTIONS = ["right", "left", "up", "down"] as const
36
+ export type SurroundDirection = (typeof SURROUND_DIRECTIONS)[number]
37
+
38
+ /** Half the frame is carried for a horizontal pan (matches studio's composite). */
39
+ export const DEFAULT_CARRIED_FRACTION = 0.5
40
+ /**
41
+ * Tilts carry only a thin horizon strip. Carrying half of a horizontal frame is
42
+ * exactly what makes the model echo/mirror the landscape vertically instead of
43
+ * rendering what's actually overhead/underfoot — so tilts keep the carry small
44
+ * and let the tilt prompt drive the subject.
45
+ */
46
+ export const TILT_CARRIED_FRACTION = 0.12
47
+
48
+ /** True for the vertical tilt directions (up/down), false for the pans. */
49
+ export function isTiltDirection(direction: SurroundDirection): boolean {
50
+ return direction === "up" || direction === "down"
51
+ }
52
+
53
+ /** The carried fraction the platform uses when the caller doesn't pin one. */
54
+ export function defaultCarriedFraction(direction: SurroundDirection): number {
55
+ return isTiltDirection(direction) ? TILT_CARRIED_FRACTION : DEFAULT_CARRIED_FRACTION
56
+ }
57
+
58
+ /** Which edge of the NEW frame holds the carried pixels vs the painted region. */
59
+ const EDGE: Record<SurroundDirection, { carried: string; painted: string }> = {
60
+ right: { carried: "left", painted: "right" },
61
+ left: { carried: "right", painted: "left" },
62
+ up: { carried: "bottom", painted: "top" },
63
+ down: { carried: "top", painted: "bottom" },
64
+ }
65
+
66
+ /** What a tilt must actually render (NOT a continuation of the landscape). */
67
+ const TILT_SUBJECT: Record<"up" | "down", { word: string; subject: string; where: string }> = {
68
+ up: {
69
+ word: "up",
70
+ subject: "the open sky directly overhead — sky, clouds, or (for an interior) the canopy or ceiling",
71
+ where: "overhead",
72
+ },
73
+ down: {
74
+ word: "down",
75
+ subject: "the ground directly below — terrain, floor, or water surface",
76
+ where: "below",
77
+ },
78
+ }
79
+
80
+ /**
81
+ * Build the fill prompt the model receives alongside the half-carry composite.
82
+ *
83
+ * `userPrompt` (an optional scene hint from the caller) is woven in front. PAN
84
+ * directions get the seamless-continuation prompt (with the anti-golden-hour
85
+ * negative that fights the documented warm-regrade drift). TILT directions get a
86
+ * subject-forcing prompt — render the sky / ground overhead / below, explicitly
87
+ * NOT a mirrored landscape — which is what stops the vertical echo.
88
+ */
89
+ export function buildSurroundFillPrompt(direction: SurroundDirection, userPrompt?: string): string {
90
+ const scene = userPrompt && userPrompt.trim() ? `${userPrompt.trim()}. ` : ""
91
+ const { carried, painted } = EDGE[direction]
92
+
93
+ if (direction === "up" || direction === "down") {
94
+ const t = TILT_SUBJECT[direction]
95
+ return (
96
+ `${scene}` +
97
+ `This is a camera tilted straight ${t.word} from the same scene. The ${carried} strip holds real, finished pixels from the edge of the horizon view; the ${painted} region is flat gray and MUST be painted as ${t.subject}. ` +
98
+ `Render what is genuinely ${t.where} — do NOT repeat, mirror, or continue the landscape, and do NOT draw a horizon line or distant scenery in the painted region. ` +
99
+ `CRITICAL: keep the ${carried} strip unchanged and match the scene's EXACT lighting, time of day, white balance, and color grade — the same light as the ${carried} strip; no golden hour, no sunset, no warm relight, no cinematic regrade. ` +
100
+ `Blend smoothly into the ${carried} strip with no visible seam. No people, no text, no labels, no watermarks.`
101
+ )
102
+ }
103
+
104
+ // pan (right / left)
105
+ return (
106
+ `${scene}` +
107
+ `This is a partial frame: the ${carried} portion contains real, finished pixels and the ${painted} portion is flat gray that MUST be painted in. ` +
108
+ `Paint ONLY the ${painted} gray region as a natural, seamless continuation of the ${carried} portion — same scene, same perspective, continuing the horizon, geometry, and content across the boundary with no break. ` +
109
+ `Keep the ${carried} portion completely unchanged. ` +
110
+ `CRITICAL: do NOT change the lighting, exposure, white balance, or time of day. Match the ${carried} portion's EXACT light, color temperature, and contrast across the whole frame — if it is flat overcast daylight, keep flat overcast daylight. No golden hour, no sunset, no warm relight, no cinematic regrade. ` +
111
+ `The seam between the ${carried} and ${painted} portions must be invisible. No people, no text, no labels, no watermarks.`
112
+ )
113
+ }
@@ -0,0 +1,33 @@
1
+ // Beeble SwitchX — Relight & Switch video node. Non-monetary tier bucketing
2
+ // and credit-identifier helpers. Beeble bills per 30-frame block with no
3
+ // per-job meter returned, so we reserve a block tier (the smallest tier that
4
+ // covers the clip's frame count) and commit it verbatim — tiers are 30-frame
5
+ // multiples, so a clip snaps to the exact number of blocks Beeble bills
6
+ // (ceil(frames/30)); there is no tier over-charge.
7
+ //
8
+ // The $-per-block provider rate and the credits-per-block formula derived
9
+ // from it live in `backend/src/lib/pricing/switchx-cost.ts` (core, not ee/).
10
+ // They were moved out of this package (published Apache-2.0 on npm — an
11
+ // irrevocable grant) per the 2026-07-06 public-flip IP audit, S5.
12
+ export const SWITCHX_FRAME_TIERS = [30, 60, 90, 120, 150, 180, 210, 240] as const
13
+
14
+ /** Beeble's metering granularity: frames per billed block. */
15
+ export const SWITCHX_BLOCK_FRAMES = 30
16
+
17
+ export function pickSwitchXFrameTier(frames?: number): number {
18
+ if (frames === undefined || !Number.isFinite(frames) || frames <= 0) return 240
19
+ for (const t of SWITCHX_FRAME_TIERS) if (frames <= t) return t
20
+ return 240
21
+ }
22
+
23
+ function readMaxResolution(body: Record<string, unknown>): 720 | 1080 {
24
+ const r = Number(body.maxResolution ?? body.max_resolution)
25
+ return r === 720 ? 720 : 1080 // default 1080
26
+ }
27
+
28
+ // Frames are stashed on the raw body by the route's ffprobe preHandler.
29
+ export function resolveSwitchXCreditId(body: Record<string, unknown>): string {
30
+ const frames = Number(body.__probedFrameCount)
31
+ const tier = pickSwitchXFrameTier(Number.isFinite(frames) ? frames : undefined)
32
+ return `beeble-switchx:${tier}f:${readMaxResolution(body)}p`
33
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared separator presets for the Combine Text and Split Text nodes.
3
+ * Single source of truth for both the frontend DAG executor and backend orchestrator.
4
+ */
5
+
6
+ export const SEPARATOR_PRESETS = [
7
+ "newline",
8
+ "double-newline",
9
+ "comma",
10
+ "space",
11
+ "stars",
12
+ "custom",
13
+ ] as const
14
+
15
+ export type SeparatorPreset = (typeof SEPARATOR_PRESETS)[number]
16
+
17
+ const SPLIT_MAP: Record<string, string> = {
18
+ newline: "\n",
19
+ "double-newline": "\n\n",
20
+ comma: ",",
21
+ space: " ",
22
+ stars: "***",
23
+ }
24
+
25
+ const COMBINE_MAP: Record<string, string> = {
26
+ ...SPLIT_MAP,
27
+ comma: ", ",
28
+ }
29
+
30
+ /** Human-readable label for the node badge. */
31
+ export const SEPARATOR_DISPLAY: Record<string, string> = {
32
+ newline: "\\n",
33
+ "double-newline": "\\n\\n",
34
+ comma: ",",
35
+ space: "space",
36
+ stars: "***",
37
+ }
38
+
39
+ export interface ResolveSeparatorOptions {
40
+ /** Use combine-text spacing — e.g. ", " for comma instead of "," */
41
+ combineSpacing?: boolean
42
+ }
43
+
44
+ /**
45
+ * Resolve a separator value to its actual string.
46
+ * - Enum preset → mapped value (e.g. "newline" → "\n")
47
+ * - "custom" → customSeparator field
48
+ * - Anything else → literal string (back-compat with legacy values like "===NEXT===")
49
+ */
50
+ export function resolveSeparator(
51
+ raw: string | undefined,
52
+ customSeparator: string | undefined,
53
+ opts?: ResolveSeparatorOptions,
54
+ ): string {
55
+ const r = raw || "newline"
56
+ if (r === "custom") return customSeparator ?? ""
57
+ const map = opts?.combineSpacing ? COMBINE_MAP : SPLIT_MAP
58
+ return map[r] ?? r
59
+ }
@@ -0,0 +1,77 @@
1
+ import type { ConnectedReference } from "./types.js"
2
+ import { characterMentionSlug } from "./character-mention-slug.js"
3
+ import { locationMentionSlug } from "./location-mention-slug.js"
4
+
5
+ /**
6
+ * A bound entity (a wired Character or Location) ready to convert into a
7
+ * `ConnectedReference`. The minimal identity an app captures when a user binds
8
+ * an entity — the SLUG (and thus the resolver match) is DERIVED from `name`
9
+ * here, so callers can't drift from Nodaro's mention resolver. Apps own their
10
+ * own binding UX (chips, pickers); this is just the contract mapping.
11
+ */
12
+ export interface EntityReferenceInput {
13
+ /** The entity row id. */
14
+ readonly id: string
15
+ readonly kind: "character" | "location" | "creature"
16
+ /** Display name — the slug is derived from this. */
17
+ readonly name: string
18
+ /** Resolved thumbnail/source URL; null/undefined → "" (placeholder-safe). */
19
+ readonly url?: string | null
20
+ /** Variant slug (e.g. "smile", "rain"); undefined = canonical/default. */
21
+ readonly variant?: string
22
+ /** Optional free-text descriptor (creature bindings: species/appearance) —
23
+ * folded into the auto-generated directive subject by the prompt builder. */
24
+ readonly description?: string | null
25
+ }
26
+
27
+ /**
28
+ * Map ONE bound entity to its `ConnectedReference`. character → `wired-character`
29
+ * (slug via `characterMentionSlug`), location → `wired-location` (slug via
30
+ * `locationMentionSlug`), creature → `wired-creature` (no mention-slug machinery
31
+ * — like `wired-object`, a bound creature AUTO-ATTACHES and gets a canonical-style
32
+ * creature/animal-subject directive with zero typing; `{image:N:creature}` tokens
33
+ * also resolve against it). Canonical-description fields are null here (a binding
34
+ * captures only name+variant; the picker/full-row path supplies descriptions).
35
+ */
36
+ export function toConnectedReference(entity: EntityReferenceInput): ConnectedReference {
37
+ if (entity.kind === "character") {
38
+ return {
39
+ id: entity.id,
40
+ defaultName: entity.name,
41
+ source: "wired-character",
42
+ url: entity.url ?? "",
43
+ characterSlug: characterMentionSlug(entity.name),
44
+ variantSlug: entity.variant,
45
+ characterCanonicalDescription: null,
46
+ variantDescription: null,
47
+ variantDisplayName: entity.variant ?? "canonical",
48
+ }
49
+ }
50
+ if (entity.kind === "creature") {
51
+ return {
52
+ id: entity.id,
53
+ defaultName: entity.name,
54
+ source: "wired-creature",
55
+ url: entity.url ?? "",
56
+ ...(entity.description ? { description: entity.description } : {}),
57
+ }
58
+ }
59
+ return {
60
+ id: entity.id,
61
+ defaultName: entity.name,
62
+ source: "wired-location",
63
+ url: entity.url ?? "",
64
+ locationSlug: locationMentionSlug(entity.name),
65
+ locationCanonicalDescription: null,
66
+ locationVariantBucket: undefined,
67
+ locationVariantSlug: entity.variant,
68
+ locationVariantDisplayName: entity.variant ?? "canonical",
69
+ }
70
+ }
71
+
72
+ /** Batch form — `entities.map(toConnectedReference)`. */
73
+ export function toConnectedReferences(
74
+ entities: readonly EntityReferenceInput[],
75
+ ): ConnectedReference[] {
76
+ return entities.map(toConnectedReference)
77
+ }