davinci-resolve-mcp 2.57.4 → 2.58.0

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 (328) hide show
  1. package/AGENTS.md +20 -0
  2. package/CHANGELOG.md +197 -2
  3. package/LICENSE +1 -1
  4. package/README.md +73 -1
  5. package/bin/davinci-resolve-advanced-mcp.mjs +20 -0
  6. package/docs/README.md +19 -0
  7. package/docs/SKILL.md +62 -1
  8. package/docs/contributing.md +1 -1
  9. package/docs/guides/control-panel.md +9 -0
  10. package/docs/kernels/README.md +21 -0
  11. package/docs/kernels/audio-fairlight-kernel.md +22 -0
  12. package/docs/kernels/color-grade-kernel.md +51 -0
  13. package/docs/kernels/fusion-composition-kernel.md +17 -0
  14. package/docs/kernels/media-pool-ingest-kernel.md +20 -0
  15. package/docs/kernels/render-deliver-kernel.md +32 -0
  16. package/docs/kernels/timeline-conform-interchange-kernel.md +39 -0
  17. package/docs/kernels/timeline-edit-kernel.md +17 -0
  18. package/docs/process/release-process.md +29 -7
  19. package/docs/reference/api-coverage.md +1 -1
  20. package/docs/reference/api-limitations.md +38 -1
  21. package/install.py +27 -4
  22. package/package.json +23 -2
  23. package/resolve-advanced/README.md +194 -0
  24. package/resolve-advanced/package.json +50 -0
  25. package/resolve-advanced/server/black-balance.mjs +92 -0
  26. package/resolve-advanced/server/capabilities.mjs +86 -0
  27. package/resolve-advanced/server/cdl-io.mjs +76 -0
  28. package/resolve-advanced/server/contrast-normalize.mjs +180 -0
  29. package/resolve-advanced/server/db-patch.mjs +91 -0
  30. package/resolve-advanced/server/deliverable-entities.mjs +86 -0
  31. package/resolve-advanced/server/deliverable-qc.mjs +270 -0
  32. package/resolve-advanced/server/editorial.mjs +370 -0
  33. package/resolve-advanced/server/exposure-level.mjs +129 -0
  34. package/resolve-advanced/server/extract-frames.mjs +196 -0
  35. package/resolve-advanced/server/ffprobe-media.mjs +88 -0
  36. package/resolve-advanced/server/gamut-legal.mjs +112 -0
  37. package/resolve-advanced/server/grade-body-patch.mjs +246 -0
  38. package/resolve-advanced/server/grade-transfer.mjs +66 -0
  39. package/resolve-advanced/server/group-grade-read.mjs +137 -0
  40. package/resolve-advanced/server/index.mjs +105 -0
  41. package/resolve-advanced/server/lib.mjs +84 -0
  42. package/resolve-advanced/server/libs.mjs +65 -0
  43. package/resolve-advanced/server/lineage-db.mjs +479 -0
  44. package/resolve-advanced/server/lut-apply.mjs +61 -0
  45. package/resolve-advanced/server/match-to-reference.mjs +173 -0
  46. package/resolve-advanced/server/media-inventory.mjs +169 -0
  47. package/resolve-advanced/server/media-ops.mjs +243 -0
  48. package/resolve-advanced/server/node-meta-db.mjs +62 -0
  49. package/resolve-advanced/server/node-provenance.mjs +102 -0
  50. package/resolve-advanced/server/offline-ref-db.mjs +420 -0
  51. package/resolve-advanced/server/offline-ref.mjs +179 -0
  52. package/resolve-advanced/server/project-db.mjs +233 -0
  53. package/resolve-advanced/server/provenance-audit.mjs +210 -0
  54. package/resolve-advanced/server/qc-frame.mjs +224 -0
  55. package/resolve-advanced/server/qc-sampler.mjs +67 -0
  56. package/resolve-advanced/server/readback.mjs +77 -0
  57. package/resolve-advanced/server/render-manifest.mjs +93 -0
  58. package/resolve-advanced/server/reverse-clip-db.mjs +270 -0
  59. package/resolve-advanced/server/runner-apply-contract.mjs +64 -0
  60. package/resolve-advanced/server/runner.mjs +244 -0
  61. package/resolve-advanced/server/saturation-match.mjs +108 -0
  62. package/resolve-advanced/server/scope-read.mjs +257 -0
  63. package/resolve-advanced/server/season-look.mjs +96 -0
  64. package/resolve-advanced/server/shot-intent.mjs +82 -0
  65. package/resolve-advanced/server/shot-match.mjs +147 -0
  66. package/resolve-advanced/server/skin-match.mjs +205 -0
  67. package/resolve-advanced/server/spec-compile.mjs +217 -0
  68. package/resolve-advanced/server/tone-curve-transfer.mjs +184 -0
  69. package/resolve-advanced/server/tool-catalog.mjs +265 -0
  70. package/resolve-advanced/server/tools/audio.mjs +54 -0
  71. package/resolve-advanced/server/tools/audio_plan.mjs +58 -0
  72. package/resolve-advanced/server/tools/capabilities.mjs +16 -0
  73. package/resolve-advanced/server/tools/color_trace.mjs +165 -0
  74. package/resolve-advanced/server/tools/conform.mjs +291 -0
  75. package/resolve-advanced/server/tools/deliverable.mjs +105 -0
  76. package/resolve-advanced/server/tools/drp.mjs +232 -0
  77. package/resolve-advanced/server/tools/drt.mjs +200 -0
  78. package/resolve-advanced/server/tools/drx.mjs +943 -0
  79. package/resolve-advanced/server/tools/editorial.mjs +69 -0
  80. package/resolve-advanced/server/tools/fairlight.mjs +108 -0
  81. package/resolve-advanced/server/tools/fusion.mjs +64 -0
  82. package/resolve-advanced/server/tools/media.mjs +102 -0
  83. package/resolve-advanced/server/tools/offline_ref.mjs +123 -0
  84. package/resolve-advanced/server/tools/pipeline.mjs +137 -0
  85. package/resolve-advanced/server/tools/project_db.mjs +200 -0
  86. package/resolve-advanced/server/tools/project_read.mjs +212 -0
  87. package/resolve-advanced/server/tools/provenance.mjs +73 -0
  88. package/resolve-advanced/server/verify-grade.mjs +113 -0
  89. package/resolve-advanced/server/white-balance-match.mjs +122 -0
  90. package/resolve-advanced/vendor/audio/format-converter.js +330 -0
  91. package/resolve-advanced/vendor/audio/split.js +173 -0
  92. package/resolve-advanced/vendor/audio/trim.js +188 -0
  93. package/resolve-advanced/vendor/audio-fairlight/index.js +391 -0
  94. package/resolve-advanced/vendor/conform-qc/adapters/frame-sampler.js +56 -0
  95. package/resolve-advanced/vendor/conform-qc/adapters/local-ffmpeg-sampler.js +65 -0
  96. package/resolve-advanced/vendor/conform-qc/adapters/rendernode-ffmpeg-sampler.js +50 -0
  97. package/resolve-advanced/vendor/conform-qc/adapters/resolve/driver.py +176 -0
  98. package/resolve-advanced/vendor/conform-qc/adapters/resolve-driver.js +61 -0
  99. package/resolve-advanced/vendor/conform-qc/adapters/resolve-headless-driver.js +86 -0
  100. package/resolve-advanced/vendor/conform-qc/adapters/vision-validator.js +75 -0
  101. package/resolve-advanced/vendor/conform-qc/cli.js +63 -0
  102. package/resolve-advanced/vendor/conform-qc/compare/advisory.js +106 -0
  103. package/resolve-advanced/vendor/conform-qc/compare/decode.js +36 -0
  104. package/resolve-advanced/vendor/conform-qc/compare/index.js +61 -0
  105. package/resolve-advanced/vendor/conform-qc/compare/locate.js +70 -0
  106. package/resolve-advanced/vendor/conform-qc/compare/metrics.js +409 -0
  107. package/resolve-advanced/vendor/conform-qc/docs/runbook.md +72 -0
  108. package/resolve-advanced/vendor/conform-qc/index.js +49 -0
  109. package/resolve-advanced/vendor/conform-qc/knowledge/index.js +110 -0
  110. package/resolve-advanced/vendor/conform-qc/ops/conform-core.js +137 -0
  111. package/resolve-advanced/vendor/conform-qc/ops/conform-diff.js +109 -0
  112. package/resolve-advanced/vendor/conform-qc/ops/insert.js +108 -0
  113. package/resolve-advanced/vendor/conform-qc/ops/local-conform.js +61 -0
  114. package/resolve-advanced/vendor/conform-qc/ops/patch.js +80 -0
  115. package/resolve-advanced/vendor/conform-qc/ops/trigger.js +32 -0
  116. package/resolve-advanced/vendor/conform-qc/ops/verify.js +105 -0
  117. package/resolve-advanced/vendor/conform-qc/ops/workflow.js +30 -0
  118. package/resolve-advanced/vendor/conform-qc/oracle/emulate.js +155 -0
  119. package/resolve-advanced/vendor/conform-qc/oracle/index.js +38 -0
  120. package/resolve-advanced/vendor/conform-qc/oracle/resolve.js +196 -0
  121. package/resolve-advanced/vendor/conform-qc/package.json +16 -0
  122. package/resolve-advanced/vendor/conform-qc/packaging/emit-aaf.js +30 -0
  123. package/resolve-advanced/vendor/conform-qc/packaging/emit-fcp7.js +64 -0
  124. package/resolve-advanced/vendor/conform-qc/packaging/index.js +169 -0
  125. package/resolve-advanced/vendor/conform-qc/packaging/media-ops.js +56 -0
  126. package/resolve-advanced/vendor/conform-qc/packaging/otio.js +50 -0
  127. package/resolve-advanced/vendor/conform-qc/packaging/relink.js +50 -0
  128. package/resolve-advanced/vendor/conform-qc/packaging/surgical-relink.js +195 -0
  129. package/resolve-advanced/vendor/conform-qc/parse/index.js +54 -0
  130. package/resolve-advanced/vendor/conform-qc/parse/merge-dto.js +27 -0
  131. package/resolve-advanced/vendor/conform-qc/parse/xmeml-geometry.js +256 -0
  132. package/resolve-advanced/vendor/conform-qc/reference/burnin-ocr.js +100 -0
  133. package/resolve-advanced/vendor/conform-qc/reference/sidecar.js +37 -0
  134. package/resolve-advanced/vendor/conform-qc/repair/analysis.js +62 -0
  135. package/resolve-advanced/vendor/conform-qc/repair/index.js +78 -0
  136. package/resolve-advanced/vendor/conform-qc/repair/media-analysis.js +139 -0
  137. package/resolve-advanced/vendor/conform-qc/repair/media-index.js +135 -0
  138. package/resolve-advanced/vendor/conform-qc/repair/strategies.js +250 -0
  139. package/resolve-advanced/vendor/conform-qc/report/index.js +133 -0
  140. package/resolve-advanced/vendor/conform-qc/roles/index.js +96 -0
  141. package/resolve-advanced/vendor/conform-qc/synthetic/generate.js +233 -0
  142. package/resolve-advanced/vendor/conform-qc/test/advisory.test.js +85 -0
  143. package/resolve-advanced/vendor/conform-qc/test/cli.test.js +39 -0
  144. package/resolve-advanced/vendor/conform-qc/test/compare.test.js +152 -0
  145. package/resolve-advanced/vendor/conform-qc/test/conform-diff.test.js +70 -0
  146. package/resolve-advanced/vendor/conform-qc/test/emulate.test.js +51 -0
  147. package/resolve-advanced/vendor/conform-qc/test/frame-sampler.test.js +30 -0
  148. package/resolve-advanced/vendor/conform-qc/test/geometry.test.js +112 -0
  149. package/resolve-advanced/vendor/conform-qc/test/knowledge.test.js +56 -0
  150. package/resolve-advanced/vendor/conform-qc/test/lifecycle.test.js +110 -0
  151. package/resolve-advanced/vendor/conform-qc/test/local-ffmpeg-sampler.test.js +66 -0
  152. package/resolve-advanced/vendor/conform-qc/test/locate.test.js +63 -0
  153. package/resolve-advanced/vendor/conform-qc/test/media-analysis.test.js +63 -0
  154. package/resolve-advanced/vendor/conform-qc/test/media-index-normalized.test.js +65 -0
  155. package/resolve-advanced/vendor/conform-qc/test/media-index-origin.test.js +53 -0
  156. package/resolve-advanced/vendor/conform-qc/test/metrics-fast.test.js +91 -0
  157. package/resolve-advanced/vendor/conform-qc/test/oracle-reverse.test.js +86 -0
  158. package/resolve-advanced/vendor/conform-qc/test/oracle.test.js +136 -0
  159. package/resolve-advanced/vendor/conform-qc/test/p0-acceptance.test.js +60 -0
  160. package/resolve-advanced/vendor/conform-qc/test/p1-acceptance.test.js +75 -0
  161. package/resolve-advanced/vendor/conform-qc/test/p45-patch-acceptance.test.js +102 -0
  162. package/resolve-advanced/vendor/conform-qc/test/packaging.test.js +133 -0
  163. package/resolve-advanced/vendor/conform-qc/test/parse-stubs.test.js +28 -0
  164. package/resolve-advanced/vendor/conform-qc/test/repair-strategies.test.js +128 -0
  165. package/resolve-advanced/vendor/conform-qc/test/repair.test.js +84 -0
  166. package/resolve-advanced/vendor/conform-qc/test/report.test.js +52 -0
  167. package/resolve-advanced/vendor/conform-qc/test/resolve-readback.test.js +71 -0
  168. package/resolve-advanced/vendor/conform-qc/test/roles.test.js +107 -0
  169. package/resolve-advanced/vendor/conform-qc/test/runbook.test.js +30 -0
  170. package/resolve-advanced/vendor/conform-qc/test/scale-residual.test.js +40 -0
  171. package/resolve-advanced/vendor/conform-qc/test/sidecar.test.js +51 -0
  172. package/resolve-advanced/vendor/conform-qc/test/smoke.test.js +87 -0
  173. package/resolve-advanced/vendor/conform-qc/test/surgical-relink.test.js +73 -0
  174. package/resolve-advanced/vendor/conform-qc/test/synthetic.test.js +98 -0
  175. package/resolve-advanced/vendor/conform-qc/test/verify.test.js +93 -0
  176. package/resolve-advanced/vendor/conform-qc/test/vision-validator.test.js +43 -0
  177. package/resolve-advanced/vendor/conform-qc/test/workflow-driver.test.js +46 -0
  178. package/resolve-advanced/vendor/conform-qc/toolset/index.js +53 -0
  179. package/resolve-advanced/vendor/drp-format/README.md +116 -0
  180. package/resolve-advanced/vendor/drp-format/__tests__/_resolve-verify.js +39 -0
  181. package/resolve-advanced/vendor/drp-format/__tests__/add-media-clip.test.js +30 -0
  182. package/resolve-advanced/vendor/drp-format/__tests__/assemble-timeline.test.js +68 -0
  183. package/resolve-advanced/vendor/drp-format/__tests__/author-project.test.js +57 -0
  184. package/resolve-advanced/vendor/drp-format/__tests__/composition-text.test.js +98 -0
  185. package/resolve-advanced/vendor/drp-format/__tests__/diff.test.js +272 -0
  186. package/resolve-advanced/vendor/drp-format/__tests__/effect-filters-compressed.test.js +143 -0
  187. package/resolve-advanced/vendor/drp-format/__tests__/fixtures/p0-3-session30-empty-effectfilters.drp +0 -0
  188. package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-50pct.hex +1 -0
  189. package/resolve-advanced/vendor/drp-format/__tests__/fixtures/retimed-timemap-dynamic.hex +1 -0
  190. package/resolve-advanced/vendor/drp-format/__tests__/inject-grades.test.js +238 -0
  191. package/resolve-advanced/vendor/drp-format/__tests__/keyed-dict.test.js +85 -0
  192. package/resolve-advanced/vendor/drp-format/__tests__/lut-refs.test.js +119 -0
  193. package/resolve-advanced/vendor/drp-format/__tests__/media-blobs.test.js +25 -0
  194. package/resolve-advanced/vendor/drp-format/__tests__/media-timemap.test.js +119 -0
  195. package/resolve-advanced/vendor/drp-format/__tests__/place-fusion-title.test.js +52 -0
  196. package/resolve-advanced/vendor/drp-format/__tests__/place-generator.test.js +40 -0
  197. package/resolve-advanced/vendor/drp-format/__tests__/place-transition.test.js +48 -0
  198. package/resolve-advanced/vendor/drp-format/__tests__/protobuf-wire.test.js +64 -0
  199. package/resolve-advanced/vendor/drp-format/__tests__/relink-media.test.js +106 -0
  200. package/resolve-advanced/vendor/drp-format/__tests__/splice-clips.test.js +256 -0
  201. package/resolve-advanced/vendor/drp-format/assemble-timeline.js +65 -0
  202. package/resolve-advanced/vendor/drp-format/author-project.js +118 -0
  203. package/resolve-advanced/vendor/drp-format/composition-text.js +213 -0
  204. package/resolve-advanced/vendor/drp-format/curves-encoder.js +763 -0
  205. package/resolve-advanced/vendor/drp-format/diff.js +310 -0
  206. package/resolve-advanced/vendor/drp-format/drp-packager.js +201 -0
  207. package/resolve-advanced/vendor/drp-format/drp-validator.js +809 -0
  208. package/resolve-advanced/vendor/drp-format/effect-encoder.js +640 -0
  209. package/resolve-advanced/vendor/drp-format/extract-lut-refs.js +119 -0
  210. package/resolve-advanced/vendor/drp-format/grade-encoder.example.js +133 -0
  211. package/resolve-advanced/vendor/drp-format/grade-encoder.js +401 -0
  212. package/resolve-advanced/vendor/drp-format/grade-encoder.test.js +171 -0
  213. package/resolve-advanced/vendor/drp-format/grade-encoder.verify.js +249 -0
  214. package/resolve-advanced/vendor/drp-format/grade-node-extractor.js +495 -0
  215. package/resolve-advanced/vendor/drp-format/grade-parameter-decoder.js +774 -0
  216. package/resolve-advanced/vendor/drp-format/index.js +174 -0
  217. package/resolve-advanced/vendor/drp-format/inject-grades.js +219 -0
  218. package/resolve-advanced/vendor/drp-format/keyed-dict.js +227 -0
  219. package/resolve-advanced/vendor/drp-format/marker-encoder.js +532 -0
  220. package/resolve-advanced/vendor/drp-format/media-blobs.js +53 -0
  221. package/resolve-advanced/vendor/drp-format/media-timemap.js +164 -0
  222. package/resolve-advanced/vendor/drp-format/mp-folder-builder.js +293 -0
  223. package/resolve-advanced/vendor/drp-format/node-tree-encoder.js +1246 -0
  224. package/resolve-advanced/vendor/drp-format/package.json +18 -0
  225. package/resolve-advanced/vendor/drp-format/place-fusion-title.js +131 -0
  226. package/resolve-advanced/vendor/drp-format/place-generator.js +77 -0
  227. package/resolve-advanced/vendor/drp-format/place-transition.js +91 -0
  228. package/resolve-advanced/vendor/drp-format/power-window-encoder.js +776 -0
  229. package/resolve-advanced/vendor/drp-format/protobuf-wire.js +111 -0
  230. package/resolve-advanced/vendor/drp-format/qualifier-encoder.js +706 -0
  231. package/resolve-advanced/vendor/drp-format/relink-media.js +218 -0
  232. package/resolve-advanced/vendor/drp-format/rich-title-encoder.js +447 -0
  233. package/resolve-advanced/vendor/drp-format/seq-container-builder.js +572 -0
  234. package/resolve-advanced/vendor/drp-format/seq-surgery.js +155 -0
  235. package/resolve-advanced/vendor/drp-format/splice-clips.js +445 -0
  236. package/resolve-advanced/vendor/drp-format/templates/empty-project.drp +0 -0
  237. package/resolve-advanced/vendor/drp-format/templates/fusion-title.xml +56 -0
  238. package/resolve-advanced/vendor/drp-format/templates/generator-solid-color.xml +21 -0
  239. package/resolve-advanced/vendor/drp-format/templates/media-clip-h264.drp +0 -0
  240. package/resolve-advanced/vendor/drp-format/templates/transition-cross-dissolve.xml +22 -0
  241. package/resolve-advanced/vendor/drp-format/tool-registry.descriptor.js +80 -0
  242. package/resolve-advanced/vendor/drp-format/utils/safe-archive.js +54 -0
  243. package/resolve-advanced/vendor/drp-format/xml-builder.js +759 -0
  244. package/resolve-advanced/vendor/drt-format/__tests__/_resolve-verify.js +21 -0
  245. package/resolve-advanced/vendor/drt-format/__tests__/build.test.js +113 -0
  246. package/resolve-advanced/vendor/drt-format/__tests__/multi-format.test.js +93 -0
  247. package/resolve-advanced/vendor/drt-format/__tests__/parse-real-resolve21.test.js +51 -0
  248. package/resolve-advanced/vendor/drt-format/__tests__/parse.test.js +134 -0
  249. package/resolve-advanced/vendor/drt-format/__tests__/resolve-versions.test.js +120 -0
  250. package/resolve-advanced/vendor/drt-format/__tests__/schema-fingerprint.test.js +62 -0
  251. package/resolve-advanced/vendor/drt-format/__tests__/smoke.test.js +27 -0
  252. package/resolve-advanced/vendor/drt-format/__tests__/validate.test.js +109 -0
  253. package/resolve-advanced/vendor/drt-format/capabilities.js +69 -0
  254. package/resolve-advanced/vendor/drt-format/capability-domains.js +56 -0
  255. package/resolve-advanced/vendor/drt-format/drt-builder.js +42 -0
  256. package/resolve-advanced/vendor/drt-format/drt-parser.js +164 -0
  257. package/resolve-advanced/vendor/drt-format/drt-validator.js +98 -0
  258. package/resolve-advanced/vendor/drt-format/index.js +45 -0
  259. package/resolve-advanced/vendor/drt-format/package.json +17 -0
  260. package/resolve-advanced/vendor/drt-format/resolve-versions.js +153 -0
  261. package/resolve-advanced/vendor/drt-format/schema-fingerprint.js +74 -0
  262. package/resolve-advanced/vendor/drt-format/templates/drt-project-shell.xml +124 -0
  263. package/resolve-advanced/vendor/drx-codec/__tests__/curves-roundtrip.test.js +148 -0
  264. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-face-refinement.drx +58 -0
  265. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-filmgrain.drx +58 -0
  266. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-glow.drx +58 -0
  267. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-1-lens-flare.drx +58 -0
  268. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-25.drx +58 -0
  269. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p2-3-beauty-75.drx +58 -0
  270. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-no-lut.drx +58 -0
  271. package/resolve-advanced/vendor/drx-codec/__tests__/fixtures/p5-1-node-with-lut.drx +58 -0
  272. package/resolve-advanced/vendor/drx-codec/__tests__/hsl-curves-roundtrip.test.js +117 -0
  273. package/resolve-advanced/vendor/drx-codec/__tests__/lut-refs-roundtrip.test.js +112 -0
  274. package/resolve-advanced/vendor/drx-codec/__tests__/matte-roundtrip.test.js +167 -0
  275. package/resolve-advanced/vendor/drx-codec/__tests__/ofx-roundtrip.test.js +215 -0
  276. package/resolve-advanced/vendor/drx-codec/__tests__/ofx-slugs-discovery.test.js +149 -0
  277. package/resolve-advanced/vendor/drx-codec/__tests__/power-window-roundtrip.test.js +230 -0
  278. package/resolve-advanced/vendor/drx-codec/__tests__/qualifier-roundtrip.test.js +226 -0
  279. package/resolve-advanced/vendor/drx-codec/cdl-exporter.js +470 -0
  280. package/resolve-advanced/vendor/drx-codec/color-nlp-parser.js +833 -0
  281. package/resolve-advanced/vendor/drx-codec/data/color-nlp-action-mappings.json +2232 -0
  282. package/resolve-advanced/vendor/drx-codec/drx-generator.js +4123 -0
  283. package/resolve-advanced/vendor/drx-codec/drx-merger.js +320 -0
  284. package/resolve-advanced/vendor/drx-codec/drx-parser.js +1808 -0
  285. package/resolve-advanced/vendor/drx-codec/extract-custom-curves.js +215 -0
  286. package/resolve-advanced/vendor/drx-codec/extract-hsl-curves.js +180 -0
  287. package/resolve-advanced/vendor/drx-codec/extract-lut-refs.js +158 -0
  288. package/resolve-advanced/vendor/drx-codec/extract-matte-finesse.js +83 -0
  289. package/resolve-advanced/vendor/drx-codec/extract-ofx-params.js +226 -0
  290. package/resolve-advanced/vendor/drx-codec/extract-power-window.js +184 -0
  291. package/resolve-advanced/vendor/drx-codec/extract-qualifier.js +99 -0
  292. package/resolve-advanced/vendor/drx-codec/index.js +109 -0
  293. package/resolve-advanced/vendor/drx-codec/node-layout.js +249 -0
  294. package/resolve-advanced/vendor/drx-codec/resolved-drx-generator.js +393 -0
  295. package/resolve-advanced/vendor/drx-codec/tool-resolver.js +974 -0
  296. package/resolve-advanced/vendor/drx-codec/training-examples.js +548 -0
  297. package/resolve-advanced/vendor/drx-codec/vocabulary-intents.js +539 -0
  298. package/resolve-advanced/vendor/drx-parameters/CALIBRATION-STATUS.md +319 -0
  299. package/resolve-advanced/vendor/drx-parameters/DRX-VALUE-SCALING.md +251 -0
  300. package/resolve-advanced/vendor/drx-parameters/calibrated-ranges.json +17737 -0
  301. package/resolve-advanced/vendor/drx-parameters/corrector-types.js +120 -0
  302. package/resolve-advanced/vendor/drx-parameters/index.js +193 -0
  303. package/resolve-advanced/vendor/drx-parameters/parameter-codec.js +451 -0
  304. package/resolve-advanced/vendor/drx-parameters/parameter-ids.js +1292 -0
  305. package/resolve-advanced/vendor/drx-parameters/parameter-ranges.js +570 -0
  306. package/resolve-advanced/vendor/drx-parameters/parameter-validator.js +392 -0
  307. package/resolve-advanced/vendor/drx-parameters/resolvefx-registry.json +14973 -0
  308. package/resolve-advanced/vendor/drx-parameters/tool-registry.descriptor.js +38 -0
  309. package/resolve-advanced/vendor/drx-parameters/tools/drx-analyzer.js +371 -0
  310. package/resolve-advanced/vendor/fairlight/index.js +833 -0
  311. package/resolve-advanced/vendor/fusion-codec/composition-generator.js +401 -0
  312. package/resolve-advanced/vendor/fusion-codec/templates/blur-region.js +103 -0
  313. package/resolve-advanced/vendor/fusion-codec/templates/color-correct.js +87 -0
  314. package/resolve-advanced/vendor/fusion-codec/templates/film-grain.js +106 -0
  315. package/resolve-advanced/vendor/fusion-codec/templates/lower-third.js +241 -0
  316. package/resolve-advanced/vendor/fusion-codec/templates/picture-in-picture.js +188 -0
  317. package/resolve-advanced/vendor/fusion-codec/templates/text-overlay.js +161 -0
  318. package/resolve-advanced/vendor/fusion-codec/templates/title-card.js +184 -0
  319. package/resolve-advanced/vendor/fusion-codec/templates/vignette.js +107 -0
  320. package/resolve-advanced/vendor/fusion-codec/templates/watermark.js +101 -0
  321. package/scripts/agent-rules/README.md +68 -0
  322. package/src/analysis_dashboard.py +233 -1
  323. package/src/granular/common.py +1 -1
  324. package/src/server.py +479 -29
  325. package/src/utils/api_truth.py +117 -0
  326. package/src/utils/cut_ir.py +1 -1
  327. package/src/utils/failure_tracker.py +0 -2
  328. package/src/utils/timeline_xml.py +405 -0
@@ -0,0 +1,763 @@
1
+ /**
2
+ * DaVinci Resolve Curves Encoder
3
+ *
4
+ * Advanced curve encoding for color grading including:
5
+ * - RGB channel curves
6
+ * - Hue vs Hue/Sat/Lum curves
7
+ * - Luminance vs Saturation curves
8
+ * - Saturation vs Saturation/Lum curves
9
+ * - Bezier and linear interpolation
10
+ * - S-curve and lift/gamma/gain presets
11
+ *
12
+ * Works with node-tree-encoder.js for complete grade encoding.
13
+ *
14
+ * @module curves-encoder
15
+ */
16
+
17
+ const { encodeVarint, encodeFloat, encodeTag } = require('./grade-encoder');
18
+ const { CURVE_TYPES } = require('./grade-parameter-decoder');
19
+
20
+ // ═══════════════════════════════════════════════════════════════════════════
21
+ // CURVE POINT GENERATION
22
+ // ═══════════════════════════════════════════════════════════════════════════
23
+
24
+ /**
25
+ * Default bezier handle length relative to adjacent point distance
26
+ */
27
+ const DEFAULT_HANDLE_LENGTH = 0.33;
28
+
29
+ /**
30
+ * Create curve points from simple x,y coordinates with automatic bezier handles
31
+ *
32
+ * @param {Array} xyPoints - Array of [x, y] coordinate pairs
33
+ * @param {Object} options - Handle generation options
34
+ * @param {number} options.tension - Curve tension (0 = sharp, 1 = smooth)
35
+ * @returns {Array} Array of complete point objects with handles
36
+ */
37
+ function createBezierPoints(xyPoints, options = {}) {
38
+ const { tension = 0.5 } = options;
39
+ const points = [];
40
+
41
+ for (let i = 0; i < xyPoints.length; i++) {
42
+ const [x, y] = xyPoints[i];
43
+ const prev = xyPoints[i - 1];
44
+ const next = xyPoints[i + 1];
45
+
46
+ // Calculate handle directions based on adjacent points
47
+ let handleInX = x;
48
+ let handleInY = y;
49
+ let handleOutX = x;
50
+ let handleOutY = y;
51
+
52
+ if (prev && next) {
53
+ // Interior point - smooth bezier
54
+ const dx = next[0] - prev[0];
55
+ const dy = next[1] - prev[1];
56
+ const length = Math.sqrt(dx * dx + dy * dy) * DEFAULT_HANDLE_LENGTH * tension;
57
+
58
+ const angle = Math.atan2(dy, dx);
59
+ handleInX = x - Math.cos(angle) * length;
60
+ handleInY = y - Math.sin(angle) * length;
61
+ handleOutX = x + Math.cos(angle) * length;
62
+ handleOutY = y + Math.sin(angle) * length;
63
+ } else if (prev) {
64
+ // End point
65
+ const dx = x - prev[0];
66
+ const dy = y - prev[1];
67
+ const length = Math.sqrt(dx * dx + dy * dy) * DEFAULT_HANDLE_LENGTH * tension;
68
+ handleInX = x - (dx / Math.sqrt(dx * dx + dy * dy || 1)) * length;
69
+ handleInY = y - (dy / Math.sqrt(dx * dx + dy * dy || 1)) * length;
70
+ } else if (next) {
71
+ // Start point
72
+ const dx = next[0] - x;
73
+ const dy = next[1] - y;
74
+ const length = Math.sqrt(dx * dx + dy * dy) * DEFAULT_HANDLE_LENGTH * tension;
75
+ handleOutX = x + (dx / Math.sqrt(dx * dx + dy * dy || 1)) * length;
76
+ handleOutY = y + (dy / Math.sqrt(dx * dx + dy * dy || 1)) * length;
77
+ }
78
+
79
+ points.push({
80
+ x,
81
+ y,
82
+ handleInX,
83
+ handleInY,
84
+ handleOutX,
85
+ handleOutY,
86
+ });
87
+ }
88
+
89
+ return points;
90
+ }
91
+
92
+ /**
93
+ * Create linear interpolation points (no bezier handles)
94
+ *
95
+ * @param {Array} xyPoints - Array of [x, y] coordinate pairs
96
+ * @returns {Array} Array of point objects
97
+ */
98
+ function createLinearPoints(xyPoints) {
99
+ return xyPoints.map(([x, y]) => ({
100
+ x,
101
+ y,
102
+ handleInX: x,
103
+ handleInY: y,
104
+ handleOutX: x,
105
+ handleOutY: y,
106
+ }));
107
+ }
108
+
109
+ // ═══════════════════════════════════════════════════════════════════════════
110
+ // PRESET CURVE GENERATORS
111
+ // ═══════════════════════════════════════════════════════════════════════════
112
+
113
+ /**
114
+ * Create an S-curve for contrast enhancement
115
+ *
116
+ * @param {number} strength - Curve strength (0-1, default 0.3)
117
+ * @param {number} pivot - Pivot point (0-1, default 0.5)
118
+ * @returns {Array} Curve points
119
+ */
120
+ function createSCurve(strength = 0.3, pivot = 0.5) {
121
+ // S-curve with customizable strength and pivot
122
+ const shadowLift = strength * 0.5;
123
+ const highlightPush = strength * 0.5;
124
+
125
+ const points = [
126
+ [0, shadowLift * 0.3], // Lift shadows slightly
127
+ [pivot * 0.5, pivot * 0.5 - shadowLift], // Shadow control point
128
+ [pivot, pivot], // Pivot stays fixed
129
+ [pivot + (1 - pivot) * 0.5, pivot + (1 - pivot) * 0.5 + highlightPush], // Highlight control
130
+ [1, 1 - highlightPush * 0.3], // Pull highlights slightly
131
+ ];
132
+
133
+ return createBezierPoints(points, { tension: 0.6 });
134
+ }
135
+
136
+ /**
137
+ * Create a lift curve (affects shadows)
138
+ *
139
+ * @param {number} amount - Lift amount (-1 to 1)
140
+ * @returns {Array} Curve points
141
+ */
142
+ function createLiftCurve(amount = 0) {
143
+ const liftValue = Math.max(0, Math.min(1, amount + 0));
144
+ const points = [
145
+ [0, liftValue], // Black point lifted
146
+ [0.25, 0.25 + amount * 0.5], // Quarter tone
147
+ [1, 1], // White point unchanged
148
+ ];
149
+
150
+ return createBezierPoints(points, { tension: 0.4 });
151
+ }
152
+
153
+ /**
154
+ * Create a gamma curve (affects midtones)
155
+ *
156
+ * @param {number} amount - Gamma adjustment (0.1 to 4, 1 = neutral)
157
+ * @returns {Array} Curve points
158
+ */
159
+ function createGammaCurve(amount = 1) {
160
+ // Generate gamma curve points
161
+ const points = [];
162
+ const numPoints = 5;
163
+
164
+ for (let i = 0; i <= numPoints; i++) {
165
+ const x = i / numPoints;
166
+ const y = Math.pow(x, 1 / amount);
167
+ points.push([x, Math.max(0, Math.min(1, y))]);
168
+ }
169
+
170
+ return createBezierPoints(points, { tension: 0.3 });
171
+ }
172
+
173
+ /**
174
+ * Create a gain curve (affects highlights)
175
+ *
176
+ * @param {number} amount - Gain multiplier (0 to 2, 1 = neutral)
177
+ * @returns {Array} Curve points
178
+ */
179
+ function createGainCurve(amount = 1) {
180
+ const points = [
181
+ [0, 0], // Black point unchanged
182
+ [0.75, 0.75 * amount], // Three-quarter tone
183
+ [1, Math.min(1, amount)], // White point scaled
184
+ ];
185
+
186
+ return createBezierPoints(points, { tension: 0.4 });
187
+ }
188
+
189
+ /**
190
+ * Create a clipping curve for crushing blacks or whites
191
+ *
192
+ * @param {Object} options - Clipping options
193
+ * @param {number} options.blackClip - Black clipping point (0-0.5)
194
+ * @param {number} options.whiteClip - White clipping point (0.5-1)
195
+ * @returns {Array} Curve points
196
+ */
197
+ function createClippingCurve(options = {}) {
198
+ const { blackClip = 0, whiteClip = 1 } = options;
199
+
200
+ const points = [
201
+ [0, 0],
202
+ [blackClip, 0], // Crush blacks
203
+ [blackClip + 0.1, 0.1], // Transition
204
+ [whiteClip - 0.1, 0.9], // Transition
205
+ [whiteClip, 1], // Clip whites
206
+ [1, 1],
207
+ ];
208
+
209
+ return createLinearPoints(points);
210
+ }
211
+
212
+ /**
213
+ * Create a cross-process style curve for color channel
214
+ *
215
+ * @param {string} channel - 'red', 'green', or 'blue'
216
+ * @param {number} strength - Effect strength (0-1)
217
+ * @returns {Array} Curve points
218
+ */
219
+ function createCrossProcessCurve(channel, strength = 0.5) {
220
+ let points;
221
+
222
+ switch (channel.toLowerCase()) {
223
+ case 'red':
224
+ // Boost shadows, compress highlights
225
+ points = [
226
+ [0, 0.1 * strength],
227
+ [0.25, 0.35],
228
+ [0.5, 0.5],
229
+ [0.75, 0.7 - 0.05 * strength],
230
+ [1, 0.95],
231
+ ];
232
+ break;
233
+
234
+ case 'green':
235
+ // S-curve for contrast
236
+ points = [
237
+ [0, 0.05 * strength],
238
+ [0.25, 0.2],
239
+ [0.5, 0.5],
240
+ [0.75, 0.8],
241
+ [1, 1 - 0.05 * strength],
242
+ ];
243
+ break;
244
+
245
+ case 'blue':
246
+ // Lift shadows significantly, compress highlights
247
+ points = [
248
+ [0, 0.15 * strength],
249
+ [0.25, 0.3 + 0.05 * strength],
250
+ [0.5, 0.55],
251
+ [0.75, 0.75],
252
+ [1, 0.9],
253
+ ];
254
+ break;
255
+
256
+ default:
257
+ points = [
258
+ [0, 0],
259
+ [1, 1],
260
+ ];
261
+ }
262
+
263
+ return createBezierPoints(points, { tension: 0.5 });
264
+ }
265
+
266
+ // ═══════════════════════════════════════════════════════════════════════════
267
+ // HUE CURVE GENERATORS
268
+ // ═══════════════════════════════════════════════════════════════════════════
269
+
270
+ /**
271
+ * Hue color reference values (in degrees)
272
+ */
273
+ const HUE_COLORS = {
274
+ RED: 0,
275
+ ORANGE: 30,
276
+ YELLOW: 60,
277
+ YELLOW_GREEN: 90,
278
+ GREEN: 120,
279
+ CYAN: 180,
280
+ BLUE: 240,
281
+ PURPLE: 270,
282
+ MAGENTA: 300,
283
+ PINK: 330,
284
+ };
285
+
286
+ /**
287
+ * Create a Hue vs Hue shift curve
288
+ *
289
+ * @param {Array} shifts - Array of {hue, shift} objects
290
+ * @param {number} shifts[].hue - Source hue (0-360)
291
+ * @param {number} shifts[].shift - Hue shift amount (-180 to 180)
292
+ * @param {number} shifts[].width - Affected range width
293
+ * @returns {Object} Complete curve definition
294
+ */
295
+ function createHueVsHueCurve(shifts) {
296
+ const points = [];
297
+
298
+ // Start and end at neutral (no shift)
299
+ points.push([0, 0.5]); // Normalized: 0.5 = no shift
300
+
301
+ for (const { hue, shift, width = 30 } of shifts) {
302
+ const normalizedHue = hue / 360;
303
+ const normalizedShift = 0.5 + shift / 360;
304
+
305
+ // Add transition points
306
+ const widthNorm = width / 360;
307
+ const startHue = (normalizedHue - widthNorm + 1) % 1;
308
+ const endHue = (normalizedHue + widthNorm) % 1;
309
+
310
+ if (startHue < normalizedHue) {
311
+ points.push([startHue, 0.5]);
312
+ }
313
+ points.push([normalizedHue, normalizedShift]);
314
+ if (endHue > normalizedHue) {
315
+ points.push([endHue, 0.5]);
316
+ }
317
+ }
318
+
319
+ points.push([1, 0.5]);
320
+
321
+ // Sort by x and remove duplicates
322
+ const sortedPoints = points
323
+ .sort((a, b) => a[0] - b[0])
324
+ .filter((p, i, arr) => i === 0 || p[0] !== arr[i - 1][0]);
325
+
326
+ return {
327
+ type: 'HUE_VS_HUE',
328
+ enabled: true,
329
+ points: createBezierPoints(sortedPoints, { tension: 0.3 }),
330
+ interpolation: 'bezier',
331
+ };
332
+ }
333
+
334
+ /**
335
+ * Create a Hue vs Saturation curve
336
+ *
337
+ * @param {Array} adjustments - Array of {hue, saturation} objects
338
+ * @param {number} adjustments[].hue - Target hue (0-360)
339
+ * @param {number} adjustments[].saturation - Saturation multiplier (0-2, 1 = neutral)
340
+ * @param {number} adjustments[].width - Affected range width
341
+ * @returns {Object} Complete curve definition
342
+ */
343
+ function createHueVsSatCurve(adjustments) {
344
+ const points = [];
345
+
346
+ // Neutral baseline
347
+ points.push([0, 0.5]); // 0.5 = 1x saturation (neutral)
348
+
349
+ for (const { hue, saturation, width = 30 } of adjustments) {
350
+ const normalizedHue = hue / 360;
351
+ const normalizedSat = saturation / 2; // 0-1 range for 0-2x
352
+
353
+ // Add transition points
354
+ const widthNorm = width / 360;
355
+
356
+ points.push([(normalizedHue - widthNorm + 1) % 1, 0.5]);
357
+ points.push([normalizedHue, normalizedSat]);
358
+ points.push([(normalizedHue + widthNorm) % 1, 0.5]);
359
+ }
360
+
361
+ points.push([1, 0.5]);
362
+
363
+ const sortedPoints = points
364
+ .sort((a, b) => a[0] - b[0])
365
+ .filter((p, i, arr) => i === 0 || p[0] !== arr[i - 1][0]);
366
+
367
+ return {
368
+ type: 'HUE_VS_SAT',
369
+ enabled: true,
370
+ points: createBezierPoints(sortedPoints, { tension: 0.4 }),
371
+ interpolation: 'bezier',
372
+ };
373
+ }
374
+
375
+ /**
376
+ * Create a Hue vs Luminance curve
377
+ *
378
+ * @param {Array} adjustments - Array of {hue, luminance} objects
379
+ * @param {number} adjustments[].hue - Target hue (0-360)
380
+ * @param {number} adjustments[].luminance - Luminance adjustment (-1 to 1, 0 = neutral)
381
+ * @param {number} adjustments[].width - Affected range width
382
+ * @returns {Object} Complete curve definition
383
+ */
384
+ function createHueVsLumCurve(adjustments) {
385
+ const points = [];
386
+
387
+ points.push([0, 0.5]); // Neutral
388
+
389
+ for (const { hue, luminance, width = 30 } of adjustments) {
390
+ const normalizedHue = hue / 360;
391
+ const normalizedLum = 0.5 + luminance / 2;
392
+
393
+ const widthNorm = width / 360;
394
+
395
+ points.push([(normalizedHue - widthNorm + 1) % 1, 0.5]);
396
+ points.push([normalizedHue, normalizedLum]);
397
+ points.push([(normalizedHue + widthNorm) % 1, 0.5]);
398
+ }
399
+
400
+ points.push([1, 0.5]);
401
+
402
+ const sortedPoints = points
403
+ .sort((a, b) => a[0] - b[0])
404
+ .filter((p, i, arr) => i === 0 || p[0] !== arr[i - 1][0]);
405
+
406
+ return {
407
+ type: 'HUE_VS_LUM',
408
+ enabled: true,
409
+ points: createBezierPoints(sortedPoints, { tension: 0.4 }),
410
+ interpolation: 'bezier',
411
+ };
412
+ }
413
+
414
+ // ═══════════════════════════════════════════════════════════════════════════
415
+ // LUMINANCE/SATURATION CURVE GENERATORS
416
+ // ═══════════════════════════════════════════════════════════════════════════
417
+
418
+ /**
419
+ * Create a Luminance vs Saturation curve
420
+ *
421
+ * @param {Object} options - Curve options
422
+ * @param {number} options.shadowSat - Shadow saturation (0-2, 1 = neutral)
423
+ * @param {number} options.midtoneSat - Midtone saturation (0-2, 1 = neutral)
424
+ * @param {number} options.highlightSat - Highlight saturation (0-2, 1 = neutral)
425
+ * @returns {Object} Complete curve definition
426
+ */
427
+ function createLumVsSatCurve(options = {}) {
428
+ const { shadowSat = 1, midtoneSat = 1, highlightSat = 1 } = options;
429
+
430
+ const points = [
431
+ [0, shadowSat / 2],
432
+ [0.25, (shadowSat + midtoneSat) / 4],
433
+ [0.5, midtoneSat / 2],
434
+ [0.75, (midtoneSat + highlightSat) / 4],
435
+ [1, highlightSat / 2],
436
+ ];
437
+
438
+ return {
439
+ type: 'LUM_VS_SAT',
440
+ enabled: true,
441
+ points: createBezierPoints(points, { tension: 0.5 }),
442
+ interpolation: 'bezier',
443
+ };
444
+ }
445
+
446
+ /**
447
+ * Create a Saturation vs Saturation curve (affects saturated vs unsaturated areas)
448
+ *
449
+ * @param {Object} options - Curve options
450
+ * @param {number} options.lowSatBoost - Boost for low saturation areas
451
+ * @param {number} options.highSatCompress - Compression for high saturation
452
+ * @returns {Object} Complete curve definition
453
+ */
454
+ function createSatVsSatCurve(options = {}) {
455
+ const { lowSatBoost = 0, highSatCompress = 0 } = options;
456
+
457
+ const points = [
458
+ [0, 0],
459
+ [0.25, 0.25 + lowSatBoost * 0.1],
460
+ [0.5, 0.5],
461
+ [0.75, 0.75 - highSatCompress * 0.05],
462
+ [1, 1 - highSatCompress * 0.1],
463
+ ];
464
+
465
+ return {
466
+ type: 'SAT_VS_SAT',
467
+ enabled: true,
468
+ points: createBezierPoints(points, { tension: 0.4 }),
469
+ interpolation: 'bezier',
470
+ };
471
+ }
472
+
473
+ /**
474
+ * Create a Saturation vs Luminance curve
475
+ *
476
+ * @param {Object} options - Curve options
477
+ * @param {number} options.lowSatLum - Luminance adjustment for low saturation
478
+ * @param {number} options.highSatLum - Luminance adjustment for high saturation
479
+ * @returns {Object} Complete curve definition
480
+ */
481
+ function createSatVsLumCurve(options = {}) {
482
+ const { lowSatLum = 0, highSatLum = 0 } = options;
483
+
484
+ const points = [
485
+ [0, 0.5 + lowSatLum / 2],
486
+ [0.5, 0.5],
487
+ [1, 0.5 + highSatLum / 2],
488
+ ];
489
+
490
+ return {
491
+ type: 'SAT_VS_LUM',
492
+ enabled: true,
493
+ points: createBezierPoints(points, { tension: 0.5 }),
494
+ interpolation: 'bezier',
495
+ };
496
+ }
497
+
498
+ // ═══════════════════════════════════════════════════════════════════════════
499
+ // FILM EMULATION PRESETS
500
+ // ═══════════════════════════════════════════════════════════════════════════
501
+
502
+ /**
503
+ * Create curves that emulate classic film stocks
504
+ *
505
+ * @param {string} filmStock - Film stock name
506
+ * @returns {Object} Object containing R, G, B, and Lum curves
507
+ */
508
+ function createFilmEmulationCurves(filmStock) {
509
+ switch (filmStock.toLowerCase()) {
510
+ case 'kodak_portra':
511
+ return {
512
+ lum: {
513
+ type: 'CUSTOM',
514
+ enabled: true,
515
+ points: createBezierPoints([
516
+ [0, 0.02],
517
+ [0.25, 0.27],
518
+ [0.5, 0.52],
519
+ [0.75, 0.78],
520
+ [1, 0.98],
521
+ ]),
522
+ interpolation: 'bezier',
523
+ },
524
+ red: {
525
+ type: 'RED',
526
+ enabled: true,
527
+ points: createBezierPoints([
528
+ [0, 0.03],
529
+ [0.25, 0.28],
530
+ [0.5, 0.52],
531
+ [0.75, 0.76],
532
+ [1, 0.97],
533
+ ]),
534
+ interpolation: 'bezier',
535
+ },
536
+ green: {
537
+ type: 'GREEN',
538
+ enabled: true,
539
+ points: createBezierPoints([
540
+ [0, 0.02],
541
+ [0.25, 0.26],
542
+ [0.5, 0.51],
543
+ [0.75, 0.77],
544
+ [1, 0.98],
545
+ ]),
546
+ interpolation: 'bezier',
547
+ },
548
+ blue: {
549
+ type: 'BLUE',
550
+ enabled: true,
551
+ points: createBezierPoints([
552
+ [0, 0.05],
553
+ [0.25, 0.29],
554
+ [0.5, 0.53],
555
+ [0.75, 0.78],
556
+ [1, 0.96],
557
+ ]),
558
+ interpolation: 'bezier',
559
+ },
560
+ };
561
+
562
+ case 'fuji_velvia':
563
+ return {
564
+ lum: {
565
+ type: 'CUSTOM',
566
+ enabled: true,
567
+ points: createSCurve(0.4, 0.5),
568
+ interpolation: 'bezier',
569
+ },
570
+ red: {
571
+ type: 'RED',
572
+ enabled: true,
573
+ points: createBezierPoints([
574
+ [0, 0],
575
+ [0.2, 0.18],
576
+ [0.5, 0.55],
577
+ [0.8, 0.85],
578
+ [1, 1],
579
+ ]),
580
+ interpolation: 'bezier',
581
+ },
582
+ green: {
583
+ type: 'GREEN',
584
+ enabled: true,
585
+ points: createBezierPoints([
586
+ [0, 0],
587
+ [0.2, 0.22],
588
+ [0.5, 0.52],
589
+ [0.8, 0.82],
590
+ [1, 1],
591
+ ]),
592
+ interpolation: 'bezier',
593
+ },
594
+ blue: {
595
+ type: 'BLUE',
596
+ enabled: true,
597
+ points: createBezierPoints([
598
+ [0, 0.02],
599
+ [0.2, 0.24],
600
+ [0.5, 0.54],
601
+ [0.8, 0.84],
602
+ [1, 1],
603
+ ]),
604
+ interpolation: 'bezier',
605
+ },
606
+ };
607
+
608
+ case 'cinestill_800t':
609
+ return {
610
+ lum: {
611
+ type: 'CUSTOM',
612
+ enabled: true,
613
+ points: createBezierPoints([
614
+ [0, 0.05],
615
+ [0.3, 0.32],
616
+ [0.5, 0.52],
617
+ [0.7, 0.72],
618
+ [1, 0.95],
619
+ ]),
620
+ interpolation: 'bezier',
621
+ },
622
+ red: {
623
+ type: 'RED',
624
+ enabled: true,
625
+ points: createBezierPoints([
626
+ [0, 0.02],
627
+ [0.3, 0.28],
628
+ [0.5, 0.48],
629
+ [0.7, 0.7],
630
+ [1, 0.95],
631
+ ]),
632
+ interpolation: 'bezier',
633
+ },
634
+ green: {
635
+ type: 'GREEN',
636
+ enabled: true,
637
+ points: createBezierPoints([
638
+ [0, 0.04],
639
+ [0.3, 0.32],
640
+ [0.5, 0.52],
641
+ [0.7, 0.72],
642
+ [1, 0.96],
643
+ ]),
644
+ interpolation: 'bezier',
645
+ },
646
+ blue: {
647
+ type: 'BLUE',
648
+ enabled: true,
649
+ points: createBezierPoints([
650
+ [0, 0.08],
651
+ [0.3, 0.36],
652
+ [0.5, 0.56],
653
+ [0.7, 0.74],
654
+ [1, 0.94],
655
+ ]),
656
+ interpolation: 'bezier',
657
+ },
658
+ };
659
+
660
+ default:
661
+ // Neutral curves
662
+ return {
663
+ lum: {
664
+ type: 'CUSTOM',
665
+ enabled: true,
666
+ points: createLinearPoints([
667
+ [0, 0],
668
+ [1, 1],
669
+ ]),
670
+ interpolation: 'linear',
671
+ },
672
+ red: { type: 'RED', enabled: false, points: [], interpolation: 'linear' },
673
+ green: { type: 'GREEN', enabled: false, points: [], interpolation: 'linear' },
674
+ blue: { type: 'BLUE', enabled: false, points: [], interpolation: 'linear' },
675
+ };
676
+ }
677
+ }
678
+
679
+ // ═══════════════════════════════════════════════════════════════════════════
680
+ // CURVE ENCODING HELPERS
681
+ // ═══════════════════════════════════════════════════════════════════════════
682
+
683
+ /**
684
+ * Encode a complete curve set for a corrector
685
+ *
686
+ * @param {Object} curveSet - Object with multiple curves
687
+ * @returns {Array} Array of curve objects ready for node-tree-encoder
688
+ */
689
+ function encodeCurveSet(curveSet) {
690
+ const curves = [];
691
+
692
+ if (curveSet.lum) curves.push(curveSet.lum);
693
+ if (curveSet.red) curves.push(curveSet.red);
694
+ if (curveSet.green) curves.push(curveSet.green);
695
+ if (curveSet.blue) curves.push(curveSet.blue);
696
+ if (curveSet.hueVsHue) curves.push(curveSet.hueVsHue);
697
+ if (curveSet.hueVsSat) curves.push(curveSet.hueVsSat);
698
+ if (curveSet.hueVsLum) curves.push(curveSet.hueVsLum);
699
+ if (curveSet.lumVsSat) curves.push(curveSet.lumVsSat);
700
+ if (curveSet.satVsSat) curves.push(curveSet.satVsSat);
701
+ if (curveSet.satVsLum) curves.push(curveSet.satVsLum);
702
+
703
+ return curves;
704
+ }
705
+
706
+ /**
707
+ * Create a corrector node with curves
708
+ *
709
+ * @param {Object|Array} curves - Curve set or array of curves
710
+ * @returns {Object} Corrector object ready for encoding
711
+ */
712
+ function createCurvesCorrector(curves) {
713
+ const { CORRECTOR_TYPE } = require('./grade-parameter-decoder');
714
+
715
+ const curveArray = Array.isArray(curves) ? curves : encodeCurveSet(curves);
716
+
717
+ return {
718
+ typeId: CORRECTOR_TYPE.CURVES,
719
+ enabled: true,
720
+ values: {
721
+ curves: curveArray,
722
+ },
723
+ };
724
+ }
725
+
726
+ // ═══════════════════════════════════════════════════════════════════════════
727
+ // EXPORTS
728
+ // ═══════════════════════════════════════════════════════════════════════════
729
+
730
+ module.exports = {
731
+ // Point generation
732
+ createBezierPoints,
733
+ createLinearPoints,
734
+
735
+ // Preset curves
736
+ createSCurve,
737
+ createLiftCurve,
738
+ createGammaCurve,
739
+ createGainCurve,
740
+ createClippingCurve,
741
+ createCrossProcessCurve,
742
+
743
+ // Hue curves
744
+ createHueVsHueCurve,
745
+ createHueVsSatCurve,
746
+ createHueVsLumCurve,
747
+
748
+ // Lum/Sat curves
749
+ createLumVsSatCurve,
750
+ createSatVsSatCurve,
751
+ createSatVsLumCurve,
752
+
753
+ // Film emulation
754
+ createFilmEmulationCurves,
755
+
756
+ // Encoding helpers
757
+ encodeCurveSet,
758
+ createCurvesCorrector,
759
+
760
+ // Constants
761
+ HUE_COLORS,
762
+ DEFAULT_HANDLE_LENGTH,
763
+ };