@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.
- package/LICENSE +202 -0
- package/README.md +32 -0
- package/dist/index.cjs +12506 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +12269 -0
- package/dist/index.d.ts +12269 -0
- package/dist/index.js +11831 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
- package/src/__tests__/__snapshots__/prompt-builder-segments.test.ts.snap +65 -0
- package/src/__tests__/ai-avatar-pricing.test.ts +321 -0
- package/src/__tests__/apply-video-negative-prompt.test.ts +76 -0
- package/src/__tests__/attach-columns.test.ts +28 -0
- package/src/__tests__/audio-crossfade-curves.test.ts +33 -0
- package/src/__tests__/build-model-menu.test.ts +58 -0
- package/src/__tests__/character-aspect-defaults.test.ts +142 -0
- package/src/__tests__/character-mention-slug.test.ts +199 -0
- package/src/__tests__/character-reference-photo-kinds.test.ts +32 -0
- package/src/__tests__/character-usage-mode.test.ts +147 -0
- package/src/__tests__/character-variant-assets.test.ts +142 -0
- package/src/__tests__/character-voice.test.ts +130 -0
- package/src/__tests__/cinematic-avatar-pricing.test.ts +119 -0
- package/src/__tests__/combine-transitions.test.ts +137 -0
- package/src/__tests__/component-types.test.ts +87 -0
- package/src/__tests__/condition-variables.test.ts +98 -0
- package/src/__tests__/credit-identifiers.test.ts +811 -0
- package/src/__tests__/default-video-provider.test.ts +63 -0
- package/src/__tests__/entity-image-handle.test.ts +43 -0
- package/src/__tests__/entity-variants.test.ts +33 -0
- package/src/__tests__/fal-lip-sync-sets.test.ts +31 -0
- package/src/__tests__/featured-entities.test.ts +33 -0
- package/src/__tests__/film-pricing.test.ts +64 -0
- package/src/__tests__/filter-condition.test.ts +285 -0
- package/src/__tests__/freecut-protocol.test.ts +35 -0
- package/src/__tests__/generate-text-items.test.ts +19 -0
- package/src/__tests__/generated-results.test.ts +50 -0
- package/src/__tests__/graph-utils.test.ts +618 -0
- package/src/__tests__/group-aggregation.test.ts +83 -0
- package/src/__tests__/i18n-locale-completeness.test.ts +156 -0
- package/src/__tests__/image-critic-node.test.ts +86 -0
- package/src/__tests__/image-mask-mode.test.ts +16 -0
- package/src/__tests__/image-ref-limit.test.ts +78 -0
- package/src/__tests__/inpaint-region.test.ts +24 -0
- package/src/__tests__/input-field-map-parity.test.ts +30 -0
- package/src/__tests__/json-evaluator.test.ts +289 -0
- package/src/__tests__/json-path.test.ts +64 -0
- package/src/__tests__/lip-sync-pricing.test.ts +142 -0
- package/src/__tests__/list-merge.test.ts +96 -0
- package/src/__tests__/list-sort.test.ts +134 -0
- package/src/__tests__/llm-models.test.ts +445 -0
- package/src/__tests__/location-mention-slug.test.ts +246 -0
- package/src/__tests__/locations-coverage-critic-schema.test.ts +92 -0
- package/src/__tests__/loop-delimiter.test.ts +39 -0
- package/src/__tests__/lottie-slots.test.ts +245 -0
- package/src/__tests__/model-catalog-flux2-resolutions.test.ts +21 -0
- package/src/__tests__/model-constants-location.test.ts +20 -0
- package/src/__tests__/model-constants.test.ts +122 -0
- package/src/__tests__/model-tree.test.ts +86 -0
- package/src/__tests__/no-internal-imports.test.ts +25 -0
- package/src/__tests__/node-default-mappings.test.ts +175 -0
- package/src/__tests__/node-mappable-fields.test.ts +7 -0
- package/src/__tests__/node-preset-export.test.ts +46 -0
- package/src/__tests__/node-preset-extract.test.ts +166 -0
- package/src/__tests__/node-refs-canonical.test.ts +54 -0
- package/src/__tests__/node-refs-combine.test.ts +54 -0
- package/src/__tests__/node-refs.test.ts +187 -0
- package/src/__tests__/node-runtime-keys.test.ts +99 -0
- package/src/__tests__/object-aspect-defaults.test.ts +59 -0
- package/src/__tests__/parameter-node-value.test.ts +137 -0
- package/src/__tests__/pinterest-url.test.ts +35 -0
- package/src/__tests__/pipeline-chat.test.ts +110 -0
- package/src/__tests__/pipeline-validation.test.ts +98 -0
- package/src/__tests__/presentation-utils.test.ts +1137 -0
- package/src/__tests__/producer-types.test.ts +47 -0
- package/src/__tests__/prompt-length-limits.test.ts +156 -0
- package/src/__tests__/provider-directive-defaults.test.ts +46 -0
- package/src/__tests__/reduce-strategy-registry.test.ts +43 -0
- package/src/__tests__/reference-board-templates.test.ts +33 -0
- package/src/__tests__/reference-roles.test.ts +36 -0
- package/src/__tests__/resolve-field-mappings.test.ts +110 -0
- package/src/__tests__/resolve-pipeline-model.test.ts +76 -0
- package/src/__tests__/scene-node-types.test.ts +80 -0
- package/src/__tests__/scraper-actors.test.ts +67 -0
- package/src/__tests__/seedance-2-catalog.test.ts +18 -0
- package/src/__tests__/seedance-2-credit-id.test.ts +23 -0
- package/src/__tests__/seedance-aspects.test.ts +52 -0
- package/src/__tests__/selector.test.ts +1151 -0
- package/src/__tests__/settled-with-limit.test.ts +214 -0
- package/src/__tests__/social-media-specs.test.ts +129 -0
- package/src/__tests__/sub-workflow-validation.test.ts +88 -0
- package/src/__tests__/switchx-pricing.test.ts +28 -0
- package/src/__tests__/to-connected-references.test.ts +153 -0
- package/src/__tests__/utilities.test.ts +541 -0
- package/src/__tests__/video-analysis-pricing.test.ts +58 -0
- package/src/__tests__/video-analysis.test.ts +63 -0
- package/src/__tests__/video-audio-capability.test.ts +204 -0
- package/src/__tests__/video-gen-providers.test.ts +28 -0
- package/src/__tests__/video-mode-aliases.test.ts +150 -0
- package/src/__tests__/video-ref-limits.test.ts +72 -0
- package/src/__tests__/video-utils.test.ts +303 -0
- package/src/__tests__/voice-changer-models.test.ts +33 -0
- package/src/__tests__/workflow-export-strip.test.ts +46 -0
- package/src/ai-avatar-pricing.ts +213 -0
- package/src/ancestor-refs.ts +48 -0
- package/src/animals.ts +231 -0
- package/src/audio-crossfade-curves.ts +73 -0
- package/src/audio-fx-presets.ts +64 -0
- package/src/avatar-payload-validators.ts +214 -0
- package/src/caption-styles.ts +31 -0
- package/src/character-aspect-defaults.ts +102 -0
- package/src/character-facets.ts +37 -0
- package/src/character-mention-slug.ts +166 -0
- package/src/character-usage-mode.ts +109 -0
- package/src/character-variant-assets.ts +121 -0
- package/src/character-voice.ts +151 -0
- package/src/cinematic-avatar-pricing.ts +111 -0
- package/src/clone-utils.ts +46 -0
- package/src/combine-transitions.ts +482 -0
- package/src/community.ts +112 -0
- package/src/component-types.ts +127 -0
- package/src/condition-variables.ts +65 -0
- package/src/credit-estimators/index.ts +15 -0
- package/src/credit-estimators/video-utils.ts +165 -0
- package/src/credit-identifiers.ts +304 -0
- package/src/entity-approval-types.ts +31 -0
- package/src/entity-aspect-defaults.ts +82 -0
- package/src/entity-asset-types.ts +296 -0
- package/src/entity-image-handle.ts +36 -0
- package/src/extra-refs.ts +139 -0
- package/src/featured-entities.ts +136 -0
- package/src/film-pricing.ts +117 -0
- package/src/filter-condition.ts +250 -0
- package/src/flux2-pricing.ts +18 -0
- package/src/freecut-protocol.ts +52 -0
- package/src/furniture.ts +167 -0
- package/src/generate-text-items.ts +15 -0
- package/src/generated-results.ts +63 -0
- package/src/group-aggregation.ts +75 -0
- package/src/hint-graph-types.ts +18 -0
- package/src/i18n/action-fx.ar.ts +89 -0
- package/src/i18n/action-fx.de.ts +89 -0
- package/src/i18n/action-fx.es.ts +89 -0
- package/src/i18n/action-fx.fr.ts +89 -0
- package/src/i18n/action-fx.he.ts +89 -0
- package/src/i18n/action-fx.hi.ts +89 -0
- package/src/i18n/action-fx.ja.ts +89 -0
- package/src/i18n/action-fx.ko.ts +89 -0
- package/src/i18n/action-fx.pt-BR.ts +89 -0
- package/src/i18n/action-fx.ru.ts +89 -0
- package/src/i18n/action-fx.zh-CN.ts +89 -0
- package/src/i18n/aesthetic.ar.ts +170 -0
- package/src/i18n/aesthetic.de.ts +48 -0
- package/src/i18n/aesthetic.es.ts +169 -0
- package/src/i18n/aesthetic.fr.ts +52 -0
- package/src/i18n/aesthetic.he.ts +169 -0
- package/src/i18n/aesthetic.hi.ts +55 -0
- package/src/i18n/aesthetic.ja.ts +165 -0
- package/src/i18n/aesthetic.ko.ts +169 -0
- package/src/i18n/aesthetic.pt-BR.ts +148 -0
- package/src/i18n/aesthetic.ru.ts +155 -0
- package/src/i18n/aesthetic.zh-CN.ts +172 -0
- package/src/i18n/animals.ar.ts +145 -0
- package/src/i18n/animals.de.ts +144 -0
- package/src/i18n/animals.es.ts +158 -0
- package/src/i18n/animals.fr.ts +144 -0
- package/src/i18n/animals.he.ts +155 -0
- package/src/i18n/animals.hi.ts +157 -0
- package/src/i18n/animals.ja.ts +159 -0
- package/src/i18n/animals.ko.ts +159 -0
- package/src/i18n/animals.pt-BR.ts +157 -0
- package/src/i18n/animals.ru.ts +155 -0
- package/src/i18n/animals.zh-CN.ts +155 -0
- package/src/i18n/atmosphere.ar.ts +49 -0
- package/src/i18n/atmosphere.de.ts +47 -0
- package/src/i18n/atmosphere.es.ts +50 -0
- package/src/i18n/atmosphere.fr.ts +47 -0
- package/src/i18n/atmosphere.he.ts +47 -0
- package/src/i18n/atmosphere.hi.ts +49 -0
- package/src/i18n/atmosphere.ja.ts +49 -0
- package/src/i18n/atmosphere.ko.ts +49 -0
- package/src/i18n/atmosphere.pt-BR.ts +49 -0
- package/src/i18n/atmosphere.ru.ts +47 -0
- package/src/i18n/atmosphere.zh-CN.ts +152 -0
- package/src/i18n/backdrop.ar.ts +53 -0
- package/src/i18n/backdrop.de.ts +46 -0
- package/src/i18n/backdrop.es.ts +54 -0
- package/src/i18n/backdrop.fr.ts +52 -0
- package/src/i18n/backdrop.he.ts +51 -0
- package/src/i18n/backdrop.hi.ts +59 -0
- package/src/i18n/backdrop.ja.ts +61 -0
- package/src/i18n/backdrop.ko.ts +59 -0
- package/src/i18n/backdrop.pt-BR.ts +59 -0
- package/src/i18n/backdrop.ru.ts +57 -0
- package/src/i18n/backdrop.zh-CN.ts +57 -0
- package/src/i18n/camera-format.ar.ts +40 -0
- package/src/i18n/camera-format.de.ts +37 -0
- package/src/i18n/camera-format.es.ts +41 -0
- package/src/i18n/camera-format.fr.ts +37 -0
- package/src/i18n/camera-format.he.ts +37 -0
- package/src/i18n/camera-format.hi.ts +42 -0
- package/src/i18n/camera-format.ja.ts +37 -0
- package/src/i18n/camera-format.ko.ts +37 -0
- package/src/i18n/camera-format.pt-BR.ts +46 -0
- package/src/i18n/camera-format.ru.ts +42 -0
- package/src/i18n/camera-format.zh-CN.ts +42 -0
- package/src/i18n/camera-motions.ar.ts +86 -0
- package/src/i18n/camera-motions.de.ts +74 -0
- package/src/i18n/camera-motions.es.ts +86 -0
- package/src/i18n/camera-motions.fr.ts +86 -0
- package/src/i18n/camera-motions.he.ts +86 -0
- package/src/i18n/camera-motions.hi.ts +99 -0
- package/src/i18n/camera-motions.ja.ts +99 -0
- package/src/i18n/camera-motions.ko.ts +99 -0
- package/src/i18n/camera-motions.pt-BR.ts +99 -0
- package/src/i18n/camera-motions.ru.ts +99 -0
- package/src/i18n/camera-motions.zh-CN.ts +99 -0
- package/src/i18n/character-fx.ar.ts +72 -0
- package/src/i18n/character-fx.de.ts +72 -0
- package/src/i18n/character-fx.es.ts +72 -0
- package/src/i18n/character-fx.fr.ts +72 -0
- package/src/i18n/character-fx.he.ts +72 -0
- package/src/i18n/character-fx.hi.ts +72 -0
- package/src/i18n/character-fx.ja.ts +72 -0
- package/src/i18n/character-fx.ko.ts +72 -0
- package/src/i18n/character-fx.pt-BR.ts +72 -0
- package/src/i18n/character-fx.ru.ts +72 -0
- package/src/i18n/character-fx.zh-CN.ts +72 -0
- package/src/i18n/color-look.ar.ts +50 -0
- package/src/i18n/color-look.de.ts +47 -0
- package/src/i18n/color-look.es.ts +50 -0
- package/src/i18n/color-look.fr.ts +50 -0
- package/src/i18n/color-look.he.ts +49 -0
- package/src/i18n/color-look.hi.ts +52 -0
- package/src/i18n/color-look.ja.ts +54 -0
- package/src/i18n/color-look.ko.ts +54 -0
- package/src/i18n/color-look.pt-BR.ts +54 -0
- package/src/i18n/color-look.ru.ts +52 -0
- package/src/i18n/color-look.zh-CN.ts +53 -0
- package/src/i18n/composition-effects.ar.ts +26 -0
- package/src/i18n/composition-effects.de.ts +25 -0
- package/src/i18n/composition-effects.es.ts +27 -0
- package/src/i18n/composition-effects.fr.ts +25 -0
- package/src/i18n/composition-effects.he.ts +25 -0
- package/src/i18n/composition-effects.hi.ts +27 -0
- package/src/i18n/composition-effects.ja.ts +27 -0
- package/src/i18n/composition-effects.ko.ts +27 -0
- package/src/i18n/composition-effects.pt-BR.ts +25 -0
- package/src/i18n/composition-effects.ru.ts +82 -0
- package/src/i18n/composition-effects.zh-CN.ts +25 -0
- package/src/i18n/era.ar.ts +37 -0
- package/src/i18n/era.de.ts +34 -0
- package/src/i18n/era.es.ts +37 -0
- package/src/i18n/era.fr.ts +37 -0
- package/src/i18n/era.he.ts +36 -0
- package/src/i18n/era.hi.ts +39 -0
- package/src/i18n/era.ja.ts +41 -0
- package/src/i18n/era.ko.ts +39 -0
- package/src/i18n/era.pt-BR.ts +41 -0
- package/src/i18n/era.ru.ts +121 -0
- package/src/i18n/era.zh-CN.ts +39 -0
- package/src/i18n/exposure-settings.ar.ts +28 -0
- package/src/i18n/exposure-settings.de.ts +26 -0
- package/src/i18n/exposure-settings.es.ts +28 -0
- package/src/i18n/exposure-settings.fr.ts +29 -0
- package/src/i18n/exposure-settings.he.ts +28 -0
- package/src/i18n/exposure-settings.hi.ts +31 -0
- package/src/i18n/exposure-settings.ja.ts +31 -0
- package/src/i18n/exposure-settings.ko.ts +31 -0
- package/src/i18n/exposure-settings.pt-BR.ts +31 -0
- package/src/i18n/exposure-settings.ru.ts +31 -0
- package/src/i18n/exposure-settings.zh-CN.ts +31 -0
- package/src/i18n/framing.ar.ts +78 -0
- package/src/i18n/framing.de.ts +73 -0
- package/src/i18n/framing.es.ts +78 -0
- package/src/i18n/framing.fr.ts +78 -0
- package/src/i18n/framing.he.ts +77 -0
- package/src/i18n/framing.hi.ts +82 -0
- package/src/i18n/framing.ja.ts +84 -0
- package/src/i18n/framing.ko.ts +82 -0
- package/src/i18n/framing.pt-BR.ts +84 -0
- package/src/i18n/framing.ru.ts +82 -0
- package/src/i18n/framing.zh-CN.ts +82 -0
- package/src/i18n/furniture.ar.ts +92 -0
- package/src/i18n/furniture.de.ts +93 -0
- package/src/i18n/furniture.es.ts +101 -0
- package/src/i18n/furniture.fr.ts +93 -0
- package/src/i18n/furniture.he.ts +101 -0
- package/src/i18n/furniture.hi.ts +101 -0
- package/src/i18n/furniture.ja.ts +101 -0
- package/src/i18n/furniture.ko.ts +101 -0
- package/src/i18n/furniture.pt-BR.ts +101 -0
- package/src/i18n/furniture.ru.ts +101 -0
- package/src/i18n/furniture.zh-CN.ts +101 -0
- package/src/i18n/held-prop.ar.ts +74 -0
- package/src/i18n/held-prop.de.ts +65 -0
- package/src/i18n/held-prop.es.ts +83 -0
- package/src/i18n/held-prop.fr.ts +74 -0
- package/src/i18n/held-prop.he.ts +73 -0
- package/src/i18n/held-prop.hi.ts +82 -0
- package/src/i18n/held-prop.ja.ts +84 -0
- package/src/i18n/held-prop.ko.ts +84 -0
- package/src/i18n/held-prop.pt-BR.ts +84 -0
- package/src/i18n/held-prop.ru.ts +82 -0
- package/src/i18n/held-prop.zh-CN.ts +82 -0
- package/src/i18n/index.ts +208 -0
- package/src/i18n/instrumentation.ar.ts +195 -0
- package/src/i18n/instrumentation.de.ts +195 -0
- package/src/i18n/instrumentation.es.ts +195 -0
- package/src/i18n/instrumentation.fr.ts +195 -0
- package/src/i18n/instrumentation.he.ts +195 -0
- package/src/i18n/instrumentation.hi.ts +195 -0
- package/src/i18n/instrumentation.ja.ts +195 -0
- package/src/i18n/instrumentation.ko.ts +195 -0
- package/src/i18n/instrumentation.pt-BR.ts +195 -0
- package/src/i18n/instrumentation.ru.ts +195 -0
- package/src/i18n/instrumentation.zh-CN.ts +195 -0
- package/src/i18n/lens.ar.ts +24 -0
- package/src/i18n/lens.de.ts +24 -0
- package/src/i18n/lens.es.ts +24 -0
- package/src/i18n/lens.fr.ts +24 -0
- package/src/i18n/lens.he.ts +24 -0
- package/src/i18n/lens.hi.ts +24 -0
- package/src/i18n/lens.ja.ts +24 -0
- package/src/i18n/lens.ko.ts +24 -0
- package/src/i18n/lens.pt-BR.ts +24 -0
- package/src/i18n/lens.ru.ts +25 -0
- package/src/i18n/lens.zh-CN.ts +24 -0
- package/src/i18n/lighting.ar.ts +86 -0
- package/src/i18n/lighting.de.ts +84 -0
- package/src/i18n/lighting.es.ts +89 -0
- package/src/i18n/lighting.fr.ts +84 -0
- package/src/i18n/lighting.he.ts +88 -0
- package/src/i18n/lighting.hi.ts +90 -0
- package/src/i18n/lighting.ja.ts +90 -0
- package/src/i18n/lighting.ko.ts +90 -0
- package/src/i18n/lighting.pt-BR.ts +90 -0
- package/src/i18n/lighting.ru.ts +88 -0
- package/src/i18n/lighting.zh-CN.ts +92 -0
- package/src/i18n/loop-subject.ar.ts +39 -0
- package/src/i18n/loop-subject.de.ts +39 -0
- package/src/i18n/loop-subject.es.ts +39 -0
- package/src/i18n/loop-subject.fr.ts +39 -0
- package/src/i18n/loop-subject.he.ts +39 -0
- package/src/i18n/loop-subject.hi.ts +39 -0
- package/src/i18n/loop-subject.ja.ts +39 -0
- package/src/i18n/loop-subject.ko.ts +39 -0
- package/src/i18n/loop-subject.pt-BR.ts +39 -0
- package/src/i18n/loop-subject.ru.ts +39 -0
- package/src/i18n/loop-subject.zh-CN.ts +39 -0
- package/src/i18n/materials.ar.ts +80 -0
- package/src/i18n/materials.de.ts +80 -0
- package/src/i18n/materials.es.ts +87 -0
- package/src/i18n/materials.fr.ts +80 -0
- package/src/i18n/materials.he.ts +86 -0
- package/src/i18n/materials.hi.ts +86 -0
- package/src/i18n/materials.ja.ts +88 -0
- package/src/i18n/materials.ko.ts +88 -0
- package/src/i18n/materials.pt-BR.ts +88 -0
- package/src/i18n/materials.ru.ts +86 -0
- package/src/i18n/materials.zh-CN.ts +86 -0
- package/src/i18n/mood.ar.ts +61 -0
- package/src/i18n/mood.de.ts +61 -0
- package/src/i18n/mood.es.ts +66 -0
- package/src/i18n/mood.fr.ts +61 -0
- package/src/i18n/mood.he.ts +64 -0
- package/src/i18n/mood.hi.ts +66 -0
- package/src/i18n/mood.ja.ts +66 -0
- package/src/i18n/mood.ko.ts +66 -0
- package/src/i18n/mood.pt-BR.ts +64 -0
- package/src/i18n/mood.ru.ts +64 -0
- package/src/i18n/mood.zh-CN.ts +64 -0
- package/src/i18n/music-genre.ar.ts +302 -0
- package/src/i18n/music-genre.de.ts +302 -0
- package/src/i18n/music-genre.es.ts +302 -0
- package/src/i18n/music-genre.fr.ts +302 -0
- package/src/i18n/music-genre.he.ts +302 -0
- package/src/i18n/music-genre.hi.ts +302 -0
- package/src/i18n/music-genre.ja.ts +302 -0
- package/src/i18n/music-genre.ko.ts +302 -0
- package/src/i18n/music-genre.pt-BR.ts +302 -0
- package/src/i18n/music-genre.ru.ts +302 -0
- package/src/i18n/music-genre.zh-CN.ts +302 -0
- package/src/i18n/music-mood.ar.ts +75 -0
- package/src/i18n/music-mood.de.ts +75 -0
- package/src/i18n/music-mood.es.ts +75 -0
- package/src/i18n/music-mood.fr.ts +75 -0
- package/src/i18n/music-mood.he.ts +75 -0
- package/src/i18n/music-mood.hi.ts +75 -0
- package/src/i18n/music-mood.ja.ts +75 -0
- package/src/i18n/music-mood.ko.ts +75 -0
- package/src/i18n/music-mood.pt-BR.ts +75 -0
- package/src/i18n/music-mood.ru.ts +75 -0
- package/src/i18n/music-mood.zh-CN.ts +75 -0
- package/src/i18n/person.ar.ts +638 -0
- package/src/i18n/person.de.ts +629 -0
- package/src/i18n/person.es.ts +645 -0
- package/src/i18n/person.fr.ts +621 -0
- package/src/i18n/person.he.ts +656 -0
- package/src/i18n/person.hi.ts +654 -0
- package/src/i18n/person.ja.ts +662 -0
- package/src/i18n/person.ko.ts +662 -0
- package/src/i18n/person.pt-BR.ts +656 -0
- package/src/i18n/person.ru.ts +656 -0
- package/src/i18n/person.zh-CN.ts +656 -0
- package/src/i18n/photo-genre.ar.ts +58 -0
- package/src/i18n/photo-genre.de.ts +52 -0
- package/src/i18n/photo-genre.es.ts +64 -0
- package/src/i18n/photo-genre.fr.ts +58 -0
- package/src/i18n/photo-genre.he.ts +62 -0
- package/src/i18n/photo-genre.hi.ts +63 -0
- package/src/i18n/photo-genre.ja.ts +65 -0
- package/src/i18n/photo-genre.ko.ts +63 -0
- package/src/i18n/photo-genre.pt-BR.ts +65 -0
- package/src/i18n/photo-genre.ru.ts +63 -0
- package/src/i18n/photo-genre.zh-CN.ts +63 -0
- package/src/i18n/photographer.ar.ts +75 -0
- package/src/i18n/photographer.de.ts +74 -0
- package/src/i18n/photographer.es.ts +77 -0
- package/src/i18n/photographer.fr.ts +77 -0
- package/src/i18n/photographer.he.ts +78 -0
- package/src/i18n/photographer.hi.ts +80 -0
- package/src/i18n/photographer.ja.ts +84 -0
- package/src/i18n/photographer.ko.ts +84 -0
- package/src/i18n/photographer.pt-BR.ts +83 -0
- package/src/i18n/photographer.ru.ts +78 -0
- package/src/i18n/photographer.zh-CN.ts +78 -0
- package/src/i18n/pose.ar.ts +95 -0
- package/src/i18n/pose.de.ts +96 -0
- package/src/i18n/pose.es.ts +104 -0
- package/src/i18n/pose.fr.ts +96 -0
- package/src/i18n/pose.he.ts +104 -0
- package/src/i18n/pose.hi.ts +104 -0
- package/src/i18n/pose.ja.ts +104 -0
- package/src/i18n/pose.ko.ts +104 -0
- package/src/i18n/pose.pt-BR.ts +104 -0
- package/src/i18n/pose.ru.ts +104 -0
- package/src/i18n/pose.zh-CN.ts +104 -0
- package/src/i18n/post-process-effects.ar.ts +25 -0
- package/src/i18n/post-process-effects.de.ts +24 -0
- package/src/i18n/post-process-effects.es.ts +26 -0
- package/src/i18n/post-process-effects.fr.ts +24 -0
- package/src/i18n/post-process-effects.he.ts +24 -0
- package/src/i18n/post-process-effects.hi.ts +26 -0
- package/src/i18n/post-process-effects.ja.ts +26 -0
- package/src/i18n/post-process-effects.ko.ts +26 -0
- package/src/i18n/post-process-effects.pt-BR.ts +24 -0
- package/src/i18n/post-process-effects.ru.ts +24 -0
- package/src/i18n/post-process-effects.zh-CN.ts +24 -0
- package/src/i18n/render-quality.ar.ts +34 -0
- package/src/i18n/render-quality.de.ts +30 -0
- package/src/i18n/render-quality.es.ts +35 -0
- package/src/i18n/render-quality.fr.ts +34 -0
- package/src/i18n/render-quality.he.ts +33 -0
- package/src/i18n/render-quality.hi.ts +39 -0
- package/src/i18n/render-quality.ja.ts +39 -0
- package/src/i18n/render-quality.ko.ts +39 -0
- package/src/i18n/render-quality.pt-BR.ts +37 -0
- package/src/i18n/render-quality.ru.ts +37 -0
- package/src/i18n/render-quality.zh-CN.ts +37 -0
- package/src/i18n/seasons.ar.ts +10 -0
- package/src/i18n/seasons.de.ts +10 -0
- package/src/i18n/seasons.es.ts +10 -0
- package/src/i18n/seasons.fr.ts +10 -0
- package/src/i18n/seasons.he.ts +10 -0
- package/src/i18n/seasons.hi.ts +10 -0
- package/src/i18n/seasons.ja.ts +10 -0
- package/src/i18n/seasons.ko.ts +10 -0
- package/src/i18n/seasons.pt-BR.ts +10 -0
- package/src/i18n/seasons.ru.ts +10 -0
- package/src/i18n/seasons.zh-CN.ts +10 -0
- package/src/i18n/setting.ar.ts +73 -0
- package/src/i18n/setting.de.ts +73 -0
- package/src/i18n/setting.es.ts +77 -0
- package/src/i18n/setting.fr.ts +73 -0
- package/src/i18n/setting.he.ts +76 -0
- package/src/i18n/setting.hi.ts +76 -0
- package/src/i18n/setting.ja.ts +78 -0
- package/src/i18n/setting.ko.ts +76 -0
- package/src/i18n/setting.pt-BR.ts +78 -0
- package/src/i18n/setting.ru.ts +76 -0
- package/src/i18n/setting.zh-CN.ts +76 -0
- package/src/i18n/style.ar.ts +55 -0
- package/src/i18n/style.de.ts +54 -0
- package/src/i18n/style.es.ts +54 -0
- package/src/i18n/style.fr.ts +54 -0
- package/src/i18n/style.he.ts +54 -0
- package/src/i18n/style.hi.ts +54 -0
- package/src/i18n/style.ja.ts +54 -0
- package/src/i18n/style.ko.ts +54 -0
- package/src/i18n/style.pt-BR.ts +56 -0
- package/src/i18n/style.ru.ts +54 -0
- package/src/i18n/style.zh-CN.ts +54 -0
- package/src/i18n/styling.ar.ts +295 -0
- package/src/i18n/styling.de.ts +285 -0
- package/src/i18n/styling.es.ts +317 -0
- package/src/i18n/styling.fr.ts +285 -0
- package/src/i18n/styling.he.ts +307 -0
- package/src/i18n/styling.hi.ts +323 -0
- package/src/i18n/styling.ja.ts +317 -0
- package/src/i18n/styling.ko.ts +311 -0
- package/src/i18n/styling.pt-BR.ts +301 -0
- package/src/i18n/styling.ru.ts +301 -0
- package/src/i18n/styling.zh-CN.ts +307 -0
- package/src/i18n/temporal.ar.ts +31 -0
- package/src/i18n/temporal.de.ts +24 -0
- package/src/i18n/temporal.es.ts +27 -0
- package/src/i18n/temporal.fr.ts +28 -0
- package/src/i18n/temporal.he.ts +31 -0
- package/src/i18n/temporal.hi.ts +31 -0
- package/src/i18n/temporal.ja.ts +31 -0
- package/src/i18n/temporal.ko.ts +31 -0
- package/src/i18n/temporal.pt-BR.ts +31 -0
- package/src/i18n/temporal.ru.ts +31 -0
- package/src/i18n/temporal.zh-CN.ts +31 -0
- package/src/i18n/transitions.ar.ts +97 -0
- package/src/i18n/transitions.de.ts +97 -0
- package/src/i18n/transitions.es.ts +97 -0
- package/src/i18n/transitions.fr.ts +97 -0
- package/src/i18n/transitions.he.ts +97 -0
- package/src/i18n/transitions.hi.ts +97 -0
- package/src/i18n/transitions.ja.ts +97 -0
- package/src/i18n/transitions.ko.ts +97 -0
- package/src/i18n/transitions.pt-BR.ts +97 -0
- package/src/i18n/transitions.ru.ts +97 -0
- package/src/i18n/transitions.zh-CN.ts +97 -0
- package/src/i18n/types.ts +158 -0
- package/src/i18n/vehicles.ar.ts +137 -0
- package/src/i18n/vehicles.de.ts +125 -0
- package/src/i18n/vehicles.es.ts +138 -0
- package/src/i18n/vehicles.fr.ts +125 -0
- package/src/i18n/vehicles.he.ts +136 -0
- package/src/i18n/vehicles.hi.ts +138 -0
- package/src/i18n/vehicles.ja.ts +138 -0
- package/src/i18n/vehicles.ko.ts +138 -0
- package/src/i18n/vehicles.pt-BR.ts +136 -0
- package/src/i18n/vehicles.ru.ts +136 -0
- package/src/i18n/vehicles.zh-CN.ts +136 -0
- package/src/i18n/voice-character.ar.ts +126 -0
- package/src/i18n/voice-character.de.ts +126 -0
- package/src/i18n/voice-character.es.ts +126 -0
- package/src/i18n/voice-character.fr.ts +126 -0
- package/src/i18n/voice-character.he.ts +126 -0
- package/src/i18n/voice-character.hi.ts +126 -0
- package/src/i18n/voice-character.ja.ts +126 -0
- package/src/i18n/voice-character.ko.ts +126 -0
- package/src/i18n/voice-character.pt-BR.ts +126 -0
- package/src/i18n/voice-character.ru.ts +126 -0
- package/src/i18n/voice-character.zh-CN.ts +126 -0
- package/src/i18n/voice-delivery.ar.ts +77 -0
- package/src/i18n/voice-delivery.de.ts +77 -0
- package/src/i18n/voice-delivery.es.ts +77 -0
- package/src/i18n/voice-delivery.fr.ts +77 -0
- package/src/i18n/voice-delivery.he.ts +77 -0
- package/src/i18n/voice-delivery.hi.ts +77 -0
- package/src/i18n/voice-delivery.ja.ts +77 -0
- package/src/i18n/voice-delivery.ko.ts +77 -0
- package/src/i18n/voice-delivery.pt-BR.ts +77 -0
- package/src/i18n/voice-delivery.ru.ts +77 -0
- package/src/i18n/voice-delivery.zh-CN.ts +77 -0
- package/src/i18n/weapons.ar.ts +115 -0
- package/src/i18n/weapons.de.ts +114 -0
- package/src/i18n/weapons.es.ts +116 -0
- package/src/i18n/weapons.fr.ts +103 -0
- package/src/i18n/weapons.he.ts +114 -0
- package/src/i18n/weapons.hi.ts +116 -0
- package/src/i18n/weapons.ja.ts +116 -0
- package/src/i18n/weapons.ko.ts +116 -0
- package/src/i18n/weapons.pt-BR.ts +114 -0
- package/src/i18n/weapons.ru.ts +114 -0
- package/src/i18n/weapons.zh-CN.ts +114 -0
- package/src/image-critic-node.ts +61 -0
- package/src/image-critic-types.ts +40 -0
- package/src/index.ts +866 -0
- package/src/inject-upstream.ts +15 -0
- package/src/inpaint-region.ts +51 -0
- package/src/json-evaluator.ts +732 -0
- package/src/json-path.ts +52 -0
- package/src/lip-sync-pricing.ts +90 -0
- package/src/list-merge.ts +40 -0
- package/src/list-sort.ts +122 -0
- package/src/list-source-resolver.ts +50 -0
- package/src/llm-models.ts +245 -0
- package/src/location-mention-slug.ts +291 -0
- package/src/location-preset-catalog-map.ts +128 -0
- package/src/loop-delimiter.ts +73 -0
- package/src/lora-routing.ts +95 -0
- package/src/lottie-overlay-catalog.ts +175 -0
- package/src/lottie-slots.ts +309 -0
- package/src/model-catalog.ts +2386 -0
- package/src/model-constants.ts +1910 -0
- package/src/model-tree.ts +120 -0
- package/src/monetization.ts +15 -0
- package/src/multi-pick.ts +42 -0
- package/src/node-default-mappings.ts +262 -0
- package/src/node-mappable-fields.ts +70 -0
- package/src/node-preset-export.ts +56 -0
- package/src/node-preset-extract.ts +147 -0
- package/src/node-refs.ts +253 -0
- package/src/node-runtime-keys.ts +117 -0
- package/src/object-aspect-defaults.ts +72 -0
- package/src/object-picker-types.ts +22 -0
- package/src/parameter-node-value.ts +284 -0
- package/src/pinterest-url.ts +28 -0
- package/src/pipeline-chat.ts +72 -0
- package/src/pipeline-defaults.ts +318 -0
- package/src/pipeline-events.ts +162 -0
- package/src/pipeline-state-types.ts +196 -0
- package/src/pipeline-types.ts +647 -0
- package/src/pipeline-validation.ts +87 -0
- package/src/presentation-types.ts +23 -0
- package/src/presentation-utils.ts +397 -0
- package/src/producer-types.ts +188 -0
- package/src/progress-curve.ts +99 -0
- package/src/provider-directive-defaults.ts +69 -0
- package/src/reduce-strategy-registry.ts +121 -0
- package/src/reference-board-templates.ts +81 -0
- package/src/reference-roles.ts +153 -0
- package/src/reference-sheet/__tests__/board-to-column.test.ts +20 -0
- package/src/reference-sheet/__tests__/catalog.test.ts +50 -0
- package/src/reference-sheet/__tests__/cost.test.ts +38 -0
- package/src/reference-sheet/__tests__/no-drift.test.ts +28 -0
- package/src/reference-sheet/__tests__/panel-plan.test.ts +61 -0
- package/src/reference-sheet/__tests__/panel-prompts.test.ts +17 -0
- package/src/reference-sheet/__tests__/plan-generation.test.ts +72 -0
- package/src/reference-sheet/__tests__/presets.test.ts +54 -0
- package/src/reference-sheet/__tests__/types.test.ts +24 -0
- package/src/reference-sheet/catalog.ts +144 -0
- package/src/reference-sheet/cost.ts +37 -0
- package/src/reference-sheet/credit-id.ts +7 -0
- package/src/reference-sheet/index.ts +8 -0
- package/src/reference-sheet/panel-plan.ts +65 -0
- package/src/reference-sheet/panel-prompts.ts +14 -0
- package/src/reference-sheet/plan-generation.ts +79 -0
- package/src/reference-sheet/presets.ts +77 -0
- package/src/reference-sheet/types.ts +92 -0
- package/src/repeat-types.ts +97 -0
- package/src/resolve-field-mappings.ts +119 -0
- package/src/route-filter.ts +80 -0
- package/src/scene-helper-types.ts +249 -0
- package/src/scene-node-types.ts +281 -0
- package/src/scraper-actors.ts +57 -0
- package/src/scraper-output-schemas.ts +25 -0
- package/src/seasons.ts +45 -0
- package/src/selector.ts +864 -0
- package/src/settled-with-limit.ts +42 -0
- package/src/shot-element.ts +43 -0
- package/src/social-media-specs.ts +121 -0
- package/src/social-post.ts +24 -0
- package/src/sub-workflow-validation.ts +78 -0
- package/src/supported-fonts.ts +40 -0
- package/src/surround.ts +113 -0
- package/src/switchx-pricing.ts +33 -0
- package/src/text-separators.ts +59 -0
- package/src/to-connected-references.ts +77 -0
- package/src/types.ts +272 -0
- package/src/variant-job-id.ts +17 -0
- package/src/vehicles.ts +213 -0
- package/src/video-analysis-pricing.ts +74 -0
- package/src/video-analysis.ts +127 -0
- package/src/video-duration.ts +25 -0
- package/src/voice-changer-models.ts +36 -0
- package/src/voice-matcher-types.ts +37 -0
- package/src/voices.ts +92 -0
- package/src/weapons.ts +190 -0
- package/src/workflow-export.ts +153 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { TtsProvider } from "./model-constants.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How the TTS layer resolves a voice id. Mirrors `CharacterVoice.voiceType` on
|
|
5
|
+
* the frontend character node: `premade` voices resolve by NAME, `library` /
|
|
6
|
+
* `custom` voices resolve by ID. Carry it alongside the id or premade-vs-library
|
|
7
|
+
* resolution misroutes (see backend `direct-tts.ts`).
|
|
8
|
+
*/
|
|
9
|
+
export type VoiceType = "premade" | "library" | "custom"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A character's saved voice as supplied to the voiced-video orchestration on
|
|
13
|
+
* `POST /v1/generate-video`. A deliberate subset of the frontend `CharacterVoice`:
|
|
14
|
+
* only the fields the server needs to synthesise speech (no `voiceName` /
|
|
15
|
+
* `traits` / `previewUrl`, which are display-only and never read server-side).
|
|
16
|
+
*
|
|
17
|
+
* `speaker` is the join key: it matches a {@link DialogueLine}.speaker so a
|
|
18
|
+
* multi-speaker prompt routes each line to its own voice. Omit it for a
|
|
19
|
+
* single-voice clip (one spec, no dialogue attribution needed).
|
|
20
|
+
*/
|
|
21
|
+
export interface CharacterVoiceSpec {
|
|
22
|
+
/** ElevenLabs voice id, or the premade voice NAME when `voiceType === "premade"`. */
|
|
23
|
+
readonly voiceId: string
|
|
24
|
+
/** How the TTS layer resolves {@link voiceId}. Defaults to `"premade"` downstream. */
|
|
25
|
+
readonly voiceType?: VoiceType
|
|
26
|
+
/** Recommended TTS provider for this voice; forwarded as `provider` to TTS. */
|
|
27
|
+
readonly ttsProvider?: TtsProvider
|
|
28
|
+
/**
|
|
29
|
+
* Speaker label this voice belongs to (e.g. "Anna"). Joined to
|
|
30
|
+
* {@link DialogueLine}.speaker case-insensitively (trimmed). Omit for a
|
|
31
|
+
* single-voice clip.
|
|
32
|
+
*/
|
|
33
|
+
readonly speaker?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** One attributed line of dialogue: who speaks (`speaker`) and what they say (`line`). */
|
|
37
|
+
export interface DialogueLine {
|
|
38
|
+
readonly speaker: string
|
|
39
|
+
readonly line: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A dialogue line resolved to a concrete voice, in the exact shape the
|
|
44
|
+
* ElevenLabs Dialogue v3 primitive (`POST /v1/text-to-dialogue`) consumes:
|
|
45
|
+
* `{ text, voice }` per line, in order. `voiceType` rides along so the TTS layer
|
|
46
|
+
* resolves premade-by-name vs library/custom-by-id correctly.
|
|
47
|
+
*/
|
|
48
|
+
export interface ResolvedDialogueVoiceLine {
|
|
49
|
+
readonly text: string
|
|
50
|
+
readonly voice: string
|
|
51
|
+
readonly voiceType?: VoiceType
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Quote characters built from code points so this file stays pure ASCII. The
|
|
55
|
+
// published @nodaro/shared package must survive a re-save in any locale, and a
|
|
56
|
+
// literal curly quote or em-dash here is exactly the CP1255 mojibake hazard that
|
|
57
|
+
// has reached main before. RDQUO/LDQUO = curly double quotes, RAQUO/LAQUO =
|
|
58
|
+
// guillemets, RSQUO = right single quote (apostrophe inside a name like O'Brien).
|
|
59
|
+
const RDQUO = String.fromCharCode(0x201d)
|
|
60
|
+
const LDQUO = String.fromCharCode(0x201c)
|
|
61
|
+
const RAQUO = String.fromCharCode(0x00bb)
|
|
62
|
+
const LAQUO = String.fromCharCode(0x00ab)
|
|
63
|
+
const RSQUO = String.fromCharCode(0x2019)
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Matches one attributed, QUOTED line of dialogue. Built with `new RegExp` +
|
|
67
|
+
* `String.raw` so the regex backslashes stay literal while the non-ASCII quote
|
|
68
|
+
* characters are injected from the code-point consts above.
|
|
69
|
+
*
|
|
70
|
+
* - A leading boundary lookbehind (`^`, newline, sentence punctuation, or a
|
|
71
|
+
* CLOSING quote) keeps the speaker capture from bridging a sentence: e.g.
|
|
72
|
+
* "...kitchen. Anna: "hi"" yields speaker "Anna", not "kitchen. Anna", and the
|
|
73
|
+
* speaker after a closing quote ("hi" Gordon: "yo") is still found.
|
|
74
|
+
* - Speaker = 1 to 4 short words (names are short; no "." inside a token).
|
|
75
|
+
* - Body = the first quoted run in straight, curly, or guillemet quotes.
|
|
76
|
+
*
|
|
77
|
+
* Requiring quotes is what stops cinematic direction ("Setting: a forest",
|
|
78
|
+
* "Camera: dolly in") from being read as dialogue.
|
|
79
|
+
*/
|
|
80
|
+
const ATTRIBUTED_DIALOGUE_RE = new RegExp(
|
|
81
|
+
String.raw`(?<=^|[\n\r.!?;,"${RDQUO}${RAQUO}])\s*([\p{L}][\p{L}\p{N}'${RSQUO}-]*(?:\s+[\p{L}][\p{L}\p{N}'${RSQUO}-]*){0,3})\s*:\s*(?:"([^"]+)"|${LDQUO}([^${RDQUO}]+)${RDQUO}|${LAQUO}([^${RAQUO}]+)${RAQUO})`,
|
|
82
|
+
"gu",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Extract attributed dialogue (`Speaker: "line"`) from a free-text prompt.
|
|
87
|
+
*
|
|
88
|
+
* Deterministic and intentionally conservative (see {@link ATTRIBUTED_DIALOGUE_RE}):
|
|
89
|
+
* only QUOTED lines attributed to a short speaker label are matched. Callers that
|
|
90
|
+
* already have structured dialogue (studio prompt chips) should pass it directly
|
|
91
|
+
* and skip this parser. Order is preserved (it drives the stitched dialogue
|
|
92
|
+
* track). Returns `[]` when no attributed quoted dialogue is found.
|
|
93
|
+
*/
|
|
94
|
+
export function parseAttributedDialogue(prompt: string): DialogueLine[] {
|
|
95
|
+
if (!prompt) return []
|
|
96
|
+
const out: DialogueLine[] = []
|
|
97
|
+
for (const m of prompt.matchAll(ATTRIBUTED_DIALOGUE_RE)) {
|
|
98
|
+
const speaker = m[1]?.trim() ?? ""
|
|
99
|
+
const line = (m[2] ?? m[3] ?? m[4] ?? "").trim()
|
|
100
|
+
if (speaker && line) out.push({ speaker, line })
|
|
101
|
+
}
|
|
102
|
+
return out
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Resolve each dialogue line to a concrete voice by joining `line.speaker` to
|
|
107
|
+
* `voices[].speaker` (case-insensitive, trimmed) - the "Speaker mapping" model.
|
|
108
|
+
*
|
|
109
|
+
* Fallback order for an unmatched / unattributed line: the matched speaker's
|
|
110
|
+
* voice -> `defaultVoiceId` -> the sole voice (when exactly one spec is given) ->
|
|
111
|
+
* the first voice. A line resolves to nothing only when there are no voices and
|
|
112
|
+
* no default, in which case it is dropped (the caller decides whether an empty
|
|
113
|
+
* result means "no dialogue to synthesise"). This mirrors the pipeline's
|
|
114
|
+
* non-fatal missing-voice behaviour (`allowDefaultVoiceFallback`).
|
|
115
|
+
*/
|
|
116
|
+
export function resolveDialogueVoices(
|
|
117
|
+
dialogue: readonly DialogueLine[],
|
|
118
|
+
voices: readonly CharacterVoiceSpec[],
|
|
119
|
+
defaultVoiceId?: string,
|
|
120
|
+
): ResolvedDialogueVoiceLine[] {
|
|
121
|
+
const bySpeaker = new Map<string, CharacterVoiceSpec>()
|
|
122
|
+
for (const v of voices) {
|
|
123
|
+
const key = v.speaker?.trim().toLowerCase()
|
|
124
|
+
if (key) bySpeaker.set(key, v)
|
|
125
|
+
}
|
|
126
|
+
const soleVoice = voices.length === 1 ? voices[0] : undefined
|
|
127
|
+
const firstVoice = voices[0]
|
|
128
|
+
|
|
129
|
+
const lineFor = (text: string, spec: CharacterVoiceSpec): ResolvedDialogueVoiceLine => ({
|
|
130
|
+
text,
|
|
131
|
+
voice: spec.voiceId,
|
|
132
|
+
...(spec.voiceType ? { voiceType: spec.voiceType } : {}),
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
const out: ResolvedDialogueVoiceLine[] = []
|
|
136
|
+
for (const { speaker, line } of dialogue) {
|
|
137
|
+
const text = line.trim()
|
|
138
|
+
if (!text) continue
|
|
139
|
+
const matched = bySpeaker.get(speaker.trim().toLowerCase())
|
|
140
|
+
if (matched) {
|
|
141
|
+
out.push(lineFor(text, matched))
|
|
142
|
+
} else if (defaultVoiceId) {
|
|
143
|
+
out.push({ text, voice: defaultVoiceId })
|
|
144
|
+
} else if (soleVoice) {
|
|
145
|
+
out.push(lineFor(text, soleVoice))
|
|
146
|
+
} else if (firstVoice) {
|
|
147
|
+
out.push(lineFor(text, firstVoice))
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return out
|
|
151
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cinematic Avatar (HeyGen `type:"cinematic_avatar"`) duration-clamping +
|
|
3
|
+
* credit-identifier helpers. Single source of truth for the NON-monetary side
|
|
4
|
+
* of cinematic-avatar billing — imported by the frontend node UI and the
|
|
5
|
+
* backend route/orchestrator.
|
|
6
|
+
*
|
|
7
|
+
* The provider-$ rate table and the USD/credit cost FORMULAS derived from it
|
|
8
|
+
* live in `backend/src/lib/pricing/cinematic-avatar-cost.ts` (core, not ee/ —
|
|
9
|
+
* the HeyGen provider integration needs them regardless of edition). They
|
|
10
|
+
* 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
|
+
*
|
|
13
|
+
* ─── How this differs from ai-avatar pricing ────────────────────────────────
|
|
14
|
+
* Cinematic Avatar is a generative clip (Seedance-style pipeline) driven by a
|
|
15
|
+
* prompt + 1–3 avatar look ids. Crucially, `duration` is a USER PARAMETER
|
|
16
|
+
* (4–15s, clamped) and is therefore KNOWN at submit time — unlike ai-avatar's
|
|
17
|
+
* text/audio script whose clip length is only estimated. So the reserve here is
|
|
18
|
+
* EXACT (no duration-bucket estimation): the credit id encodes the exact
|
|
19
|
+
* requested duration, and the metered true-up at commit refunds nothing in the
|
|
20
|
+
* common case (provider returns the requested duration).
|
|
21
|
+
* ────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export type CinematicResolution = "720p" | "1080p"
|
|
25
|
+
|
|
26
|
+
/** Minimum / maximum / default user-selectable duration (seconds). */
|
|
27
|
+
export const CINEMATIC_MIN_DURATION_SEC = 4
|
|
28
|
+
export const CINEMATIC_MAX_DURATION_SEC = 15
|
|
29
|
+
export const CINEMATIC_DEFAULT_DURATION_SEC = 10
|
|
30
|
+
export const CINEMATIC_DEFAULT_RESOLUTION: CinematicResolution = "720p"
|
|
31
|
+
|
|
32
|
+
const ALLOWED_RESOLUTIONS = new Set<CinematicResolution>(["720p", "1080p"])
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Clamp a (possibly invalid) duration to the legal 4–15s range, rounding to a
|
|
36
|
+
* whole second. Falls back to the default (10s) for non-finite input.
|
|
37
|
+
*/
|
|
38
|
+
export function clampCinematicDuration(durationSec: number | undefined): number {
|
|
39
|
+
const n = Number(durationSec)
|
|
40
|
+
if (!Number.isFinite(n)) return CINEMATIC_DEFAULT_DURATION_SEC
|
|
41
|
+
const rounded = Math.round(n)
|
|
42
|
+
return Math.min(
|
|
43
|
+
CINEMATIC_MAX_DURATION_SEC,
|
|
44
|
+
Math.max(CINEMATIC_MIN_DURATION_SEC, rounded),
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Composite credit identifier for an EXACT-duration reserve.
|
|
50
|
+
*
|
|
51
|
+
* Format: `cinematic-avatar:<resolution>:<durationSec>s`
|
|
52
|
+
* e.g. `cinematic-avatar:720p:10s`.
|
|
53
|
+
*/
|
|
54
|
+
export function cinematicCreditId(
|
|
55
|
+
resolution: CinematicResolution,
|
|
56
|
+
durationSec: number,
|
|
57
|
+
): string {
|
|
58
|
+
return `cinematic-avatar:${resolution}:${durationSec}s`
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the credit identifier from a raw request body BEFORE Zod validation.
|
|
63
|
+
* Called at creditGuard preHandler time — mirrors resolveAiAvatarCreditId.
|
|
64
|
+
*
|
|
65
|
+
* Reads `resolution` (default 720p) and `duration` (default 10, clamped 4–15)
|
|
66
|
+
* straight off the raw body. Because duration is a user parameter known at
|
|
67
|
+
* submit time, the reserve id is EXACT — no bucketing.
|
|
68
|
+
*
|
|
69
|
+
* ─── autoDuration → reserve at the MAX-duration ceiling ──────────────────────
|
|
70
|
+
* When `autoDuration` is true, the provider DROPS `duration` and HeyGen picks
|
|
71
|
+
* the clip length itself, so the actual metered length is UNKNOWN at submit
|
|
72
|
+
* time and can exceed the requested/default `duration`. The metered true-up at
|
|
73
|
+
* commit (commit_credits) can ONLY refund a surplus — it never charges more
|
|
74
|
+
* when the actual exceeds the reserved hold. Reserving under the default-10s
|
|
75
|
+
* hold therefore silently undercharges any auto clip longer than 10s (a revenue
|
|
76
|
+
* leak). To preserve the refund-only invariant, reserve under the MAXIMUM
|
|
77
|
+
* possible hold (`cinematic-avatar:<res>:15s`) so the true-up can only refund.
|
|
78
|
+
*/
|
|
79
|
+
export function resolveCinematicCreditId(
|
|
80
|
+
body: Record<string, unknown> | undefined,
|
|
81
|
+
): string {
|
|
82
|
+
const rawResolution = body?.resolution as string | undefined
|
|
83
|
+
const resolution: CinematicResolution =
|
|
84
|
+
rawResolution !== undefined && ALLOWED_RESOLUTIONS.has(rawResolution as CinematicResolution)
|
|
85
|
+
? (rawResolution as CinematicResolution)
|
|
86
|
+
: CINEMATIC_DEFAULT_RESOLUTION
|
|
87
|
+
|
|
88
|
+
// autoDuration → HeyGen-chosen length, unknown at submit time → reserve at the
|
|
89
|
+
// 15s ceiling so the metered true-up can only ever refund (never charge more).
|
|
90
|
+
if (body?.autoDuration === true) {
|
|
91
|
+
return cinematicCreditId(resolution, CINEMATIC_MAX_DURATION_SEC)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const durationSec = clampCinematicDuration(body?.duration as number | undefined)
|
|
95
|
+
return cinematicCreditId(resolution, durationSec)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* All 24 reserve credit IDs — every (resolution × duration) combination.
|
|
100
|
+
* 2 resolutions × 12 durations (4..15s) = 24.
|
|
101
|
+
* Seeded in STATIC_CREDIT_COSTS and the model_pricing migration so
|
|
102
|
+
* getModelCreditBaseCost never hard-fails (503 price_not_configured) for any
|
|
103
|
+
* legal creditGuard input.
|
|
104
|
+
*/
|
|
105
|
+
export const CINEMATIC_RESERVE_IDS: string[] = [...ALLOWED_RESOLUTIONS].flatMap((resolution) => {
|
|
106
|
+
const ids: string[] = []
|
|
107
|
+
for (let d = CINEMATIC_MIN_DURATION_SEC; d <= CINEMATIC_MAX_DURATION_SEC; d++) {
|
|
108
|
+
ids.push(cinematicCreditId(resolution, d))
|
|
109
|
+
}
|
|
110
|
+
return ids
|
|
111
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for detecting and filtering expanded loop clones.
|
|
3
|
+
* Shared between frontend (store, persistence, execution) and backend (orchestrator).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { GenericNode, GenericEdge } from "./types.js"
|
|
7
|
+
|
|
8
|
+
/** Matches node IDs like `node_7_iter_0`, `node_7_iter_1`, etc. */
|
|
9
|
+
export const ITER_CLONE_PATTERN = /_iter_\d+$/
|
|
10
|
+
|
|
11
|
+
/** Returns true if the node is an expanded loop clone (by flag or ID pattern). */
|
|
12
|
+
export function isExpandedClone(node: GenericNode): boolean {
|
|
13
|
+
return !!(node.data as Record<string, unknown>).__expandedClone || ITER_CLONE_PATTERN.test(node.id)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Filter out expanded clone nodes and edges that reference them.
|
|
18
|
+
* Unhides original nodes that were hidden during loop expansion.
|
|
19
|
+
* Optionally filters sub-workflow nodes (prefix `__sub_`).
|
|
20
|
+
*/
|
|
21
|
+
export function filterCloneNodes<N extends GenericNode, E extends GenericEdge>(
|
|
22
|
+
nodes: N[],
|
|
23
|
+
edges: E[],
|
|
24
|
+
options?: { filterSubWorkflow?: boolean },
|
|
25
|
+
): { nodes: N[]; edges: E[] } {
|
|
26
|
+
const filterSub = options?.filterSubWorkflow ?? false
|
|
27
|
+
|
|
28
|
+
const cloneIds = new Set(
|
|
29
|
+
nodes.filter((n) => isExpandedClone(n)).map((n) => n.id),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const filteredNodes = nodes
|
|
33
|
+
.filter((n) => {
|
|
34
|
+
if (cloneIds.has(n.id)) return false
|
|
35
|
+
if (filterSub && n.id.startsWith("__sub_")) return false
|
|
36
|
+
return true
|
|
37
|
+
})
|
|
38
|
+
.map((n) => (n.hidden ? { ...n, hidden: false } as N : n))
|
|
39
|
+
|
|
40
|
+
const filteredEdges = edges.filter((e) => {
|
|
41
|
+
if (filterSub && (e as { id?: string }).id?.startsWith("__sub_")) return false
|
|
42
|
+
return !cloneIds.has(e.source) && !cloneIds.has(e.target)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
return { nodes: filteredNodes, edges: filteredEdges }
|
|
46
|
+
}
|