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,1292 @@
1
+ /**
2
+ * DRX Parameter ID Definitions
3
+ *
4
+ * Complete mapping of parameter IDs used in DaVinci Resolve's DRX format.
5
+ * Includes all known parameters from parser, generator, and analyzer tools.
6
+ *
7
+ * Parameter ID Ranges:
8
+ * - 0x06xxxxxx (100663296+): Primary corrector params
9
+ * - 0x083xxxxx (137363456+): Contrast corrector params
10
+ * - 0x085xxxxx (139460608+): Hue corrector params
11
+ * - 0x08D0xxxx (147849216+): Luma vs Saturation params
12
+ * - 0x08F0xxxx (149946368+): Saturation vs Saturation params
13
+ * - 0x0C3xxxxx (204472320+): Curves/HDR zone params
14
+ * - Negative IDs (0x860xxxxx): Temperature, Tint, Log wheels
15
+ *
16
+ * @module drx-parameters/parameter-ids
17
+ */
18
+
19
+ // ============================================================================
20
+ // PRIMARY CORRECTOR (Type 1) - Color Wheels
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Lift (Shadows) - 4 parameters
25
+ * Range: -1.0 to +1.0, Default: 0.0
26
+ */
27
+ const LIFT = {
28
+ R: 100663320, // 0x6000018
29
+ G: 100663321, // 0x6000019
30
+ B: 100663322, // 0x600001a
31
+ MASTER: 100663323, // 0x600001b
32
+ };
33
+
34
+ /**
35
+ * Gain (Highlights) - 4 parameters
36
+ * Range: 0.0 to 4.0, Default: 1.0
37
+ */
38
+ const GAIN = {
39
+ R: 100663325, // 0x600001d
40
+ G: 100663326, // 0x600001e
41
+ B: 100663327, // 0x600001f
42
+ MASTER: 100663328, // 0x6000020
43
+ };
44
+
45
+ /**
46
+ * Gamma (Midtones) - 4 parameters
47
+ * Range: -1.0 to +1.0, Default: 0.0
48
+ */
49
+ const GAMMA = {
50
+ R: 100663330, // 0x6000022
51
+ G: 100663331, // 0x6000023
52
+ B: 100663332, // 0x6000024
53
+ MASTER: 100663333, // 0x6000025
54
+ };
55
+
56
+ /**
57
+ * Offset - 3 parameters (no master)
58
+ * Range: -1.0 to +1.0, Default: 0.0
59
+ */
60
+ const OFFSET = {
61
+ R: 100663421, // 0x600007d
62
+ G: 100663422, // 0x600007e
63
+ B: 100663423, // 0x600007f
64
+ };
65
+
66
+ /**
67
+ * Saturation - Primary corrector saturation
68
+ * Range: 0.0 to 4.0, Default: 1.0
69
+ */
70
+ const SATURATION = {
71
+ PRIMARY: 100663301, // 0x6000005 - Main saturation
72
+ LEGACY: 100663300, // 0x6000004 - Legacy/alt ID (may also be Hue Rotate — needs confirmation)
73
+ };
74
+
75
+ // ============================================================================
76
+ // RGB MIXER (Primary Corrector, Type 1)
77
+ // ============================================================================
78
+
79
+ /**
80
+ * RGB Mixer - 3x3 color channel mixing matrix
81
+ * Encoded as 9 float params in the Primary corrector (0x860000a7–0x860000af)
82
+ *
83
+ * Matrix layout (row = output channel, column = input channel):
84
+ * R_out = RR*R + GR*G + BR*B
85
+ * G_out = RG*R + GG*G + BG*B
86
+ * B_out = RB*R + GB*G + BB*B
87
+ *
88
+ * Default (identity): diagonal = 1.0, off-diagonal = 0.0
89
+ * Range: 0.0 to 2.0 per cell (typical)
90
+ *
91
+ * TRAINED 2026-03-17 from rgbmixer_1.1.2.drx:
92
+ * 0.8 diagonal + 0.1 off-diagonal → desaturated cross-channel blend
93
+ */
94
+ const RGB_MIXER = {
95
+ RR: 2248147111, // 0x860000a7 - Red → Red output
96
+ GR: 2248147112, // 0x860000a8 - Green → Red output
97
+ BR: 2248147113, // 0x860000a9 - Blue → Red output
98
+ RG: 2248147114, // 0x860000aa - Red → Green output
99
+ GG: 2248147115, // 0x860000ab - Green → Green output
100
+ BG: 2248147116, // 0x860000ac - Blue → Green output
101
+ RB: 2248147117, // 0x860000ad - Red → Blue output
102
+ GB: 2248147118, // 0x860000ae - Green → Blue output
103
+ BB: 2248147119, // 0x860000af - Blue → Blue output
104
+
105
+ // Toggle
106
+ PRESERVE_LUMINANCE: 2248147132, // 0x860000bc - Preserve Luminance (0=off, nested {F2:0})
107
+ };
108
+
109
+ // ============================================================================
110
+ // CUSTOM CURVES - YRGB (Primary Corrector, Type 1)
111
+ // ============================================================================
112
+
113
+ /**
114
+ * Custom Curves (YRGB) - Bézier/spline curve adjustment
115
+ *
116
+ * Two param groups per channel:
117
+ * 1. Metadata params (0x860000bb–0x860000bf): nested {F2: pointCount} — number of control points
118
+ * 2. Spline data params (0x86000506–0x86000509): nested {F8: {F1[]: point data}} — actual curve points
119
+ *
120
+ * Spline point encoding: each F1 entry contains F1 (x, fixed32) and F5 (y, fixed32)
121
+ * x,y range: 0.0 to 1.0 (normalized), with endpoints at (0,0) and (1,1) for identity
122
+ *
123
+ * TRAINED 2026-03-17 from curves_yrgb_splines_1.1.2.drx and curve_y_scurve_1.1.2.drx
124
+ */
125
+ const CUSTOM_CURVES = {
126
+ // Metadata (control point count per channel)
127
+ Y_META: 2248147131, // 0x860000bb - Y (luma) curve point count
128
+ // 0x860000bc is RGB Mixer Preserve Luminance (see above)
129
+ R_META: 2248147133, // 0x860000bd - Red curve point count
130
+ G_META: 2248147134, // 0x860000be - Green curve point count
131
+ B_META: 2248147135, // 0x860000bf - Blue curve point count
132
+
133
+ // Spline data (actual curve points as nested protobuf)
134
+ Y_SPLINE: 2248148230, // 0x86000506 - Y (luma) curve spline data
135
+ R_SPLINE: 2248148231, // 0x86000507 - Red curve spline data
136
+ G_SPLINE: 2248148232, // 0x86000508 - Green curve spline data
137
+ B_SPLINE: 2248148233, // 0x86000509 - Blue curve spline data
138
+ };
139
+
140
+ // ============================================================================
141
+ // HSL CURVES (Primary Corrector, Type 1)
142
+ // ============================================================================
143
+
144
+ /**
145
+ * HSL Curves — Hue/Saturation/Luminance vs Hue/Saturation/Luminance curves
146
+ *
147
+ * Each curve type has:
148
+ * 1. A metadata param (varies per type) — nested {F2: value}
149
+ * 2. A common metadata flag (0x860000cf) — nested {F2: 2} (always 2 when any HSL curve active)
150
+ * 3. A spline data param (0x86000400–0x86000405) — nested {F8: point data}
151
+ *
152
+ * TRAINED 2026-03-17 from hue_vs_hue, hue_vs_sat, hue_vs_lum, lum_vs_sat, sat_vs_sat, sat_vs_lum
153
+ */
154
+ const HSL_CURVES = {
155
+ // Common metadata flag (present whenever any HSL curve is active)
156
+ COMMON_FLAG: 2248147151, // 0x860000cf - {F2: 2}
157
+
158
+ // Per-curve metadata params
159
+ HUE_VS_HUE_META: 2248147127, // 0x860000b7 - Hue vs Hue metadata
160
+ HUE_VS_SAT_META: 2248147128, // 0x860000b8 - Hue vs Saturation metadata
161
+ HUE_VS_LUM_META: 2248147129, // 0x860000b9 - Hue vs Luminance metadata
162
+ LUM_VS_SAT_META: 2248147130, // 0x860000ba - Luminance vs Saturation metadata
163
+ SAT_VS_SAT_META: 2248147203, // 0x86000103 - Saturation vs Saturation metadata
164
+ SAT_VS_LUM_META: 2248147458, // 0x86000202 - Saturation vs Luminance metadata
165
+
166
+ // Additional metadata for Hue vs Lum
167
+ HUE_VS_LUM_EXTRA: 2248147224, // 0x86000118 - Extra metadata for Hue vs Lum
168
+
169
+ // Spline data params (actual curve points)
170
+ HUE_VS_HUE_SPLINE: 2248147968, // 0x86000400
171
+ HUE_VS_SAT_SPLINE: 2248147969, // 0x86000401
172
+ HUE_VS_LUM_SPLINE: 2248147970, // 0x86000402
173
+ LUM_VS_SAT_SPLINE: 2248147971, // 0x86000403
174
+ SAT_VS_SAT_SPLINE: 2248147972, // 0x86000404
175
+ SAT_VS_LUM_SPLINE: 2248147973, // 0x86000405
176
+ };
177
+
178
+ // ============================================================================
179
+ // ADDITIONAL PRIMARY CONTROLS
180
+ // ============================================================================
181
+
182
+ /**
183
+ * Additional controls discovered from training samples
184
+ *
185
+ * TRAINED 2026-03-17 from highlights_50, shadows_50, lummix_50 DRX captures
186
+ */
187
+ const ADDITIONAL = {
188
+ LUM_MIX_SLIDER: 2248146955, // 0x8600000b - Luminosity Mix (UI 0-100 → stored /100, default 100→1.0). CORRECTED 2026-06-22 (harness, §16a): value was 2248147083=0x8600008b — a typo vs its own comment; Lum Mix decoded as unknown_ until live-measured.
189
+ HIGHLIGHTS: 2248147216, // 0x86000110 - Highlights slider (direct value, e.g., 50)
190
+ SHADOWS: 2248147217, // 0x86000111 - Shadows slider (direct value, e.g., 50)
191
+ };
192
+
193
+ // ============================================================================
194
+ // TEMPERATURE & TINT (Negative ID Encoding)
195
+ // ============================================================================
196
+
197
+ /**
198
+ * Temperature, Tint, and related parameters
199
+ * Uses unsigned representation of negative IDs
200
+ *
201
+ * Value scaling (from DRX analysis 2026-01-14):
202
+ * - Temperature: Relative offset -4000 to +4000 (NOT Kelvin, warm/cool shift)
203
+ * - Tint: Direct value (e.g., +50, -50)
204
+ * - Midtone Detail: Direct value (e.g., +50, -50)
205
+ * - Color Boost: Direct value 0-100
206
+ * - Contrast (Log): Normalized float, 1.0 = 100%
207
+ */
208
+ const TEMP_TINT = {
209
+ TEMPERATURE: 2248147221, // 0x86000115 - Relative offset -4000 to +4000
210
+ TINT: 2248147222, // 0x86000116 - Direct value
211
+ MIDTONE_DETAIL: 2248147219, // 0x86000113 - Direct value
212
+ COLOR_BOOST: 2248147218, // 0x86000112 - Range 0-100 (was SATURATION_ALT)
213
+ CONTRAST: 2248147137, // 0x860000c1 - Normalized float, 1.0 = 100% (NEW - from DRX analysis)
214
+ };
215
+
216
+ // ============================================================================
217
+ // CONTRAST / PIVOT / LOG RANGE (Primary Corrector, Type 1)
218
+ // ============================================================================
219
+
220
+ /**
221
+ * Contrast and Pivot — in the shared controls range (0x860000C0-CC)
222
+ * NOT in the 0x0830xxxx range (those are qualifier params, see below)
223
+ *
224
+ * CORRECTED 2026-03-16: The old CONTRAST block (0x0830xxxx) was a misidentification
225
+ * of HSL Qualifier parameters. Real contrast/pivot live in the shared controls range.
226
+ */
227
+ const CONTRAST = {
228
+ CONTRAST: 2248147137, // 0x860000C1 — normalized float, 1.0 = unity
229
+ PIVOT: 2248147136, // 0x860000C0 — direct float, default 0.435
230
+ LOW_RANGE: 2248147147, // 0x860000CB — direct float, default 0.333
231
+ HIGH_RANGE: 2248147148, // 0x860000CC — INVERTED: DRX = 1.0 - UI
232
+ };
233
+
234
+ // ============================================================================
235
+ // LOG WHEELS MODE (Negative ID Encoding)
236
+ // ============================================================================
237
+
238
+ /**
239
+ * Log wheels mode parameters (alternative to Lift/Gamma/Gain)
240
+ * Uses unsigned representation of negative IDs
241
+ *
242
+ * CORRECTED 2026-01-14: Based on DRX sample analysis, the correct mapping is:
243
+ * - Shadow (Low): 0x860000c2-c4 (sequential R, G, B)
244
+ * - Midtone (Mid): 0x860000c5-c7 (sequential R, G, B)
245
+ * - Highlight (High): 0x860000c8-ca (sequential R, G, B)
246
+ */
247
+ const LOG_WHEELS = {
248
+ // Shadow (Low) - 0x860000c2-c4
249
+ SHADOW_R: 2248147138, // 0x860000c2
250
+ SHADOW_G: 2248147139, // 0x860000c3
251
+ SHADOW_B: 2248147140, // 0x860000c4
252
+
253
+ // Midtone (Mid) - 0x860000c5-c7
254
+ MIDTONE_R: 2248147141, // 0x860000c5
255
+ MIDTONE_G: 2248147142, // 0x860000c6
256
+ MIDTONE_B: 2248147143, // 0x860000c7
257
+
258
+ // Highlight (High) - 0x860000c8-ca (NEW - previously unknown)
259
+ HIGHLIGHT_R: 2248147144, // 0x860000c8
260
+ HIGHLIGHT_G: 2248147145, // 0x860000c9
261
+ HIGHLIGHT_B: 2248147146, // 0x860000ca
262
+ };
263
+
264
+ // ============================================================================
265
+ // HUE / SATURATION (Primary Corrector, Type 1)
266
+ // ============================================================================
267
+
268
+ /**
269
+ * Hue Rotate and Saturation — in the primary corrector range (0x06000004-05)
270
+ *
271
+ * NOTE: The old HUE block (0x0850xxxx) was a misidentification of Power Window params.
272
+ * Real Hue Rotate is at 0x06000004 (SATURATION.LEGACY), real Saturation at 0x06000005.
273
+ */
274
+ const HUE = {
275
+ HUE_ROTATE: 100663300, // 0x06000004 — DRX = (UI - 50) / 50 (UI 50 = no rotation)
276
+ SATURATION: 100663301, // 0x06000005 — DRX = UI / 50 (UI 50 = unity = 1.0)
277
+ };
278
+
279
+ // ============================================================================
280
+ // LUMA VS SATURATION (Type 5)
281
+ // ============================================================================
282
+
283
+ /**
284
+ * Luma vs Saturation curve parameters
285
+ */
286
+ const LUM_MIX = {
287
+ PARAM_1: 147849218,
288
+ PARAM_2: 147849220,
289
+ PARAM_3: 147849222,
290
+ PARAM_4: 147849223,
291
+ PARAM_5: 147849224,
292
+ PARAM_6: 147849225,
293
+ PARAM_7: 147849226,
294
+ PARAM_8: 147849227,
295
+ PARAM_9: 147849228,
296
+ PARAM_10: 147849232,
297
+ PARAM_11: 147849233,
298
+ };
299
+
300
+ // ============================================================================
301
+ // SATURATION VS SATURATION (Type 3)
302
+ // ============================================================================
303
+
304
+ /**
305
+ * Saturation vs Saturation curve parameters
306
+ */
307
+ const SAT_VS_SAT = {
308
+ PARAM_1: 149946369,
309
+ PARAM_2: 149946371,
310
+ PARAM_3: 149946373,
311
+ PARAM_4: 149946374,
312
+ PARAM_5: 149946377,
313
+ PARAM_6: 149946378,
314
+ PARAM_7: 149946379,
315
+ };
316
+
317
+ // ============================================================================
318
+ // HDR ZONE CORRECTOR (Type 9)
319
+ // ============================================================================
320
+
321
+ /**
322
+ * HDR Zone corrector parameters
323
+ *
324
+ * IMPORTANT: HDR Zones use NESTED PROTOBUF structure - unlike standard parameters,
325
+ * zone differentiation is done via embedded zone name strings, not separate IDs.
326
+ *
327
+ * Zone names (embedded strings):
328
+ * - "Dark" -> Shadows zone (0-20% luminance)
329
+ * - "Shadow" -> Lower midtones (20-40%)
330
+ * - "Light" -> Upper midtones (60-80%)
331
+ * - "Highlight" -> Specular zone (80-100%) - NOTE: DRX uses "Highlight" not "Specular"
332
+ * - "Global" -> Affects entire image
333
+ *
334
+ * Inner field wire types (within nested structure):
335
+ * - 0x0a <len>: Zone name string
336
+ * - 0x15 <f32>: Exposure value (-6.0 to +6.0, default 0)
337
+ * - 0x3d <f32>: Saturation value (0.0 to 4.0, default 1.0)
338
+ * - 0x1d <f32> 0x25 <f32>: Hue rotation (angle, sat modifier)
339
+ *
340
+ * TRAINED 2026-01-14 from 13 HDR DRX samples
341
+ */
342
+ const HDR_ZONE = {
343
+ // Global HDR controls
344
+ BLACK_OFFSET: 0x86000303, // 2248147715 - Global black offset (float, default 0.0)
345
+
346
+ // Zone container IDs
347
+ ZONE_ADJUSTMENTS: 0x86000305, // 2248147717 - Per-zone adjustments (exposure, color balance, saturation)
348
+ ZONE_DEFINITIONS: 0x86000306, // 2248147718 - Per-zone definitions (range boundaries, falloff)
349
+ ZONE_METADATA: 0x86000309, // 2248147721 - Zone count metadata
350
+
351
+ // Legacy aliases
352
+ ZONE_DATA: 0x86000305, // Alias for ZONE_ADJUSTMENTS (backwards compat)
353
+
354
+ // Legacy/unknown HDR parameter (from original analysis)
355
+ PARAM_1: 0x0c30001b, // 204472347 - Purpose TBD
356
+
357
+ // Inner field wire type constants for ZONE_ADJUSTMENTS (0x86000305)
358
+ WIRE: {
359
+ ZONE_NAME: 0x0a, // F1: Length-delimited string
360
+ EXPOSURE: 0x15, // F2: Fixed32 float (-6.0 to +6.0)
361
+ COLOR_BALANCE_Y: 0x1d, // F3: Fixed32 float (default 0.0)
362
+ COLOR_BALANCE_X: 0x25, // F4: Fixed32 float (default 0.0)
363
+ SATURATION: 0x3d, // F7: Fixed32 float (0.0 to 4.0)
364
+ },
365
+
366
+ // Inner field wire type constants for ZONE_DEFINITIONS (0x86000306)
367
+ WIRE_DEF: {
368
+ ZONE_NAME: 0x0a, // F1: Length-delimited string
369
+ RANGE_1: 0x15, // F2: Fixed32 float (range boundary in stops)
370
+ RANGE_2: 0x1d, // F3: Fixed32 float (range boundary 2 in stops)
371
+ BASE_FALLOFF: 0x25, // F4: Fixed32 float (factory default falloff, immutable)
372
+ FALLOFF: 0x2d, // F5: Fixed32 float (active zone falloff, user-set)
373
+ },
374
+
375
+ // Zone name strings (for matching/generating)
376
+ ZONE_NAMES: {
377
+ BLACK: 'Black',
378
+ DARK: 'Dark',
379
+ SHADOW: 'Shadow',
380
+ LIGHT: 'Light',
381
+ HIGHLIGHT: 'Highlight',
382
+ SPECULAR: 'Specular',
383
+ GLOBAL: 'Global',
384
+ },
385
+
386
+ // Default falloff values per zone (from calibration 2026-03-16)
387
+ // Symmetric: Black/Specular=0.10, Dark/Highlight=0.20, Shadow/Light=0.22
388
+ DEFAULT_FALLOFFS: {
389
+ Black: 0.10,
390
+ Dark: 0.20,
391
+ Shadow: 0.22,
392
+ Light: 0.22,
393
+ Highlight: 0.20,
394
+ Specular: 0.10,
395
+ // Global has no falloff control
396
+ },
397
+
398
+ // Value ranges
399
+ RANGES: {
400
+ exposure: { min: -6.0, max: 6.0, default: 0.0 },
401
+ saturation: { min: 0.0, max: 4.0, default: 1.0 },
402
+ colorBalanceX: { min: -1.0, max: 1.0, default: 0.0 },
403
+ colorBalanceY: { min: -1.0, max: 1.0, default: 0.0 },
404
+ blackOffset: { min: -1.0, max: 1.0, default: 0.0 },
405
+ falloff: { min: 0.0, max: 2.0, default: 0.2 },
406
+ },
407
+ };
408
+
409
+ // ============================================================================
410
+ // HSL QUALIFIER (Secondary Correction)
411
+ // ============================================================================
412
+
413
+ /**
414
+ * Qualifier parameters for secondary color correction (0x0830xxxx range)
415
+ *
416
+ * ALL qualifier types (HSL, RGB, Luma, 3D) share the same param ID range.
417
+ * The qualifier mode selector (0x88300001) determines which type is active.
418
+ * Field meaning changes based on mode.
419
+ *
420
+ * TRAINED 2026-03-16: All IDs confirmed via live Resolve DRX export + protobuf diff.
421
+ * Scale: DRX = UI / 100 for all percentage-based params.
422
+ */
423
+ const HSL_QUALIFIER = {
424
+ // Mode selector — determines which qualifier type is active
425
+ QUALIFIER_MODE: 2284847105, // 0x88300001 — 0=HSL (default/absent), 2=RGB, 4=Luma, 6=3D
426
+
427
+ // === HSL MODE (0x88300001 = 0 or absent) ===
428
+ // Hue selection
429
+ HUE_CENTER: 137363470, // 0x0830000E — DRX = UI / 100
430
+ HUE_WIDTH: 137363471, // 0x0830000F — DRX = UI / 100
431
+ HUE_SYM: 137363472, // 0x08300010 — DRX = UI / 100
432
+ HUE_SOFT: 137363473, // 0x08300011 — DRX = UI / 100
433
+
434
+ // Saturation selection
435
+ SAT_HIGH: 137363474, // 0x08300012 — DRX = UI / 100
436
+ SAT_LOW: 137363475, // 0x08300013 — DRX = UI / 100
437
+ SAT_HIGH_SOFT: 137363476, // 0x08300014 — DRX = UI / 100
438
+ SAT_LOW_SOFT: 137363477, // 0x08300015 — DRX = UI / 100
439
+
440
+ // Luminance selection
441
+ LUM_HIGH: 137363478, // 0x08300016 — DRX = UI / 100
442
+ LUM_LOW: 137363479, // 0x08300017 — DRX = UI / 100
443
+ LUM_HIGH_SOFT: 137363480, // 0x08300018 — DRX = UI / 100
444
+ LUM_LOW_SOFT: 137363481, // 0x08300019 — DRX = UI / 100
445
+
446
+ // Additional HSL qualifier params
447
+ HUE_WIDTH_DUP: 137363493, // 0x08300025 — possible duplicate/linked param
448
+ HUE_SOFT_DUP: 137363494, // 0x08300026 — possible duplicate/linked param
449
+ MODE_FLAG: 137363567, // 0x0830006F — varint=4 (internal mode indicator)
450
+
451
+ // === RGB MODE (0x88300001 = 2) ===
452
+ // Uses 0x08300002–0x0830000D for per-channel ranges. Scale: DRX = UI / 100.
453
+ // ⚠ FIELD ORDER CORRECTED 2026-06-22 (harness §16a, live RGB sweep on DRX_CALIB). The prior
454
+ // "TRAINED 2026-03-16" layout [Low, High, LowSoft, HighSoft] was WRONG — both order and pairing.
455
+ // Live (Red Low 12/High 88/LSoft 5/HSoft 7 → 0x04 0.12 / 0x02 0.88 / 0x05 0.05 / 0x03 0.07) proves the
456
+ // real per-channel layout is [High, HighSoft, Low, LowSoft] from the base id. Const NAMES kept (so the
457
+ // generator's q.rLow/rHigh API stays correct); only the id VALUES are re-pointed to the right fields.
458
+ RGB_R_HIGH: 137363458, // 0x08300002 — Red High
459
+ RGB_R_HIGH_SOFT:137363459, // 0x08300003 — Red High Soft
460
+ RGB_R_LOW: 137363460, // 0x08300004 — Red Low
461
+ RGB_R_LOW_SOFT: 137363461, // 0x08300005 — Red Low Soft
462
+ RGB_G_HIGH: 137363462, // 0x08300006 — Green High
463
+ RGB_G_HIGH_SOFT:137363463, // 0x08300007 — Green High Soft
464
+ RGB_G_LOW: 137363464, // 0x08300008 — Green Low
465
+ RGB_G_LOW_SOFT: 137363465, // 0x08300009 — Green Low Soft
466
+ RGB_B_HIGH: 137363466, // 0x0830000A — Blue High
467
+ RGB_B_HIGH_SOFT:137363467, // 0x0830000B — Blue High Soft
468
+ RGB_B_LOW: 137363468, // 0x0830000C — Blue Low
469
+ RGB_B_LOW_SOFT: 137363469, // 0x0830000D — Blue Low Soft
470
+
471
+ // === 3D MODE (0x88300001 = 6) === VALIDATED LIVE 2026-06-22 (harness §16a): drew a 3D key stroke +
472
+ // set Despill 35 → these six params serialized. Volume/extra/cspace ids confirmed present (nested blobs).
473
+ QUALIFIER_3D_VOLUME: 137363498, // 0x0830002A — nested blob (3D selection volume)
474
+ QUALIFIER_3D_EXTRA: 2284847150, // 0x8830002E — nested blob (additional 3D data)
475
+ QUALIFIER_3D_CSPACE: 2284847152, // 0x88300030 — color-space container (YUV)
476
+ QUALIFIER_3D_EXTRA2: 2284847154, // 0x88300032 — nested blob (additional 3D data, NEW 2026-06-22)
477
+ // ⚠ DESPILL ID CORRECTED 2026-06-22: registry had 0x08300033 (137363507); live measurement shows the
478
+ // real id is 0x88300033 (2284847155), Despill 35 → stored 0.35 (scale /100).
479
+ QUALIFIER_3D_DESPILL:2284847155, // 0x88300033 — float despill (scale /100)
480
+
481
+ // Qualifier output — shared across all qualifier modes
482
+ // CORRECTED 2026-06-22 (harness §16a): value was 2248146001 — a typo vs its own hex comment
483
+ // (0x86000051 = 2248147025, off by 0x400). Blur Radius decoded as unknown_ until live-measured
484
+ // on the DRX_CALIB bars rig: UI 46 → stored 0.46 at 0x86000051, scale /100.
485
+ BLUR_RADIUS: 2248147025, // 0x86000051 — in corrector type 1, scale /100
486
+ // Matte finesse params are in the MATTE_FINESSE block (corrector type 9)
487
+ };
488
+
489
+ // ============================================================================
490
+ // MATTE FINESSE (Corrector Type 9, 0x0C30xxxx range)
491
+ // ============================================================================
492
+
493
+ /**
494
+ * Matte Finesse parameters — qualifier output cleanup controls
495
+ *
496
+ * Applied after qualifier selection to refine the matte/key signal.
497
+ * All scale: DRX = UI / 100
498
+ *
499
+ * TRAINED 2026-03-16: All IDs confirmed.
500
+ */
501
+ const MATTE_FINESSE = {
502
+ // CORRECTED 2026-03-22: Names were swapped in March 16 calibration.
503
+ // Verified empirically: Denoise=15 → 0x0C300020=0.15, CleanBlack=30 → 0x0C300024=0.30
504
+ DENOISE: 204472352, // 0x0C300020 — was incorrectly labeled CLEAN_BLACK
505
+ BLACK_CLIP: 204472353, // 0x0C300021
506
+ WHITE_CLIP: 204472354, // 0x0C300022
507
+ IN_OUT_RATIO: 204472355, // 0x0C300023
508
+ CLEAN_BLACK: 204472356, // 0x0C300024 — was incorrectly labeled CLEAN_WHITE
509
+ CLEAN_WHITE: 204472357, // 0x0C300025 — was incorrectly labeled DENOISE
510
+ MORPH_RADIUS: 204472368, // 0x0C300030
511
+ PRE_FILTER: 204472369, // 0x0C300031
512
+ POST_FILTER: 204472370, // 0x0C300032
513
+ SHADOW: 204472371, // 0x0C300033
514
+ MIDTONE: 204472372, // 0x0C300034
515
+ HIGHLIGHT: 204472373, // 0x0C300035
516
+ };
517
+
518
+ // ============================================================================
519
+ // POWER WINDOWS (Spatial Correction)
520
+ // ============================================================================
521
+
522
+ /**
523
+ * Power Window parameters for spatial grading (0x0850xxxx / 0x8850xxxx range)
524
+ *
525
+ * Corrector Type 4. Window types: 1=Circular, 2=Linear, 3=Polygon, 4=Curve, 5=Gradient
526
+ *
527
+ * TRAINED 2026-03-16: Position/size/type confirmed. Softness partially mapped.
528
+ * Softness uses corrector type 3 (0x0870xxxx) auto-generated alongside window.
529
+ */
530
+ const POWER_WINDOWS = {
531
+ // Transform controls
532
+ ROTATE: 139460609, // 0x08500001 — rotation; scale CONFIRMED 2026-06-22 (multi-point): stored = −UI°/180 (neutral 0; UI 27→-0.15, 49→-0.2722). The "direct degrees" note was WRONG.
533
+ // ⚠ SIZE/ASPECT IDS WERE SWAPPED — corrected 2026-06-22 via isolated multi-point fit (vary one, hold the
534
+ // other neutral). 0x08500004 is ASPECT = (50−UI)/50 (neutral 0); 0x08500006 is SIZE = 1+(UI−50)×0.08 (neutral 1.0).
535
+ ASPECT: 139460612, // 0x08500004 — aspect, scale (50−UI)/50, neutral 0
536
+ SOFT_REF: 139460613, // 0x08500005 — pixel reference = Soft1 × 16 (CONFIRMED 2026-06-22: Soft1 67 → 1072)
537
+ SIZE: 139460614, // 0x08500006 — size, scale 1+(UI−50)×0.08, neutral 1.0
538
+ PAN: 139460619, // 0x0850000B — pixel offset from center (horizontal)
539
+ TILT: 139460620, // 0x0850000C — pixel offset from center (vertical)
540
+ OPACITY: 139460626, // 0x08500012 — window opacity, scale /100 (UI 66 → 0.66). ADDED 2026-06-22 (harness §16a) — was unwired (decoded unknown_).
541
+
542
+ // Type selector
543
+ WINDOW_TYPE: 2286944264, // 0x88500008 — varint: 1=Circular, 2=Linear, 3=Polygon, 4=Curve, 5=Gradient
544
+ REF_WIDTH: 2286944269, // 0x8850000D — reference dimension (288.0 typical)
545
+
546
+ // Unknown positional params (observed but not yet mapped)
547
+ UNK_0E: 2286944270, // 0x8850000E — 0.0
548
+ UNK_0F: 2286944271, // 0x8850000F — 0.0
549
+ TRACKING_BLOB:2286944272, // 0x88500010 — blob (tracking keyframe data)
550
+
551
+ // Softness mask shape — LINEAR/CURVE windows. CORRECTOR TYPE 3 (VALIDATED LIVE 2026-06-22 on DRX_CALIB:
552
+ // dumped corrector.F1 directly = 3; the prior "type 65539 = 0x10003" claim is WRONG/version-stale).
553
+ // SOFT_1–4 scale: UI × 16 — RE-CONFIRMED LIVE 2026-06-22 with asymmetric softness (4.50/6.25/8.75/11.00
554
+ // → 72/100/140/176, all ÷16 exact). PAN/TILT/WIDTH/HEIGHT observed at defaults (0/0/1/1); BBOX = nested blob.
555
+ SOFT_1: 141557769, // 0x08700009 — Soft 1 (also used by circle via SoftRef)
556
+ SOFT_2: 141557770, // 0x0870000A — Soft 2
557
+ SOFT_3: 141557771, // 0x0870000B — Soft 3
558
+ SOFT_4: 141557772, // 0x0870000C — Soft 4
559
+ SOFT_BBOX: 141557780, // 0x08700014 — vertex/bbox data blob (4 corners of linear window)
560
+ SOFT_PAN: 141557781, // 0x08700015 — Pan offset within softness mask (0.0)
561
+ SOFT_TILT: 141557782, // 0x08700016 — Tilt offset (0.0)
562
+ SOFT_WIDTH: 141557783, // 0x08700017 — Width scale (1.0)
563
+ SOFT_HEIGHT: 141557784, // 0x08700018 — Height scale (1.0)
564
+ SOFT_UNK_1: 141557788, // 0x0870001C — unknown (0.0)
565
+ SOFT_UNK_2: 141557789, // 0x0870001D — unknown (0.0)
566
+ // Structural containers on the same ct3 corrector (RE'd live 2026-06-22):
567
+ SOFT_STRUCT_0F: 2289041423, // 0x8870000F — nested {F2} default container
568
+ SOFT_STRUCT_12: 2289041426, // 0x88700012 — varint (default 0)
569
+ SOFT_MATRIX: 2289041438, // 0x8870001E — structural 3×3 matrix (identity default), decoded by decodeStructMatrix
570
+ };
571
+
572
+ // ============================================================================
573
+ // NODE SIZING / INPUT SIZING (Corrector Type 10)
574
+ // ============================================================================
575
+
576
+ /**
577
+ * Node "Input Sizing" transform — Pan/Tilt/Zoom/Width/Height/Rotate/Pitch/Yaw.
578
+ *
579
+ * REVERSE-ENGINEERED 2026-06-22 (harness §16a) on the DRX_CALIB SMPTE-bars compound clip.
580
+ * Stored as CORRECTOR TYPE 10. Params live in F6.F2.F3[] as `1a`-tagged sub-messages, each
581
+ * { F1: <key varint>, F2: { F1: <fixed32 float> } }. Two key groups (the varint encodes the
582
+ * group): group A keys 0x10310001–06, group B keys 0x10B10001–02.
583
+ *
584
+ * Scales (live-measured): Zoom/Width/Height = direct multiplier (1.0 = neutral); Rotate = degrees;
585
+ * Pan = UI px / frame width (71 → 0.03698 = 71/1920); Tilt = UI px / frame height (72 → 0.0667 = 72/1080);
586
+ * Pitch/Yaw = direct (0.77/0.78).
587
+ *
588
+ * NOTE: the drx-parser does NOT yet surface corrector type 10, so these decode to nothing today.
589
+ * Recorded here from the RE; needs a parser extension (extract ct10 + its 1a-entry params). See
590
+ * the internal calibration program ledger (Node Sizing section).
591
+ */
592
+ const NODE_SIZING = {
593
+ WIDTH: 0x10310001, // ZoomX / Width — direct multiplier
594
+ HEIGHT: 0x10310002, // ZoomY / Height — direct multiplier
595
+ ZOOM: 0x10310003, // Zoom — direct multiplier
596
+ ROTATE: 0x10310004, // Rotate — degrees
597
+ PAN: 0x10310005, // Pan — normalized: UI px / frame width (1920)
598
+ TILT: 0x10310006, // Tilt — normalized: UI px / frame height (1080)
599
+ PITCH: 0x10B10001, // Pitch — direct
600
+ YAW: 0x10B10002, // Yaw — direct
601
+ };
602
+
603
+ // ============================================================================
604
+ // POLYGON WINDOW (Corrector Type 5, 0x08B0xxxx range)
605
+ // ============================================================================
606
+
607
+ /**
608
+ * Polygon window parameters — arbitrary vertex shapes
609
+ *
610
+ * DECODED 2026-03-23: Vertex array format fully reverse-engineered.
611
+ *
612
+ * Vertex array (0x08B00006) protobuf structure:
613
+ * N repeated sub-messages, one per vertex:
614
+ * Each: { F1 = X (float32), F2 = Y (float32) }
615
+ * Coordinates are pixels relative to frame center.
616
+ * Y axis: negative = top, positive = bottom.
617
+ *
618
+ * Default rectangle at Size=50 on 1920×1080:
619
+ * (-480,-270), (-480,270), (480,270), (480,-270)
620
+ * = ±(halfWidth×0.5), ±(halfHeight×0.5)
621
+ */
622
+ const POLYGON_WINDOW = {
623
+ SHAPE_TYPE: 145752066, // 0x08B00002 — varint 2 (polygon shape type)
624
+ VERTEX_MODE: 145752068, // 0x08B00004 — varint 0
625
+ VERTEX_ARRAY: 145752070, // 0x08B00006 — N×12B vertex sub-msgs {F1=X, F2=Y} float32 pixels from center
626
+ CLOSE_FLAG: 145752071, // 0x08B00007 — varint 0 (closed shape flag?)
627
+ FILL_FLAG_1: 145752072, // 0x08B00008 — varint 0
628
+ INSIDE_FILL: 145752073, // 0x08B00009 — varint 1 (inside fill enabled)
629
+ ENABLED: 145752074, // 0x08B0000A — varint 1 (window enabled)
630
+ UNK_0E: 145752078, // 0x08B0000E — varint 0
631
+ UNK_0F: 145752079, // 0x08B0000F — varint 0
632
+ };
633
+
634
+ // ============================================================================
635
+ // GRADIENT WINDOW (Corrector Type 65554 = 0x10012, 0x08F0xxxx range)
636
+ // ============================================================================
637
+
638
+ /**
639
+ * Gradient window parameters — different range than circle/linear windows
640
+ *
641
+ * TRAINED 2026-03-22: Softness scale is ×100 (not ×16 like circle/linear).
642
+ * Uses corrector type 65554 (0x10000 + 18).
643
+ */
644
+ const GRADIENT_WINDOW = {
645
+ TYPE: 149946369, // 0x08F00001 — varint 2 (gradient subtype)
646
+ ROTATION: 149946371, // 0x08F00003 — float (rotation; UI 83 → -0.461 on a moved gradient — odd scale, like power-window rotate)
647
+ HANDLE_1_POS: 149946373, // 0x08F00005 — float (handle 1 position, pixels; UI Pan 81 → 2539.52)
648
+ HANDLE_2_POS: 149946374, // 0x08F00006 — float (handle 2 position, pixels; UI Tilt 82 → 2621.44)
649
+ OFFSET_X: 149946377, // 0x08F00009 — float (horizontal offset, 0.0)
650
+ OFFSET_Y: 149946378, // 0x08F0000A — float (vertical offset, 0.0)
651
+ SOFTNESS: 149946379, // 0x08F0000B — float (softness × 100 — CONFIRMED 2026-06-22: Soft1 85 → 8500)
652
+ OPACITY: 149946385, // 0x08F00011 — float opacity, scale /100 (UI 84 → 0.84). ADDED 2026-06-22 (harness §16a) — was unwired.
653
+ MATRIX: 2297430029, // 0x88F0000D — structural container: F10 = row-major 3×3 matrix (identity default). NAMED 2026-06-22 (completeness sweep; off the gradient-window fixture). Exact semantic role (color/orientation) unconfirmed.
654
+ // ⚠ ID COLLISION: TYPE/ROTATION/HANDLE_1/2/OFFSET_X/Y/SOFTNESS share IDs with SAT_VS_SAT.PARAM_1–7
655
+ // (both 0x08F000xx), distinguished ONLY by corrector type (gradient = 65554, sat-v-sat = 3). The flat
656
+ // PARAM_ID_MAP is keyed by id alone, so it resolves these to satVsSat.* — gradient-window params
657
+ // currently MISLABEL as satVsSat. Proper fix = corrector-type-aware naming (follow-up). 0x08F00011
658
+ // (opacity) is collision-free, so it's mapped below.
659
+ };
660
+
661
+ // ============================================================================
662
+ // NODE LUT REF (per-node LUT attachment, 0x860000A0–A1)
663
+ // ============================================================================
664
+
665
+ /**
666
+ * Per-node LUT references — when a Resolve color node has a LUT attached
667
+ * via Right-click → LUT, the LUT path is stored as two parameters inside
668
+ * a corrector block at the node level (NOT the corrector list — same
669
+ * location in F9 the existing parser treats as a corrector, but the
670
+ * params carry LUT data instead of grade controls).
671
+ *
672
+ * DECODED 2026-06-19 (P5.1, Session 31) from a paired DRX capture
673
+ * (no-LUT vs with-LUT, same clip + node):
674
+ * - SLOT_META (0x860000A0): varint, value=6 in captured fixture.
675
+ * Likely encodes the LUT slot kind (node-LUT vs other). Value
676
+ * persists across LUT changes per fixture but exact taxonomy
677
+ * is queued for a follow-up multi-fixture capture.
678
+ * - LUT_PATH (0x860000A1): value envelope's F5 carries the LUT
679
+ * basename/path as a string. In the captured fixture it was the
680
+ * bare basename "FilmUnlimited_2383_Rec709_Finished.cube"; absolute
681
+ * paths likely also live here for custom (non-built-in) LUTs.
682
+ *
683
+ * Encoding scheme (value envelope F5 = string) differs from the
684
+ * float/int envelopes used by grade controls. The decoder
685
+ * `extract-lut-refs.js` reads F5 directly rather than going through
686
+ * the standard parameter-codec int/float unwrap path.
687
+ */
688
+ const NODE_LUT_REF = {
689
+ SLOT_META: 2248147104, // 0x860000A0 — varint (slot/kind code, e.g. 6)
690
+ LUT_PATH: 2248147105, // 0x860000A1 — string in F5 of value envelope (LUT path or basename)
691
+ };
692
+
693
+ // ============================================================================
694
+ // COLOR WARPER (Primary Corrector, Type 1, 0x86000120+ range)
695
+ // ============================================================================
696
+
697
+ /**
698
+ * Color Warper parameters — chroma-warp PIN list (Primary corrector, ct1).
699
+ *
700
+ * RE-CALIBRATED LIVE 2026-06-22 on DRX_CALIB (Resolve 21, harness §16a). The prior
701
+ * "DECODED 2026-03-23" mesh-vertex model (0x86000121: F1=ver/F2=config/F3=N×12B
702
+ * float32 triplets, "5 vertices per moved point") is **WRONG for R21** — exactly the
703
+ * kind of unverified registry claim the validation rule warns about (cf. the polygon
704
+ * 0x08B0/ct5 claim, also wrong). A live chroma-warp move emits **none** of
705
+ * 0x86000121/126/129/12C/12D/130; the entire 0x86000120+ scan turns up only
706
+ * 0x86000133, 0x86000136, 0x86000137 and 0x86000138.
707
+ *
708
+ * R21 stores the Color Warper (Chroma Warp) as a list of **pins**, not a vertex mesh:
709
+ * 0x86000133 MODE_FLAG varint (observed 2)
710
+ * 0x86000136 CONFIG_A varint (observed 2 — was labeled COLOR_SPACE "HS mode")
711
+ * 0x86000137 CONFIG_B varint (observed 0/2)
712
+ * 0x86000138 PINS value envelope = { F2: { F27: { F1: [ <pin>, … ] } } }
713
+ *
714
+ * Each pin sub-message (validated identity-scale against the UI Pin controls):
715
+ * F1 varint pin id/index (observed 1)
716
+ * F2 f32 source chroma X
717
+ * F3 f32 source chroma Y
718
+ * F4 f32 dest chroma X
719
+ * F5 f32 dest chroma Y
720
+ * F6 f32 Chroma Range (UI "Chroma Range")
721
+ * F7 f32 Exposure (UI "Exposure"; default 0 is NOT serialized)
722
+ * F8 f32 Tonal Range Low (UI "Tonal Range Low")
723
+ * F9 f32 Tonal Range High (UI "Tonal Range High")
724
+ * F10 f32 Tonal Range Pivot (UI "Tonal Range Pivot")
725
+ * F2–F5 are normalized chroma-plane coords (source→dest warp vector). Default-valued
726
+ * fields are omitted (e.g. F7 only appears when Exposure≠0). Lifted into named
727
+ * `colorWarper.pin<N>.<field>` params + `node.params.colorWarper` by decodeColorWarperPins.
728
+ * Luma Warp (the palette's second mode) is a parallel pin list — UI-gated, not yet swept.
729
+ */
730
+ const COLOR_WARPER = {
731
+ MODE_FLAG: 2248147251, // 0x86000133 — varint warper mode (observed 2)
732
+ CONFIG_A: 2248147254, // 0x86000136 — varint config (observed 2)
733
+ CONFIG_B: 2248147255, // 0x86000137 — varint config (observed 0/2)
734
+ PINS: 2248147256, // 0x86000138 — pin list: F2.F27.F1[] (see block comment)
735
+ };
736
+
737
+ // ============================================================================
738
+ // COLORSLICE (OFX Tool 0xC00000DC, 0x86000600+ range)
739
+ // ============================================================================
740
+
741
+ /**
742
+ * ColorSlice parameters — global controls + per-vector color adjustment grid
743
+ *
744
+ * TRAINED 2026-03-16: Confirmed IN DRX (manual study was wrong).
745
+ * Uses OFX tool container + dedicated param IDs.
746
+ *
747
+ * DECODED 2026-03-23: Per-vector format fully reverse-engineered.
748
+ *
749
+ * CALIBRATED 2026-06-22 (automated harness, design note §16a): the 6 GLOBAL controls
750
+ * at 0x86000600–0x86000605 were previously MISSED (the range was thought to start at
751
+ * 0x86000606). Measured live by setting each UI field to known values on the Color
752
+ * page and reading back the encoded value from Project.db. Scales: identity for all
753
+ * except Hue, which is NEGATED (UI +X → stored −X), consistent with the per-vector
754
+ * note below. Sat default 1.0 (range up to 2.0); others default 0.0.
755
+ *
756
+ * Grid blob (0x86000606) stored in protobuf F24:
757
+ * 7 repeated sub-messages, one per color vector:
758
+ * Order: Red, Skin, Yellow, Green, Cyan, Blue, Magenta
759
+ * Each: F1=enabled(varint), F3=sat(float32), F4=hue(float32, optional, absent=0)
760
+ *
761
+ * Sat default = 1.0, Hue default = 0.0 (absent). Hue stored as negative of UI value.
762
+ */
763
+ const COLORSLICE = {
764
+ // Global controls (0x86000600–605) — CALIBRATED 2026-06-22.
765
+ DENSITY: 2248148480, // 0x86000600 — "Den" (identity)
766
+ DENSITY_DEPTH:2248148481, // 0x86000601 — "Den.Depth" (identity)
767
+ SAT: 2248148482, // 0x86000602 — "Sat" (identity, default 1.0, max 2.0)
768
+ SAT_BALANCE: 2248148483, // 0x86000603 — "Sat.Balance" (identity)
769
+ SAT_DEPTH: 2248148484, // 0x86000604 — "Sat.Depth" (identity)
770
+ HUE: 2248148485, // 0x86000605 — "Hue" (NEGATED: UI +X → stored −X)
771
+ // Per-vector grid (0x86000606+) — structure documented above.
772
+ VECTOR_DATA: 2248148486, // 0x86000606 — 7 per-vector sub-msgs (Red,Skin,Yel,Grn,Cyn,Blu,Mag)
773
+ GRID_DATA_2: 2248148487, // 0x86000607 — additional grid data
774
+ OFX_TOOL_ID: 0xC00000DC, // OFX tool type ID when ColorSlice is active
775
+ };
776
+
777
+ // ============================================================================
778
+ // RESOLVEFX / OFX PLUGIN ENCODING (F7.F10 container)
779
+ // ============================================================================
780
+
781
+ /**
782
+ * ResolveFX plugin parameters — stored in node tool list F7.F10
783
+ *
784
+ * NOT in corrector chain. Uses OFX string-named parameters, not integer IDs.
785
+ * Each plugin has its own param names (e.g., Film Grain: "inMean", "inSize", etc.)
786
+ *
787
+ * TRAINED 2026-03-16: Container structure confirmed. Per-plugin param mapping
788
+ * needs autoresearch Phase 6.
789
+ */
790
+ const RESOLVEFX = {
791
+ // Known OFX tool type IDs (in F7.F10)
792
+ FILM_GRAIN: 0xC0000087,
793
+ OFX_MARKER: 0x4F4659, // "OFY" — marker byte in F2.F21.F1
794
+
795
+ // Plugin container structure:
796
+ // F7.F10 (tool list)
797
+ // F2.F21 → F1 = 0x4F4659 ("OFY" = OFX marker)
798
+ // F5 (repeated) → F1 = descriptor with string name, F2 = value
799
+
800
+ // ────────────────────────────────────────────────────────────────────
801
+ // Plugin slugs (P2.1 discovery 2026-06-19, Session 32)
802
+ // ────────────────────────────────────────────────────────────────────
803
+ //
804
+ // The OFX container's F2.F5 field carries a string slug — the canonical
805
+ // identifier the protobuf bag uses to name the plugin. Slugs MAY carry
806
+ // a version suffix (e.g. `facerefinement2`, `lensflarev2`); newer
807
+ // plugin revisions land at a new slug while the old one persists.
808
+ //
809
+ // Discovery: scripts/drx-autoresearch/discover-ofx-tools.mjs against
810
+ // the Session 30 capture set.
811
+ //
812
+ // Knowledge: docs/design/drp-drx-drt-closeout-harness/knowledge/
813
+ // ofx-tool-ids.md
814
+ SLUGS: {
815
+ FILM_GRAIN: 'com.blackmagicdesign.resolvefx.filmgrain',
816
+ BEAUTY: 'com.blackmagicdesign.resolvefx.beauty',
817
+ FACE_REFINEMENT2: 'com.blackmagicdesign.resolvefx.facerefinement2',
818
+ LENS_FLARE_V2: 'com.blackmagicdesign.resolvefx.lensflarev2',
819
+ GLOW: 'com.blackmagicdesign.resolvefx.glow',
820
+ },
821
+
822
+ // Known parameter names per plugin slug. Partial: only the
823
+ // fixture-perturbed param + the always-present `resolvefxVersion`
824
+ // are confirmed. Expanded coverage requires a per-plugin
825
+ // single-param sweep (queued follow-up).
826
+ KNOWN_PARAMS: {
827
+ 'com.blackmagicdesign.resolvefx.filmgrain': ['filmGrainPresets', 'resolvefxVersion'],
828
+ 'com.blackmagicdesign.resolvefx.beauty': ['watercolorBlend', 'resolvefxVersion'],
829
+ 'com.blackmagicdesign.resolvefx.facerefinement2': ['gradShineRemoval', 'resolvefxVersion'],
830
+ 'com.blackmagicdesign.resolvefx.lensflarev2': ['xyPosition', 'resolvefxVersion'],
831
+ 'com.blackmagicdesign.resolvefx.glow': ['inputAlphaUsage', 'resolvefxVersion'],
832
+ },
833
+ };
834
+
835
+ // ============================================================================
836
+ // CURVES CORRECTOR (Type 18) — LEGACY MISLABEL, superseded 2026-07-02
837
+ // ============================================================================
838
+
839
+ /**
840
+ * ⚠ The old "Curves corrector (Type 18)" grouping was an unvalidated legacy claim
841
+ * (same class as the Color Warper mesh / polygon 0x08B0 claims — wrong when measured).
842
+ * A live palette sweep on R19.1.3 (bars rig; distinctive values) proves these ids are:
843
+ * 0x0C30001x → the KEY palette, corrector type 9 (shared with Matte Finesse 0x0C30002x)
844
+ * 0x0C4000xx → the MOTION EFFECTS palette, corrector type 15 (NEW corrector type)
845
+ * The CURVES constants are kept for source compatibility; PARAM_ID_MAP now carries the
846
+ * measured names below.
847
+ */
848
+ const CURVES = {
849
+ PARAM_1: 204472349,
850
+ PARAM_2: 205520898,
851
+ PARAM_3: 205520899,
852
+ PARAM_4: 205520900,
853
+ PARAM_5: 205520903,
854
+ PARAM_6: 205520904,
855
+ PARAM_7: 205520905,
856
+ PARAM_8: 205520907,
857
+ PARAM_9: 205520908,
858
+ PARAM_10: 205520909,
859
+ PARAM_11: 205520917,
860
+ PARAM_12: 205520918,
861
+ PARAM_13: 205520919,
862
+ };
863
+
864
+ // ============================================================================
865
+ // BLUR PALETTE (Blur / Sharpen / Mist) — ct1, swept live 2026-07-02
866
+ // ============================================================================
867
+
868
+ /**
869
+ * Blur palette, Blur mode (Radius 0.73 / H-V Ratio 0.62 / Scaling 0.31 sweep):
870
+ * RADIUS 0x86000052–54 (R/G/B) stored = (UI − 0.5) × 2 (0.73 → 0.46; neutral 0.5 → 0)
871
+ * HV_RATIO 0x86000056–58 (R/G/B) stored = (UI − 0.5) × 2 (0.62 → 0.24)
872
+ * SCALING 0x8600005B–5D (R/G/B) identity observed (0.31 → 0.31)
873
+ * Single-point fits — affine forms consistent with the 0.5-neutral sliders. Sharpen/Mist
874
+ * share the palette (mode presumably flagged elsewhere); not separately swept.
875
+ */
876
+ const BLUR_PALETTE = {
877
+ RADIUS_R: 2248147026, // 0x86000052
878
+ RADIUS_G: 2248147027, // 0x86000053
879
+ RADIUS_B: 2248147028, // 0x86000054
880
+ HV_RATIO_R: 2248147030, // 0x86000056
881
+ HV_RATIO_G: 2248147031, // 0x86000057
882
+ HV_RATIO_B: 2248147032, // 0x86000058
883
+ SCALING_R: 2248147035, // 0x8600005B
884
+ SCALING_G: 2248147036, // 0x8600005C
885
+ SCALING_B: 2248147037, // 0x8600005D
886
+ };
887
+
888
+ // ============================================================================
889
+ // KEY PALETTE — ct9 (0x0C30001x), swept live 2026-07-02
890
+ // ============================================================================
891
+
892
+ /**
893
+ * Key palette (Key Input Gain 0.85 / Offset 0.12, Key Output Gain 0.65 / Offset 0.08
894
+ * sweep): all identity scale. NOTE 0x0C30001D (Key Output Gain) is the param the June
895
+ * keyframe sweep animated — it was labeled curves.param1 then.
896
+ */
897
+ const KEY_PALETTE = {
898
+ INPUT_GAIN: 204472345, // 0x0C300019 — identity (0.85 → 0.85)
899
+ INPUT_OFFSET: 204472346, // 0x0C30001A — identity
900
+ OUTPUT_GAIN: 204472349, // 0x0C30001D — identity (== CURVES.PARAM_1)
901
+ OUTPUT_OFFSET: 204472350, // 0x0C30001E — identity
902
+ };
903
+
904
+ // ============================================================================
905
+ // MOTION EFFECTS PALETTE — ct15 (0x0C4000xx), swept live 2026-07-02
906
+ // ============================================================================
907
+
908
+ /**
909
+ * Motion Effects (Spatial NR luma/chroma 27, blend 0.15; Temporal frames 2,
910
+ * luma/chroma 21, motion 35, blend 0.25; Motion Blur 0.4 sweep):
911
+ * SPATIAL_LUMA/CHROMA identity (UI 27 → 27) · SPATIAL_BLEND identity (0.15)
912
+ * TEMPORAL_LUMA/CHROMA identity (21) · TEMPORAL_BLEND identity (0.25)
913
+ * FRAMES_FLAG varint {F2:4} at UI frames 2 (2× or enum — single point, unconfirmed)
914
+ * TEMPORAL_MOTION: UI 35 → 11.8 (scale unconfirmed, single point)
915
+ * MOTION_BLUR: UI 0.4 → 0.0044 (scale unconfirmed, single point)
916
+ */
917
+ const MOTION_EFFECTS = {
918
+ SPATIAL_LUMA: 205520898, // 0x0C400002 (== CURVES.PARAM_2)
919
+ SPATIAL_CHROMA: 205520899, // 0x0C400003
920
+ SPATIAL_BLEND: 205520900, // 0x0C400004
921
+ FRAMES_FLAG: 205520903, // 0x0C400007 — varint
922
+ TEMPORAL_MOTION: 205520906, // 0x0C40000A — scale unconfirmed
923
+ TEMPORAL_LUMA: 205520907, // 0x0C40000B
924
+ TEMPORAL_CHROMA: 205520908, // 0x0C40000C
925
+ TEMPORAL_BLEND: 205520909, // 0x0C40000D
926
+ MOTION_BLUR: 205520913, // 0x0C400011 — scale unconfirmed
927
+ };
928
+
929
+ // ============================================================================
930
+ // UNIFIED PARAMETER MAP
931
+ // ============================================================================
932
+
933
+ /**
934
+ * Complete parameter ID to metadata mapping
935
+ * Used for parsing DRX files and extracting parameters
936
+ */
937
+ const PARAM_ID_MAP = {
938
+ // Lift
939
+ [LIFT.R]: { control: 'lift', channel: 'r', correctorType: 1 },
940
+ [LIFT.G]: { control: 'lift', channel: 'g', correctorType: 1 },
941
+ [LIFT.B]: { control: 'lift', channel: 'b', correctorType: 1 },
942
+ [LIFT.MASTER]: { control: 'lift', channel: 'master', correctorType: 1 },
943
+
944
+ // Gain
945
+ [GAIN.R]: { control: 'gain', channel: 'r', correctorType: 1 },
946
+ [GAIN.G]: { control: 'gain', channel: 'g', correctorType: 1 },
947
+ [GAIN.B]: { control: 'gain', channel: 'b', correctorType: 1 },
948
+ [GAIN.MASTER]: { control: 'gain', channel: 'master', correctorType: 1 },
949
+
950
+ // Gamma
951
+ [GAMMA.R]: { control: 'gamma', channel: 'r', correctorType: 1 },
952
+ [GAMMA.G]: { control: 'gamma', channel: 'g', correctorType: 1 },
953
+ [GAMMA.B]: { control: 'gamma', channel: 'b', correctorType: 1 },
954
+ [GAMMA.MASTER]: { control: 'gamma', channel: 'master', correctorType: 1 },
955
+
956
+ // Offset
957
+ [OFFSET.R]: { control: 'offset', channel: 'r', correctorType: 1 },
958
+ [OFFSET.G]: { control: 'offset', channel: 'g', correctorType: 1 },
959
+ [OFFSET.B]: { control: 'offset', channel: 'b', correctorType: 1 },
960
+
961
+ // Saturation
962
+ [SATURATION.PRIMARY]: { control: 'saturation', channel: 'master', correctorType: 1 },
963
+ [SATURATION.LEGACY]: { control: 'saturation', channel: 'master', correctorType: 1 },
964
+
965
+ // Temperature/Tint
966
+ [TEMP_TINT.TEMPERATURE]: { control: 'temperature', channel: 'master', correctorType: 1 },
967
+ [TEMP_TINT.TINT]: { control: 'tint', channel: 'master', correctorType: 1 },
968
+ [TEMP_TINT.MIDTONE_DETAIL]: { control: 'midtoneDetail', channel: 'master', correctorType: 1 },
969
+ [TEMP_TINT.COLOR_BOOST]: { control: 'colorBoost', channel: 'master', correctorType: 1 },
970
+ [TEMP_TINT.CONTRAST]: { control: 'contrast', channel: 'master', correctorType: 1, note: 'Log contrast' },
971
+
972
+ // Contrast / Pivot / Log Range (Primary corrector, shared controls range)
973
+ [CONTRAST.CONTRAST]: { control: 'contrast', channel: 'master', correctorType: 1 },
974
+ [CONTRAST.PIVOT]: { control: 'pivot', channel: 'master', correctorType: 1 },
975
+ [CONTRAST.LOW_RANGE]: { control: 'lowRange', channel: 'master', correctorType: 1 },
976
+ [CONTRAST.HIGH_RANGE]: { control: 'highRange', channel: 'master', correctorType: 1, note: 'INVERTED: DRX = 1.0 - UI' },
977
+
978
+ // HSL Qualifier (corrector type 2, 0x0830xxxx range — trained 2026-03-16)
979
+ [HSL_QUALIFIER.HUE_CENTER]: { control: 'qualifier', channel: 'hueCenter', correctorType: 2 },
980
+ [HSL_QUALIFIER.HUE_WIDTH]: { control: 'qualifier', channel: 'hueWidth', correctorType: 2 },
981
+ [HSL_QUALIFIER.HUE_SYM]: { control: 'qualifier', channel: 'hueSymmetry', correctorType: 2 },
982
+ [HSL_QUALIFIER.HUE_SOFT]: { control: 'qualifier', channel: 'hueSoft', correctorType: 2 },
983
+ [HSL_QUALIFIER.SAT_HIGH]: { control: 'qualifier', channel: 'satHigh', correctorType: 2 },
984
+ [HSL_QUALIFIER.SAT_LOW]: { control: 'qualifier', channel: 'satLow', correctorType: 2 },
985
+ [HSL_QUALIFIER.SAT_HIGH_SOFT]: { control: 'qualifier', channel: 'satHighSoft', correctorType: 2 },
986
+ [HSL_QUALIFIER.SAT_LOW_SOFT]: { control: 'qualifier', channel: 'satLowSoft', correctorType: 2 },
987
+ [HSL_QUALIFIER.LUM_HIGH]: { control: 'qualifier', channel: 'lumHigh', correctorType: 2 },
988
+ [HSL_QUALIFIER.LUM_LOW]: { control: 'qualifier', channel: 'lumLow', correctorType: 2 },
989
+ [HSL_QUALIFIER.LUM_HIGH_SOFT]: { control: 'qualifier', channel: 'lumHighSoft', correctorType: 2 },
990
+ [HSL_QUALIFIER.LUM_LOW_SOFT]: { control: 'qualifier', channel: 'lumLowSoft', correctorType: 2 },
991
+
992
+ // RGB-mode qualifier ranges (correctorType 2, scale UI/100) — VALIDATED LIVE 2026-06-22. Distinct id
993
+ // range (0x02–0x0d) from HSL mode (0x0e+), so no collision; mode flag 0x88300001=2 selects RGB.
994
+ [HSL_QUALIFIER.RGB_R_HIGH]: { control: 'qualifier', channel: 'rgbRHigh', correctorType: 2, note: 'UI/100' },
995
+ [HSL_QUALIFIER.RGB_R_HIGH_SOFT]: { control: 'qualifier', channel: 'rgbRHighSoft', correctorType: 2, note: 'UI/100' },
996
+ [HSL_QUALIFIER.RGB_R_LOW]: { control: 'qualifier', channel: 'rgbRLow', correctorType: 2, note: 'UI/100' },
997
+ [HSL_QUALIFIER.RGB_R_LOW_SOFT]: { control: 'qualifier', channel: 'rgbRLowSoft', correctorType: 2, note: 'UI/100' },
998
+ [HSL_QUALIFIER.RGB_G_HIGH]: { control: 'qualifier', channel: 'rgbGHigh', correctorType: 2, note: 'UI/100' },
999
+ [HSL_QUALIFIER.RGB_G_HIGH_SOFT]: { control: 'qualifier', channel: 'rgbGHighSoft', correctorType: 2, note: 'UI/100' },
1000
+ [HSL_QUALIFIER.RGB_G_LOW]: { control: 'qualifier', channel: 'rgbGLow', correctorType: 2, note: 'UI/100' },
1001
+ [HSL_QUALIFIER.RGB_G_LOW_SOFT]: { control: 'qualifier', channel: 'rgbGLowSoft', correctorType: 2, note: 'UI/100' },
1002
+ [HSL_QUALIFIER.RGB_B_HIGH]: { control: 'qualifier', channel: 'rgbBHigh', correctorType: 2, note: 'UI/100' },
1003
+ [HSL_QUALIFIER.RGB_B_HIGH_SOFT]: { control: 'qualifier', channel: 'rgbBHighSoft', correctorType: 2, note: 'UI/100' },
1004
+ [HSL_QUALIFIER.RGB_B_LOW]: { control: 'qualifier', channel: 'rgbBLow', correctorType: 2, note: 'UI/100' },
1005
+ [HSL_QUALIFIER.RGB_B_LOW_SOFT]: { control: 'qualifier', channel: 'rgbBLowSoft', correctorType: 2, note: 'UI/100' },
1006
+
1007
+ // 3D-mode qualifier (correctorType 2) — VALIDATED LIVE 2026-06-22. Volume/extra/cspace are nested blobs
1008
+ // (named, not deep-decoded — bounded scope); Despill is a /100 float.
1009
+ [HSL_QUALIFIER.QUALIFIER_3D_VOLUME]: { control: 'qualifier', channel: 'volume3d', correctorType: 2, nested: true, note: '3D selection volume blob' },
1010
+ [HSL_QUALIFIER.QUALIFIER_3D_EXTRA]: { control: 'qualifier', channel: 'extra3d', correctorType: 2, nested: true },
1011
+ [HSL_QUALIFIER.QUALIFIER_3D_CSPACE]: { control: 'qualifier', channel: 'cspace3d', correctorType: 2, nested: true, note: 'color-space container (YUV)' },
1012
+ [HSL_QUALIFIER.QUALIFIER_3D_EXTRA2]: { control: 'qualifier', channel: 'extra3d2', correctorType: 2, nested: true },
1013
+ [HSL_QUALIFIER.QUALIFIER_3D_DESPILL]: { control: 'qualifier', channel: 'despill3d', correctorType: 2, note: 'UI/100' },
1014
+ [HSL_QUALIFIER.QUALIFIER_MODE]: { control: 'qualifier', channel: 'mode', correctorType: 2, note: '0=HSL, 2=RGB, 4=Luma, 6=3D' },
1015
+ [HSL_QUALIFIER.MODE_FLAG]: { control: 'qualifier', channel: 'modeFlag', correctorType: 2, note: 'internal mode indicator (varint, observed 4); value envelope F2. NAMED 2026-06-22' },
1016
+ [HSL_QUALIFIER.BLUR_RADIUS]: { control: 'qualifier', channel: 'blurRadius', correctorType: 1 },
1017
+
1018
+ // Matte Finesse (corrector type 9, 0x0C30xxxx — trained 2026-03-16)
1019
+ [MATTE_FINESSE.DENOISE]: { control: 'matteFinesse', channel: 'denoise', correctorType: 9 },
1020
+ [MATTE_FINESSE.BLACK_CLIP]: { control: 'matteFinesse', channel: 'blackClip', correctorType: 9 },
1021
+ [MATTE_FINESSE.WHITE_CLIP]: { control: 'matteFinesse', channel: 'whiteClip', correctorType: 9 },
1022
+ [MATTE_FINESSE.IN_OUT_RATIO]: { control: 'matteFinesse', channel: 'inOutRatio', correctorType: 9 },
1023
+ [MATTE_FINESSE.CLEAN_BLACK]: { control: 'matteFinesse', channel: 'cleanBlack', correctorType: 9 },
1024
+ [MATTE_FINESSE.CLEAN_WHITE]: { control: 'matteFinesse', channel: 'cleanWhite', correctorType: 9 },
1025
+ [MATTE_FINESSE.MORPH_RADIUS]: { control: 'matteFinesse', channel: 'morphRadius', correctorType: 9 },
1026
+ [MATTE_FINESSE.PRE_FILTER]: { control: 'matteFinesse', channel: 'preFilter', correctorType: 9 },
1027
+ [MATTE_FINESSE.POST_FILTER]: { control: 'matteFinesse', channel: 'postFilter', correctorType: 9 },
1028
+ [MATTE_FINESSE.SHADOW]: { control: 'matteFinesse', channel: 'shadow', correctorType: 9 },
1029
+ [MATTE_FINESSE.MIDTONE]: { control: 'matteFinesse', channel: 'midtone', correctorType: 9 },
1030
+ [MATTE_FINESSE.HIGHLIGHT]: { control: 'matteFinesse', channel: 'highlight', correctorType: 9 },
1031
+
1032
+ // Power Windows (corrector type 4, 0x0850xxxx — trained 2026-03-16)
1033
+ [POWER_WINDOWS.ROTATE]: { control: 'window', channel: 'rotate', correctorType: 4, note: 'stored = −UI°/180' },
1034
+ [POWER_WINDOWS.SIZE]: { control: 'window', channel: 'size', correctorType: 4, note: '0x08500006; stored = 1+(UI−50)×0.08, neutral 1.0' },
1035
+ [POWER_WINDOWS.SOFT_REF]: { control: 'window', channel: 'softRef', correctorType: 4 },
1036
+ [POWER_WINDOWS.ASPECT]: { control: 'window', channel: 'aspect', correctorType: 4, note: '0x08500004; stored = (50−UI)/50, neutral 0' },
1037
+ [POWER_WINDOWS.PAN]: { control: 'window', channel: 'pan', correctorType: 4 },
1038
+ [POWER_WINDOWS.TILT]: { control: 'window', channel: 'tilt', correctorType: 4 },
1039
+ [POWER_WINDOWS.WINDOW_TYPE]: { control: 'window', channel: 'type', correctorType: 4, note: '1=Circ, 2=Lin, 3=Poly, 4=Curve, 5=Grad' },
1040
+ [POWER_WINDOWS.OPACITY]: { control: 'window', channel: 'opacity', correctorType: 4, note: 'scale /100' },
1041
+ [POWER_WINDOWS.REF_WIDTH]: { control: 'window', channel: 'refWidth', correctorType: 4, note: 'reference dimension (288 typical)' },
1042
+ [POWER_WINDOWS.UNK_0E]: { control: 'window', channel: 'unk0e', correctorType: 4 },
1043
+ [POWER_WINDOWS.UNK_0F]: { control: 'window', channel: 'unk0f', correctorType: 4 },
1044
+ [POWER_WINDOWS.TRACKING_BLOB]: { control: 'window', channel: 'trackingBlob', correctorType: 4, nested: true, note: 'tracking keyframe data blob' },
1045
+
1046
+ // Linear/Curve window softness mask (corrector type 3, VALIDATED LIVE 2026-06-22). Soft 1-4 = UI × 16.
1047
+ [POWER_WINDOWS.SOFT_1]: { control: 'window', channel: 'soft1', correctorType: 3, note: 'stored = UI × 16' },
1048
+ [POWER_WINDOWS.SOFT_2]: { control: 'window', channel: 'soft2', correctorType: 3, note: 'stored = UI × 16' },
1049
+ [POWER_WINDOWS.SOFT_3]: { control: 'window', channel: 'soft3', correctorType: 3, note: 'stored = UI × 16' },
1050
+ [POWER_WINDOWS.SOFT_4]: { control: 'window', channel: 'soft4', correctorType: 3, note: 'stored = UI × 16' },
1051
+ [POWER_WINDOWS.SOFT_BBOX]: { control: 'window', channel: 'softBbox', correctorType: 3, nested: true, note: 'softness-mask bbox blob' },
1052
+ [POWER_WINDOWS.SOFT_PAN]: { control: 'window', channel: 'softPan', correctorType: 3, note: 'mask pan offset (default 0)' },
1053
+ [POWER_WINDOWS.SOFT_TILT]: { control: 'window', channel: 'softTilt', correctorType: 3, note: 'mask tilt offset (default 0)' },
1054
+ [POWER_WINDOWS.SOFT_WIDTH]: { control: 'window', channel: 'softWidth', correctorType: 3, note: 'mask width scale (default 1)' },
1055
+ [POWER_WINDOWS.SOFT_HEIGHT]: { control: 'window', channel: 'softHeight', correctorType: 3, note: 'mask height scale (default 1)' },
1056
+ [POWER_WINDOWS.SOFT_UNK_1]: { control: 'window', channel: 'softUnk1', correctorType: 3 },
1057
+ [POWER_WINDOWS.SOFT_UNK_2]: { control: 'window', channel: 'softUnk2', correctorType: 3 },
1058
+ [POWER_WINDOWS.SOFT_STRUCT_0F]: { control: 'window', channel: 'softStruct0f', correctorType: 3, nested: true },
1059
+ [POWER_WINDOWS.SOFT_STRUCT_12]: { control: 'window', channel: 'softStruct12', correctorType: 3 },
1060
+ // SOFT_MATRIX (0x8870001E) is decoded structurally by decodeStructMatrix → window.softMatrix.
1061
+
1062
+ // Log wheels (corrected 2026-01-14)
1063
+ [LOG_WHEELS.SHADOW_R]: { control: 'logShadow', channel: 'r', correctorType: 1 },
1064
+ [LOG_WHEELS.SHADOW_G]: { control: 'logShadow', channel: 'g', correctorType: 1 },
1065
+ [LOG_WHEELS.SHADOW_B]: { control: 'logShadow', channel: 'b', correctorType: 1 },
1066
+ [LOG_WHEELS.MIDTONE_R]: { control: 'logMidtone', channel: 'r', correctorType: 1 },
1067
+ [LOG_WHEELS.MIDTONE_G]: { control: 'logMidtone', channel: 'g', correctorType: 1 },
1068
+ [LOG_WHEELS.MIDTONE_B]: { control: 'logMidtone', channel: 'b', correctorType: 1 },
1069
+ [LOG_WHEELS.HIGHLIGHT_R]: { control: 'logHighlight', channel: 'r', correctorType: 1 },
1070
+ [LOG_WHEELS.HIGHLIGHT_G]: { control: 'logHighlight', channel: 'g', correctorType: 1 },
1071
+ [LOG_WHEELS.HIGHLIGHT_B]: { control: 'logHighlight', channel: 'b', correctorType: 1 },
1072
+
1073
+ // Hue / Saturation (Primary corrector)
1074
+ [HUE.HUE_ROTATE]: { control: 'hueRotate', channel: 'master', correctorType: 1 },
1075
+ [HUE.SATURATION]: { control: 'saturation', channel: 'primary', correctorType: 1 },
1076
+
1077
+ // Luma vs Saturation
1078
+ [LUM_MIX.PARAM_1]: { control: 'lumMix', channel: 'param1', correctorType: 5 },
1079
+ [LUM_MIX.PARAM_2]: { control: 'lumMix', channel: 'param2', correctorType: 5 },
1080
+ [LUM_MIX.PARAM_3]: { control: 'lumMix', channel: 'param3', correctorType: 5 },
1081
+ [LUM_MIX.PARAM_4]: { control: 'lumMix', channel: 'param4', correctorType: 5 },
1082
+ [LUM_MIX.PARAM_5]: { control: 'lumMix', channel: 'param5', correctorType: 5 },
1083
+ [LUM_MIX.PARAM_6]: { control: 'lumMix', channel: 'param6', correctorType: 5 },
1084
+ [LUM_MIX.PARAM_7]: { control: 'lumMix', channel: 'param7', correctorType: 5 },
1085
+ [LUM_MIX.PARAM_8]: { control: 'lumMix', channel: 'param8', correctorType: 5 },
1086
+ [LUM_MIX.PARAM_9]: { control: 'lumMix', channel: 'param9', correctorType: 5 },
1087
+ [LUM_MIX.PARAM_10]: { control: 'lumMix', channel: 'param10', correctorType: 5 },
1088
+ [LUM_MIX.PARAM_11]: { control: 'lumMix', channel: 'param11', correctorType: 5 },
1089
+
1090
+ // Saturation vs Saturation
1091
+ [SAT_VS_SAT.PARAM_1]: { control: 'satVsSat', channel: 'param1', correctorType: 3 },
1092
+ [SAT_VS_SAT.PARAM_2]: { control: 'satVsSat', channel: 'param2', correctorType: 3 },
1093
+ [SAT_VS_SAT.PARAM_3]: { control: 'satVsSat', channel: 'param3', correctorType: 3 },
1094
+ [SAT_VS_SAT.PARAM_4]: { control: 'satVsSat', channel: 'param4', correctorType: 3 },
1095
+ [SAT_VS_SAT.PARAM_5]: { control: 'satVsSat', channel: 'param5', correctorType: 3 },
1096
+ [SAT_VS_SAT.PARAM_6]: { control: 'satVsSat', channel: 'param6', correctorType: 3 },
1097
+ [SAT_VS_SAT.PARAM_7]: { control: 'satVsSat', channel: 'param7', correctorType: 3 },
1098
+
1099
+ // Node LUT reference (Primary corrector ct1) — the value envelopes are read by extract-lut-refs.js
1100
+ // (LUT_PATH carries the basename in F5); named here so the main param path doesn't report unknown_.
1101
+ [NODE_LUT_REF.SLOT_META]: { control: 'nodeLut', channel: 'slotMeta', correctorType: 1, note: 'varint slot/kind (e.g. 6)' },
1102
+ [NODE_LUT_REF.LUT_PATH]: { control: 'nodeLut', channel: 'lutPath', correctorType: 1, nested: true, note: 'LUT basename/path in value-envelope F5' },
1103
+
1104
+ // Color Warper (chroma warp, Primary corrector ct1) — pins live in 0x86000138 (decoded
1105
+ // into colorWarper.pin<N>.* by decodeColorWarperPins); the three flags decode as scalars.
1106
+ [COLOR_WARPER.MODE_FLAG]: { control: 'colorWarper', channel: 'modeFlag', correctorType: 1 },
1107
+ [COLOR_WARPER.CONFIG_A]: { control: 'colorWarper', channel: 'configA', correctorType: 1 },
1108
+ [COLOR_WARPER.CONFIG_B]: { control: 'colorWarper', channel: 'configB', correctorType: 1 },
1109
+ [COLOR_WARPER.PINS]: { control: 'colorWarper', channel: 'pins', correctorType: 1, nested: true, note: 'F2.F27.F1[] chroma-warp pin list' },
1110
+
1111
+ // Gradient window opacity — collision-free (0x08F00011 isn't used by SAT_VS_SAT). The other
1112
+ // gradient params collide with SAT_VS_SAT (see GRADIENT_WINDOW note) and need ct-aware naming.
1113
+ [GRADIENT_WINDOW.OPACITY]: { control: 'gradientWindow', channel: 'opacity', correctorType: 65554, note: 'scale /100' },
1114
+ [GRADIENT_WINDOW.MATRIX]: { control: 'gradientWindow', channel: 'matrix', correctorType: 65554, note: 'structural: F10 = row-major 3×3 matrix (identity default)' },
1115
+
1116
+ // HDR Global
1117
+ [HDR_ZONE.BLACK_OFFSET]: { control: 'hdrBlackOffset', channel: 'master', correctorType: 1 },
1118
+
1119
+ // HDR Zone (nested protobuf structure - see HDR_ZONE docs)
1120
+ [HDR_ZONE.ZONE_ADJUSTMENTS]: { control: 'hdrZone', channel: 'adjustments', correctorType: 1, nested: true },
1121
+ [HDR_ZONE.ZONE_DEFINITIONS]: { control: 'hdrZone', channel: 'definitions', correctorType: 1, nested: true },
1122
+ [HDR_ZONE.ZONE_METADATA]: { control: 'hdrZone', channel: 'metadata', correctorType: 1 },
1123
+ [HDR_ZONE.PARAM_1]: { control: 'hdrZone', channel: 'param1', correctorType: 9 },
1124
+
1125
+ // Curves (legacy IDs from Type 18 corrector — may be alternate encoding)
1126
+ // Key palette (ct9) + Motion Effects (ct15) — live-measured 2026-07-02; the old
1127
+ // curves.param* (ct18) labels for these ids were an unvalidated legacy claim.
1128
+ [KEY_PALETTE.INPUT_GAIN]: { control: 'key', channel: 'inputGain', correctorType: 9 },
1129
+ [KEY_PALETTE.INPUT_OFFSET]: { control: 'key', channel: 'inputOffset', correctorType: 9 },
1130
+ [KEY_PALETTE.OUTPUT_GAIN]: { control: 'key', channel: 'outputGain', correctorType: 9 },
1131
+ [KEY_PALETTE.OUTPUT_OFFSET]: { control: 'key', channel: 'outputOffset', correctorType: 9 },
1132
+ [MOTION_EFFECTS.SPATIAL_LUMA]: { control: 'motionEffects', channel: 'spatialLuma', correctorType: 15 },
1133
+ [MOTION_EFFECTS.SPATIAL_CHROMA]: { control: 'motionEffects', channel: 'spatialChroma', correctorType: 15 },
1134
+ [MOTION_EFFECTS.SPATIAL_BLEND]: { control: 'motionEffects', channel: 'spatialBlend', correctorType: 15 },
1135
+ [MOTION_EFFECTS.FRAMES_FLAG]: { control: 'motionEffects', channel: 'framesFlag', correctorType: 15, note: 'varint; observed {F2:4} at UI frames 2' },
1136
+ [MOTION_EFFECTS.TEMPORAL_MOTION]: { control: 'motionEffects', channel: 'temporalMotion', correctorType: 15, note: 'stored = 0.28×UI + 2.0 (three-point panel fit 2026-07-03: 35→11.8, 60→18.8, 80→24.4)' },
1137
+ [MOTION_EFFECTS.TEMPORAL_LUMA]: { control: 'motionEffects', channel: 'temporalLuma', correctorType: 15 },
1138
+ [MOTION_EFFECTS.TEMPORAL_CHROMA]: { control: 'motionEffects', channel: 'temporalChroma', correctorType: 15 },
1139
+ [MOTION_EFFECTS.TEMPORAL_BLEND]: { control: 'motionEffects', channel: 'temporalBlend', correctorType: 15 },
1140
+ [MOTION_EFFECTS.MOTION_BLUR]: { control: 'motionEffects', channel: 'motionBlur', correctorType: 15, note: 'stored = 0.0099×UI (panel fit 2026-07-03: 50→0.495, 25→0.2475; the old 0.4→0.0044 point was UI 0.44)' },
1141
+ [CURVES.PARAM_6]: { control: 'motionEffects', channel: 'unk08', correctorType: 15 },
1142
+ [CURVES.PARAM_7]: { control: 'motionEffects', channel: 'unk09', correctorType: 15 },
1143
+ [CURVES.PARAM_12]: { control: 'motionEffects', channel: 'unk12', correctorType: 15 },
1144
+ [CURVES.PARAM_13]: { control: 'motionEffects', channel: 'unk13', correctorType: 15 },
1145
+ // Blur palette (ct1) — live-measured 2026-07-02 (see BLUR_PALETTE block for scales).
1146
+ [BLUR_PALETTE.RADIUS_R]: { control: 'blur', channel: 'radiusR', correctorType: 1, note: 'stored = (UI−0.5)×2' },
1147
+ [BLUR_PALETTE.RADIUS_G]: { control: 'blur', channel: 'radiusG', correctorType: 1, note: 'stored = (UI−0.5)×2' },
1148
+ [BLUR_PALETTE.RADIUS_B]: { control: 'blur', channel: 'radiusB', correctorType: 1, note: 'stored = (UI−0.5)×2' },
1149
+ [BLUR_PALETTE.HV_RATIO_R]: { control: 'blur', channel: 'hvRatioR', correctorType: 1, note: 'stored = (UI−0.5)×2' },
1150
+ [BLUR_PALETTE.HV_RATIO_G]: { control: 'blur', channel: 'hvRatioG', correctorType: 1, note: 'stored = (UI−0.5)×2' },
1151
+ [BLUR_PALETTE.HV_RATIO_B]: { control: 'blur', channel: 'hvRatioB', correctorType: 1, note: 'stored = (UI−0.5)×2' },
1152
+ [BLUR_PALETTE.SCALING_R]: { control: 'blur', channel: 'scalingR', correctorType: 1 },
1153
+ [BLUR_PALETTE.SCALING_G]: { control: 'blur', channel: 'scalingG', correctorType: 1 },
1154
+ [BLUR_PALETTE.SCALING_B]: { control: 'blur', channel: 'scalingB', correctorType: 1 },
1155
+
1156
+ // RGB Mixer (Primary corrector — trained 2026-03-17)
1157
+ [RGB_MIXER.RR]: { control: 'rgbMixer', channel: 'rr', correctorType: 1 },
1158
+ [RGB_MIXER.GR]: { control: 'rgbMixer', channel: 'gr', correctorType: 1 },
1159
+ [RGB_MIXER.BR]: { control: 'rgbMixer', channel: 'br', correctorType: 1 },
1160
+ [RGB_MIXER.RG]: { control: 'rgbMixer', channel: 'rg', correctorType: 1 },
1161
+ [RGB_MIXER.GG]: { control: 'rgbMixer', channel: 'gg', correctorType: 1 },
1162
+ [RGB_MIXER.BG]: { control: 'rgbMixer', channel: 'bg', correctorType: 1 },
1163
+ [RGB_MIXER.RB]: { control: 'rgbMixer', channel: 'rb', correctorType: 1 },
1164
+ [RGB_MIXER.GB]: { control: 'rgbMixer', channel: 'gb', correctorType: 1 },
1165
+ [RGB_MIXER.BB]: { control: 'rgbMixer', channel: 'bb', correctorType: 1 },
1166
+ [RGB_MIXER.PRESERVE_LUMINANCE]: { control: 'rgbMixer', channel: 'preserveLuminance', correctorType: 1, nested: true },
1167
+
1168
+ // Custom Curves YRGB (Primary corrector — trained 2026-03-17)
1169
+ [CUSTOM_CURVES.Y_META]: { control: 'customCurves', channel: 'yMeta', correctorType: 1, nested: true },
1170
+ [CUSTOM_CURVES.R_META]: { control: 'customCurves', channel: 'rMeta', correctorType: 1, nested: true },
1171
+ [CUSTOM_CURVES.G_META]: { control: 'customCurves', channel: 'gMeta', correctorType: 1, nested: true },
1172
+ [CUSTOM_CURVES.B_META]: { control: 'customCurves', channel: 'bMeta', correctorType: 1, nested: true },
1173
+ [CUSTOM_CURVES.Y_SPLINE]: { control: 'customCurves', channel: 'ySpline', correctorType: 1, nested: true },
1174
+ [CUSTOM_CURVES.R_SPLINE]: { control: 'customCurves', channel: 'rSpline', correctorType: 1, nested: true },
1175
+ [CUSTOM_CURVES.G_SPLINE]: { control: 'customCurves', channel: 'gSpline', correctorType: 1, nested: true },
1176
+ [CUSTOM_CURVES.B_SPLINE]: { control: 'customCurves', channel: 'bSpline', correctorType: 1, nested: true },
1177
+
1178
+ // HSL Curves (Primary corrector — trained 2026-03-17)
1179
+ [HSL_CURVES.COMMON_FLAG]: { control: 'hslCurves', channel: 'commonFlag', correctorType: 1, nested: true },
1180
+ [HSL_CURVES.HUE_VS_HUE_META]: { control: 'hslCurves', channel: 'hueVsHueMeta', correctorType: 1, nested: true },
1181
+ [HSL_CURVES.HUE_VS_SAT_META]: { control: 'hslCurves', channel: 'hueVsSatMeta', correctorType: 1, nested: true },
1182
+ [HSL_CURVES.HUE_VS_LUM_META]: { control: 'hslCurves', channel: 'hueVsLumMeta', correctorType: 1, nested: true },
1183
+ [HSL_CURVES.LUM_VS_SAT_META]: { control: 'hslCurves', channel: 'lumVsSatMeta', correctorType: 1, nested: true },
1184
+ [HSL_CURVES.SAT_VS_SAT_META]: { control: 'hslCurves', channel: 'satVsSatMeta', correctorType: 1, nested: true },
1185
+ [HSL_CURVES.SAT_VS_LUM_META]: { control: 'hslCurves', channel: 'satVsLumMeta', correctorType: 1, nested: true },
1186
+ [HSL_CURVES.HUE_VS_LUM_EXTRA]: { control: 'hslCurves', channel: 'hueVsLumExtra', correctorType: 1, nested: true },
1187
+ [HSL_CURVES.HUE_VS_HUE_SPLINE]: { control: 'hslCurves', channel: 'hueVsHueSpline', correctorType: 1, nested: true },
1188
+ [HSL_CURVES.HUE_VS_SAT_SPLINE]: { control: 'hslCurves', channel: 'hueVsSatSpline', correctorType: 1, nested: true },
1189
+ [HSL_CURVES.HUE_VS_LUM_SPLINE]: { control: 'hslCurves', channel: 'hueVsLumSpline', correctorType: 1, nested: true },
1190
+ [HSL_CURVES.LUM_VS_SAT_SPLINE]: { control: 'hslCurves', channel: 'lumVsSatSpline', correctorType: 1, nested: true },
1191
+ [HSL_CURVES.SAT_VS_SAT_SPLINE]: { control: 'hslCurves', channel: 'satVsSatSpline', correctorType: 1, nested: true },
1192
+ [HSL_CURVES.SAT_VS_LUM_SPLINE]: { control: 'hslCurves', channel: 'satVsLumSpline', correctorType: 1, nested: true },
1193
+
1194
+ // Additional controls (trained 2026-03-17)
1195
+ [ADDITIONAL.LUM_MIX_SLIDER]: { control: 'lumMixSlider', channel: 'master', correctorType: 1 },
1196
+ [ADDITIONAL.HIGHLIGHTS]: { control: 'highlights', channel: 'master', correctorType: 1 },
1197
+ [ADDITIONAL.SHADOWS]: { control: 'shadows', channel: 'master', correctorType: 1 },
1198
+
1199
+ // ColorSlice global controls — CALIBRATED 2026-06-22 (automated harness, design note §16a).
1200
+ [COLORSLICE.DENSITY]: { control: 'colorSlice', channel: 'density', correctorType: 1 },
1201
+ [COLORSLICE.DENSITY_DEPTH]: { control: 'colorSlice', channel: 'densityDepth', correctorType: 1 },
1202
+ [COLORSLICE.SAT]: { control: 'colorSlice', channel: 'sat', correctorType: 1 },
1203
+ [COLORSLICE.SAT_BALANCE]: { control: 'colorSlice', channel: 'satBalance', correctorType: 1 },
1204
+ [COLORSLICE.SAT_DEPTH]: { control: 'colorSlice', channel: 'satDepth', correctorType: 1 },
1205
+ [COLORSLICE.HUE]: { control: 'colorSlice', channel: 'hue', correctorType: 1, scale: 'negated' },
1206
+ };
1207
+
1208
+ /**
1209
+ * Get parameter metadata by ID
1210
+ * @param {number} paramId - Parameter ID
1211
+ * @returns {object|null} Parameter metadata or null if unknown
1212
+ */
1213
+ function getParamInfo(paramId) {
1214
+ return PARAM_ID_MAP[paramId] || null;
1215
+ }
1216
+
1217
+ /**
1218
+ * Get all parameter IDs for a control type
1219
+ * @param {string} control - Control name (e.g., 'lift', 'gain', 'temperature')
1220
+ * @returns {number[]} Array of parameter IDs
1221
+ */
1222
+ function getParamIdsForControl(control) {
1223
+ return Object.entries(PARAM_ID_MAP)
1224
+ .filter(([, meta]) => meta.control === control)
1225
+ .map(([id]) => Number(id));
1226
+ }
1227
+
1228
+ /**
1229
+ * Check if a parameter ID is known
1230
+ * @param {number} paramId - Parameter ID
1231
+ * @returns {boolean}
1232
+ */
1233
+ function isKnownParam(paramId) {
1234
+ return paramId in PARAM_ID_MAP;
1235
+ }
1236
+
1237
+ /**
1238
+ * Get total count of known parameters
1239
+ * @returns {number}
1240
+ */
1241
+ function getKnownParamCount() {
1242
+ return Object.keys(PARAM_ID_MAP).length;
1243
+ }
1244
+
1245
+ module.exports = {
1246
+ // Parameter ID constants — Primary Corrector
1247
+ LIFT,
1248
+ GAIN,
1249
+ GAMMA,
1250
+ OFFSET,
1251
+ SATURATION,
1252
+ TEMP_TINT,
1253
+ CONTRAST,
1254
+ LOG_WHEELS,
1255
+ HUE,
1256
+ LUM_MIX,
1257
+ SAT_VS_SAT,
1258
+ HDR_ZONE,
1259
+ CURVES,
1260
+ BLUR_PALETTE,
1261
+ KEY_PALETTE,
1262
+ MOTION_EFFECTS,
1263
+ RGB_MIXER,
1264
+ CUSTOM_CURVES,
1265
+ HSL_CURVES,
1266
+ ADDITIONAL,
1267
+
1268
+ // Secondary Correction — trained 2026-03-16
1269
+ HSL_QUALIFIER,
1270
+ MATTE_FINESSE,
1271
+ POWER_WINDOWS,
1272
+
1273
+ // Per-node attachments — trained 2026-06-19 (P5.1)
1274
+ NODE_LUT_REF,
1275
+
1276
+ // Spatial / Effect tools — trained 2026-03-16 + 2026-03-22
1277
+ GRADIENT_WINDOW,
1278
+ POLYGON_WINDOW,
1279
+ NODE_SIZING,
1280
+ COLOR_WARPER,
1281
+ COLORSLICE,
1282
+ RESOLVEFX,
1283
+
1284
+ // Unified map
1285
+ PARAM_ID_MAP,
1286
+
1287
+ // Utility functions
1288
+ getParamInfo,
1289
+ getParamIdsForControl,
1290
+ isKnownParam,
1291
+ getKnownParamCount,
1292
+ };