@photivra/engine 2.17.0 → 2.19.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 (288) hide show
  1. package/CHANGELOG.md +116 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/dist/camera/sensor-equivalence.d.ts +156 -0
  6. package/dist/camera/sensor-equivalence.js +208 -0
  7. package/dist/camera/sensor-equivalence.js.map +1 -0
  8. package/dist/capture/focus-control.js +2 -75
  9. package/dist/capture/focus-control.js.map +1 -1
  10. package/dist/capture/native-environment-lean.d.ts +1 -0
  11. package/dist/capture/native-environment-lean.js +1 -1
  12. package/dist/capture/native-environment-lean.js.map +1 -1
  13. package/dist/capture/native-environment-optical-stage.d.ts +1 -0
  14. package/dist/capture/native-environment-optical-stage.js +2 -5
  15. package/dist/capture/native-environment-optical-stage.js.map +1 -1
  16. package/dist/capture/native-environment-raw.js +1 -5
  17. package/dist/capture/native-environment-raw.js.map +1 -1
  18. package/dist/capture/native-environment-tabulated.d.ts +5 -0
  19. package/dist/capture/native-environment-tabulated.js +1 -1
  20. package/dist/capture/native-environment-tabulated.js.map +1 -1
  21. package/dist/capture/release-sequence.js +2 -47
  22. package/dist/capture/release-sequence.js.map +1 -1
  23. package/dist/color/white-balance.d.ts +2 -0
  24. package/dist/color/white-balance.js +3 -56
  25. package/dist/color/white-balance.js.map +1 -1
  26. package/dist/composition/image-formation-plan.d.ts +1 -0
  27. package/dist/composition/image-formation-plan.js +3 -49
  28. package/dist/composition/image-formation-plan.js.map +1 -1
  29. package/dist/core/evidence-provenance.js +1 -16
  30. package/dist/core/evidence-provenance.js.map +1 -1
  31. package/dist/core/record-validation.d.ts +54 -0
  32. package/dist/core/record-validation.js +176 -0
  33. package/dist/core/record-validation.js.map +1 -1
  34. package/dist/core/scientific-assurance.js +1 -18
  35. package/dist/core/scientific-assurance.js.map +1 -1
  36. package/dist/core/shared-helpers.d.ts +33 -0
  37. package/dist/core/shared-helpers.js +34 -0
  38. package/dist/core/shared-helpers.js.map +1 -0
  39. package/dist/core/spectral-composition.js +1 -36
  40. package/dist/core/spectral-composition.js.map +1 -1
  41. package/dist/core/spectral.js +1 -19
  42. package/dist/core/spectral.js.map +1 -1
  43. package/dist/core/version.d.ts +1 -1
  44. package/dist/core/version.js +1 -1
  45. package/dist/core/version.js.map +1 -1
  46. package/dist/equipment/exposure-capabilities.d.ts +1 -0
  47. package/dist/equipment/exposure-capabilities.js +2 -36
  48. package/dist/equipment/exposure-capabilities.js.map +1 -1
  49. package/dist/equipment/ideal-lens.d.ts +25 -0
  50. package/dist/equipment/ideal-lens.js +21 -0
  51. package/dist/equipment/ideal-lens.js.map +1 -0
  52. package/dist/equipment/iso-capabilities.js +2 -49
  53. package/dist/equipment/iso-capabilities.js.map +1 -1
  54. package/dist/equipment/metering-capabilities.js +1 -26
  55. package/dist/equipment/metering-capabilities.js.map +1 -1
  56. package/dist/equipment/release-capabilities.js +1 -53
  57. package/dist/equipment/release-capabilities.js.map +1 -1
  58. package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
  59. package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
  60. package/dist/exposure/exposure-duration-control.js +1 -16
  61. package/dist/exposure/exposure-duration-control.js.map +1 -1
  62. package/dist/exposure/exposure-mode-resolver.js +1 -17
  63. package/dist/exposure/exposure-mode-resolver.js.map +1 -1
  64. package/dist/exposure/filtered-exposure-time.d.ts +93 -0
  65. package/dist/exposure/filtered-exposure-time.js +129 -0
  66. package/dist/exposure/filtered-exposure-time.js.map +1 -0
  67. package/dist/exposure/flash-ttl.d.ts +1 -0
  68. package/dist/exposure/flash-ttl.js +1 -1
  69. package/dist/exposure/flash-ttl.js.map +1 -1
  70. package/dist/exposure/flash.js +1 -49
  71. package/dist/exposure/flash.js.map +1 -1
  72. package/dist/exposure/metering-scene-radiance.js +1 -25
  73. package/dist/exposure/metering-scene-radiance.js.map +1 -1
  74. package/dist/exposure/metering-target.js +1 -30
  75. package/dist/exposure/metering-target.js.map +1 -1
  76. package/dist/exposure/metering-temporal.js +1 -8
  77. package/dist/exposure/metering-temporal.js.map +1 -1
  78. package/dist/exposure/metering.js +1 -72
  79. package/dist/exposure/metering.js.map +1 -1
  80. package/dist/exposure/program-line.js +1 -45
  81. package/dist/exposure/program-line.js.map +1 -1
  82. package/dist/facade/catalogue-lens-signal.d.ts +94 -0
  83. package/dist/facade/catalogue-lens-signal.js +362 -0
  84. package/dist/facade/catalogue-lens-signal.js.map +1 -0
  85. package/dist/facade/defocus-image-space-provider.js +5 -2
  86. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  87. package/dist/facade/develop-joined-parts.d.ts +29 -0
  88. package/dist/facade/develop-joined-parts.js +33 -0
  89. package/dist/facade/develop-joined-parts.js.map +1 -0
  90. package/dist/facade/display-view-lens-signal.d.ts +32 -1
  91. package/dist/facade/display-view-lens-signal.js +85 -10
  92. package/dist/facade/display-view-lens-signal.js.map +1 -1
  93. package/dist/facade/expected-signal-setup.d.ts +8 -0
  94. package/dist/facade/expected-signal-setup.js +7 -0
  95. package/dist/facade/expected-signal-setup.js.map +1 -1
  96. package/dist/facade/expected-signal.d.ts +5 -0
  97. package/dist/facade/expected-signal.js +5 -1
  98. package/dist/facade/expected-signal.js.map +1 -1
  99. package/dist/facade/generic-lens-capture.d.ts +5 -2
  100. package/dist/facade/generic-lens-capture.js +5 -2
  101. package/dist/facade/generic-lens-capture.js.map +1 -1
  102. package/dist/facade/simulate-capture.d.ts +67 -8
  103. package/dist/facade/simulate-capture.js +262 -126
  104. package/dist/facade/simulate-capture.js.map +1 -1
  105. package/dist/facade/simulate-display-view.js +1 -1
  106. package/dist/facade/simulate-display-view.js.map +1 -1
  107. package/dist/gpu/chart-composite-gpu.js +1 -3
  108. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  109. package/dist/gpu/chart-radiance-gpu.js +1 -5
  110. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  111. package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
  112. package/dist/gpu/display-view-quality-gpu.js +4 -8
  113. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  114. package/dist/gpu/display-view-speed-gpu.js +3 -25
  115. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  116. package/dist/gpu/sensor-stage-gpu.js +1 -5
  117. package/dist/gpu/sensor-stage-gpu.js.map +1 -1
  118. package/dist/gpu/webgpu-runtime.d.ts +2 -0
  119. package/dist/gpu/webgpu-runtime.js +3 -0
  120. package/dist/gpu/webgpu-runtime.js.map +1 -1
  121. package/dist/index.d.ts +6 -1
  122. package/dist/index.js +5 -0
  123. package/dist/index.js.map +1 -1
  124. package/dist/motion/camera-rotation.js +1 -6
  125. package/dist/motion/camera-rotation.js.map +1 -1
  126. package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
  127. package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
  128. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  129. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
  130. package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
  131. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  132. package/dist/motion/capture-rotation-trajectory.js +2 -17
  133. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  134. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
  135. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
  136. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  137. package/dist/motion/extended-object-projection.js +5 -40
  138. package/dist/motion/extended-object-projection.js.map +1 -1
  139. package/dist/optics/atmospheric-haze.js +1 -7
  140. package/dist/optics/atmospheric-haze.js.map +1 -1
  141. package/dist/optics/brown-conrady-distortion.js +1 -7
  142. package/dist/optics/brown-conrady-distortion.js.map +1 -1
  143. package/dist/optics/complex-pupil-psf.d.ts +1 -0
  144. package/dist/optics/complex-pupil-psf.js +2 -84
  145. package/dist/optics/complex-pupil-psf.js.map +1 -1
  146. package/dist/optics/focus-state.js +1 -11
  147. package/dist/optics/focus-state.js.map +1 -1
  148. package/dist/optics/front-of-lens-filter.d.ts +5 -0
  149. package/dist/optics/front-of-lens-filter.js +3 -65
  150. package/dist/optics/front-of-lens-filter.js.map +1 -1
  151. package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
  152. package/dist/optics/generic-nd-filter-presets.js +48 -0
  153. package/dist/optics/generic-nd-filter-presets.js.map +1 -0
  154. package/dist/optics/illumination-vignetting.js +1 -6
  155. package/dist/optics/illumination-vignetting.js.map +1 -1
  156. package/dist/optics/lens-psf-profile.d.ts +4 -1
  157. package/dist/optics/lens-psf-profile.js +12 -111
  158. package/dist/optics/lens-psf-profile.js.map +1 -1
  159. package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
  160. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
  161. package/dist/optics/pupil-vignetting.js +1 -7
  162. package/dist/optics/pupil-vignetting.js.map +1 -1
  163. package/dist/optics/radial-distortion.js +1 -6
  164. package/dist/optics/radial-distortion.js.map +1 -1
  165. package/dist/optics/scene-to-sensor-irradiance.js +4 -96
  166. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  167. package/dist/optics/stray-light.d.ts +1 -0
  168. package/dist/optics/stray-light.js +1 -1
  169. package/dist/optics/stray-light.js.map +1 -1
  170. package/dist/optics/zernike-wavefront.js +1 -7
  171. package/dist/optics/zernike-wavefront.js.map +1 -1
  172. package/dist/output/capture-geometry.js +1 -8
  173. package/dist/output/capture-geometry.js.map +1 -1
  174. package/dist/output/developed-lens-corrections.d.ts +62 -0
  175. package/dist/output/developed-lens-corrections.js +135 -0
  176. package/dist/output/developed-lens-corrections.js.map +1 -0
  177. package/dist/output/generic-lens-corrections.d.ts +2 -6
  178. package/dist/output/generic-lens-corrections.js +3 -6
  179. package/dist/output/generic-lens-corrections.js.map +1 -1
  180. package/dist/output/geometric-transforms.js +1 -4
  181. package/dist/output/geometric-transforms.js.map +1 -1
  182. package/dist/output/native-capture-sdr.d.ts +2 -2
  183. package/dist/output/native-capture-sdr.js +3 -2
  184. package/dist/output/native-capture-sdr.js.map +1 -1
  185. package/dist/processing/development-detail.d.ts +29 -0
  186. package/dist/processing/development-detail.js +128 -107
  187. package/dist/processing/development-detail.js.map +1 -1
  188. package/dist/schema/illumination-temporal.js +3 -72
  189. package/dist/schema/illumination-temporal.js.map +1 -1
  190. package/dist/schema/illumination.d.ts +1 -0
  191. package/dist/schema/illumination.js +2 -65
  192. package/dist/schema/illumination.js.map +1 -1
  193. package/dist/schema/scene-radiance-temporal.js +2 -14
  194. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  195. package/dist/schema/scene-radiance.js +2 -60
  196. package/dist/schema/scene-radiance.js.map +1 -1
  197. package/dist/schema/validation.d.ts +2 -0
  198. package/dist/schema/validation.js +2 -17
  199. package/dist/schema/validation.js.map +1 -1
  200. package/dist/sensor/accumulated-charge.js +2 -59
  201. package/dist/sensor/accumulated-charge.js.map +1 -1
  202. package/dist/sensor/architecture.js +1 -16
  203. package/dist/sensor/architecture.js.map +1 -1
  204. package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
  205. package/dist/sensor/camera-saturation-capacity.js +3 -55
  206. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  207. package/dist/sensor/capture-color-sampling-binding.js +1 -26
  208. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  209. package/dist/sensor/capture-mode-timing.js +1 -39
  210. package/dist/sensor/capture-mode-timing.js.map +1 -1
  211. package/dist/sensor/capture-mode.js +1 -23
  212. package/dist/sensor/capture-mode.js.map +1 -1
  213. package/dist/sensor/color-sampling.js +1 -26
  214. package/dist/sensor/color-sampling.js.map +1 -1
  215. package/dist/sensor/constant-rate-temporal-integration.js +2 -46
  216. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  217. package/dist/sensor/dark-current.js +2 -45
  218. package/dist/sensor/dark-current.js.map +1 -1
  219. package/dist/sensor/eqe-electron-rate.js +2 -35
  220. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  221. package/dist/sensor/exposure-window.d.ts +5 -0
  222. package/dist/sensor/exposure-window.js +7 -22
  223. package/dist/sensor/exposure-window.js.map +1 -1
  224. package/dist/sensor/iso-gain.js +1 -7
  225. package/dist/sensor/iso-gain.js.map +1 -1
  226. package/dist/sensor/iso-signal-chain.js +1 -43
  227. package/dist/sensor/iso-signal-chain.js.map +1 -1
  228. package/dist/sensor/optical-stack.js +1 -25
  229. package/dist/sensor/optical-stack.js.map +1 -1
  230. package/dist/sensor/photon-energy.js +1 -26
  231. package/dist/sensor/photon-energy.js.map +1 -1
  232. package/dist/sensor/physical-charge-capacity.js +3 -77
  233. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  234. package/dist/sensor/radiometry-readiness.js +2 -23
  235. package/dist/sensor/radiometry-readiness.js.map +1 -1
  236. package/dist/sensor/raw-readout.d.ts +3 -0
  237. package/dist/sensor/raw-readout.js +4 -66
  238. package/dist/sensor/raw-readout.js.map +1 -1
  239. package/dist/sensor/raw-reconstruction.js +2 -64
  240. package/dist/sensor/raw-reconstruction.js.map +1 -1
  241. package/dist/sensor/readout-exposure-linkage.js +1 -9
  242. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  243. package/dist/sensor/readout-timing.js +3 -57
  244. package/dist/sensor/readout-timing.js.map +1 -1
  245. package/dist/sensor/response-application-compatibility.d.ts +2 -0
  246. package/dist/sensor/response-application-compatibility.js +3 -29
  247. package/dist/sensor/response-application-compatibility.js.map +1 -1
  248. package/dist/sensor/response-operating-range.d.ts +1 -0
  249. package/dist/sensor/response-operating-range.js +3 -79
  250. package/dist/sensor/response-operating-range.js.map +1 -1
  251. package/dist/sensor/responsivity-photocurrent.js +4 -108
  252. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  253. package/dist/sensor/sampling-aperture.js +1 -25
  254. package/dist/sensor/sampling-aperture.js.map +1 -1
  255. package/dist/sensor/spatial-sample-reduction.js +2 -19
  256. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  257. package/dist/sensor/spatial-sampling-quadrature.js +1 -3
  258. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  259. package/dist/sensor/spatio-spectral-reduction.js +1 -18
  260. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  261. package/dist/sensor/spectral-coverage.d.ts +10 -1
  262. package/dist/sensor/spectral-coverage.js +1 -1
  263. package/dist/sensor/spectral-coverage.js.map +1 -1
  264. package/dist/sensor/spectral-quadrature.js +2 -35
  265. package/dist/sensor/spectral-quadrature.js.map +1 -1
  266. package/dist/sensor/spectral-response.js +1 -47
  267. package/dist/sensor/spectral-response.js.map +1 -1
  268. package/dist/stabilization/camera-shake.js +1 -6
  269. package/dist/stabilization/camera-shake.js.map +1 -1
  270. package/dist/stabilization/system.js +2 -80
  271. package/dist/stabilization/system.js.map +1 -1
  272. package/docs/AGENT_GUIDE.md +4 -0
  273. package/docs/API_REFERENCE.md +69 -2
  274. package/docs/QUICK_START.md +136 -6
  275. package/docs/USAGE.md +89 -3
  276. package/docs/api/camera-sensor-equivalence.md +209 -0
  277. package/docs/api/core-version.md +1 -1
  278. package/docs/api/equipment-ideal-lens.md +26 -0
  279. package/docs/api/exports.json +118 -3
  280. package/docs/api/exposure-filtered-exposure-time.md +105 -0
  281. package/docs/api/facade-develop-joined-parts.md +32 -0
  282. package/docs/api/facade-simulate-capture.md +62 -8
  283. package/docs/api/optics-generic-nd-filter-presets.md +34 -0
  284. package/docs/api/optics-lens-psf-profile.md +3 -1
  285. package/docs/api/output-developed-lens-corrections.md +12 -0
  286. package/docs/api/output-generic-lens-corrections.md +0 -9
  287. package/llms.txt +3 -0
  288. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"response-operating-range.js","sourceRoot":"","sources":["../../src/sensor/response-operating-range.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;GAUG;AAEH,OAAO,EACL,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EACL,iBAAiB,EAElB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAepE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AA2MjK,SAAS,aAAa,CACpB,KAAc,EACd,IAAY,EACZ,WAAqC;IAErC,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,qBAAqB,CAC7B,CAAC;IACJ,CAAC;IACD,IAAI,WAAW,KAAK,IAAI;QAAE,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACxE,OAAO,KAAsB,CAAC;AAChC,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc,EACd,IAAY;IAEZ,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EACzB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,8BAA8B,CACtC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,wBAAwB,CAC/B,KAAc,EACd,IAAY;IAEZ,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvB,KAAK,GAAG,CAAC,EACT,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,oDAAoD,CACvD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc,EACd,IAAY;IAEZ,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvB,KAAK,IAAI,CAAC,EACV,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,wCAAwC,CAC3C,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,0BAA0B,EAAE,IAAI,CAAC,CAAC;IAE7E,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,QAAQ,GACZ,wBAAwB,CACtB,MAAM,CAAC,QAAQ,EACf,IAAI,GAAG,WAAW,CACnB,CAAC;QACJ,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,QAAQ;YACR,KAAK,EAAE,qBAAqB,CAC1B,MAAM,CAAC,KAAK,EACZ,IAAI,GAAG,QAAQ,CAChB;SACF,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAChC,CAAC;QACD,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,UAAU,EAAE,qBAAqB,CAC/B,MAAM,CAAC,UAAU,EACjB,IAAI,GAAG,aAAa,CACrB;SACF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,mBAAmB,CAC3B,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAC/B,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,cAAc,EAAE,iCAAiC,EAAE,cAAc,CAAC,CAAC,CAAC;IAClG,MAAM,MAAM,GAER,EAAE,CAAC;IAEP,IACE,MAAM,CAAC,YAAY,KAAK,SAAS,EACjC,CAAC;QACD,IACE,OAAO,MAAM,CAAC,YAAY;YACxB,QAAQ;YACV,CAAC,MAAM,CAAC,QAAQ,CACd,MAAM,CAAC,YAAY,CACpB,EACD,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;gBACF,+BAA+B,CAClC,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,YAAY;YACjB,MAAM,CAAC,YAAY,CAAC;IACxB,CAAC;IAED,IACE,MAAM,CAAC,+BAA+B;QACtC,SAAS,EACT,CAAC;QACD,MAAM,KAAK,GACT,MAAM;aACH,+BAA+B,CAAC;QACrC,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvB,KAAK,GAAG,CAAC;YACT,KAAK,GAAG,EAAE,EACV,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;gBACF,oEAAoE,CACvE,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,+BAA+B;YACpC,KAAK,CAAC;IACV,CAAC;IAED,IACE,MAAM,CAAC,YAAY,KAAK,SAAS,EACjC,CAAC;QACD,IACE,MAAM,CAAC,YAAY;YACjB,aAAa;YACf,MAAM,CAAC,YAAY;gBACjB,aAAa,EACf,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;gBACF,2BAA2B,CAC9B,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,YAAY;YACjB,MAAM,CAAC,YAAY,CAAC;IACxB,CAAC;IAED,IACE,MAAM,CAAC,YAAY,KAAK,SAAS;QACjC,MAAM;aACH,+BAA+B;YAChC,SAAS;QACX,MAAM,CAAC,YAAY,KAAK,SAAS,EACjC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,uCAAuC,CAC1C,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,6BAA6B,CACpC,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,sBAAsB,EAAE,CAAC,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAEhJ,IACE,MAAM,CAAC,IAAI;QACT,sBAAsB,EACxB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,sBAAsB;SAC7B,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI,KAAK,mBAAmB,EACnC,CAAC;QACD,OAAO;YACL,IAAI,EAAE,mBAAmB;YACzB,UAAU,EACR,qBAAqB,CACnB,MAAM,CAAC,UAAU,EACjB,IAAI,GAAG,aAAa,CACrB;YACH,QAAQ,EAAE,iBAAiB,CACzB,MAAM,CAAC,QAAQ,EACf,IAAI,GAAG,WAAW,CACnB;SACF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,mBAAmB,CAC3B,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEvF,MAAM,gBAAgB,GACpB,wBAAwB,CACtB,MAAM,CAAC,gBAAgB,EACvB,IAAI,GAAG,mBAAmB,CAC3B,CAAC;IACJ,MAAM,gBAAgB,GACpB,qBAAqB,CACnB,MAAM,CAAC,gBAAgB,EACvB,IAAI,GAAG,mBAAmB,CAC3B,CAAC;IAEJ,IACE,gBAAgB;QAChB,gBAAgB,EAChB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,uDAAuD,CAC1D,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI;QACT,wDAAwD,EAC1D,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;YACxB,MAAM,IAAI,yBAAyB,CACjC,IAAI;gBACF,oBAAoB,CACvB,CAAC;QACJ,CAAC;QACD,OAAO;YACL,IAAI,EACF,wDAAwD;YAC1D,IAAI,EAAE,GAAG;YACT,gBAAgB;YAChB,gBAAgB;SACjB,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI;QACT,kDAAkD,EACpD,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,yBAAyB,CACjC,IAAI;gBACF,wBAAwB,CAC3B,CAAC;QACJ,CAAC;QACD,OAAO;YACL,IAAI,EACF,kDAAkD;YACpD,IAAI,EAAE,OAAO;YACb,gBAAgB;YAChB,gBAAgB;SACjB,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,mBAAmB,CAC3B,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CACnC,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC;IAE3G,IACE,MAAM,CAAC,eAAe,KAAK,KAAK;QAChC,MAAM,CAAC,eAAe;YACpB,QAAQ,EACV,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,6CAA6C,CAChD,CAAC;IACJ,CAAC;IAED,MAAM,iBAAiB,GACrB,qBAAqB,CACnB,MAAM,CAAC,iBAAiB,EACxB,IAAI,GAAG,oBAAoB,CAC5B,CAAC;IACJ,MAAM,iBAAiB,GACrB,qBAAqB,CACnB,MAAM,CAAC,iBAAiB,EACxB,IAAI,GAAG,oBAAoB,CAC5B,CAAC;IAEJ,IACE,iBAAiB;QACjB,iBAAiB,EACjB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,yDAAyD,CAC5D,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,WAAW;QAChB,mCAAmC,EACrC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,2DAA2D,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,eAAe,EACb,MAAM,CAAC,eAAe;QACxB,iBAAiB;QACjB,iBAAiB;QACjB,WAAW,EACT,mCAAmC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,kCAAkC,CAAC,CAAC,CAAC;IACnE,MAAM,gCAAgC,GACpC,wBAAwB,CACtB,MAAM;SACH,gCAAgC,EACnC,IAAI;QACF,mCAAmC,CACtC,CAAC;IAEJ,IACE,gCAAgC;QAC9B,CAAC,EACH,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,wEAAwE,CAC3E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,gCAAgC;KACjC,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAc;IAEd,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,2BAA2B;SAClC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAC1B,KAAK,EACL,iDAAiD,EAAE,IAAI,CACxD,CAAC;IACF,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,2BAA2B,EAAE,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAC,MAAM,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,EAAE,iDAAiD,CAAC,CAAC;IAElP,IACE,MAAM,CAAC,IAAI;QACT,2BAA2B,EAC7B,CAAC;QACD,OAAO;YACL,IAAI,EAAE,2BAA2B;SAClC,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI;QACT,kBAAkB,EACpB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,kEAAkE,CACnE,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,gBAAgB;QACrB,YAAY;QACd,MAAM,CAAC,gBAAgB;YACrB,eAAe,EACjB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,MAAM,yBAAyB,GAC7B,qBAAqB,CACnB,MAAM,CAAC,yBAAyB,EAChC,2EAA2E,CAC5E,CAAC;IACJ,MAAM,UAAU,GACd,MAAM,CAAC,UAAU,KAAK,SAAS;QAC7B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,qBAAqB,CACnB,MAAM,CAAC,UAAU,EACjB,4DAA4D,CAC7D,CAAC;IAER,IACE,MAAM,CAAC,gBAAgB;QACrB,eAAe;QACjB,UAAU,KAAK,SAAS,EACxB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,8FAA8F,CAC/F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,yBAAyB;QACzB,gBAAgB,EACd,MAAM,CAAC,gBAAgB;QACzB,QAAQ,EAAE,iBAAiB,CACzB,MAAM,CAAC,QAAQ,EACf,0DAA0D,CAC3D;QACD,GAAG,CAAC,UAAU,KAAK,SAAS;YAC1B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,KAAc;IAEd,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,iBAAiB;YACvB,UAAU,EACR,6DAA6D;SAChE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAC1B,KAAK,EACL,oDAAoD,EAAE,IAAI,CAC3D,CAAC;IACF,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,8CAA8C,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,EAAE,oDAAoD,CAAC,CAAC;IAExP,IACE,MAAM,CAAC,IAAI,KAAK,iBAAiB,EACjC,CAAC;QACD,OAAO;YACL,IAAI,EAAE,iBAAiB;YACvB,UAAU,EAAE,qBAAqB,CAC/B,MAAM,CAAC,UAAU,EACjB,+DAA+D,CAChE;SACF,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI;QACX,8CAA8C,EAC9C,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,qEAAqE,CACtE,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,gBAAgB;QACrB,YAAY;QACd,MAAM,CAAC,gBAAgB;YACrB,eAAe,EACjB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GACd,MAAM,CAAC,UAAU,KAAK,SAAS;QAC7B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,qBAAqB,CACnB,MAAM,CAAC,UAAU,EACjB,+DAA+D,CAChE,CAAC;IAER,IACE,MAAM,CAAC,gBAAgB;QACrB,eAAe;QACjB,UAAU,KAAK,SAAS,EACxB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EACF,8CAA8C;QAChD,gBAAgB,EACd,MAAM,CAAC,gBAAgB;QACzB,QAAQ,EAAE,iBAAiB,CACzB,MAAM,CAAC,QAAQ,EACf,6DAA6D,CAC9D;QACD,GAAG,CAAC,UAAU,KAAK,SAAS;YAC1B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;KACpB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wCAAwC,CACtD,KAAc;IAEd,MAAM,MAAM,GACV,aAAa,CACX,KAAK,EACL,8BAA8B,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,aAAa,EAAE,WAAW,EAAE,8BAA8B,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,oBAAoB,CAAC,CACnX,CAAC;IAEJ,IACE,MAAM,CAAC,aAAa,KAAK,OAAO,EAChC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,gBAAgB;QACrB,YAAY;QACd,MAAM,CAAC,gBAAgB;YACrB,eAAe,EACjB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,MAAM,mBAAmB,GACvB,MAAM,CAAC,mBAAmB;QAC1B,SAAS;QACP,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,wBAAwB,CACtB,MAAM,CAAC,mBAAmB,EAC1B,kDAAkD,CACnD,CAAC;IAER,MAAM,wBAAwB,GAC5B,6BAA6B,CAC3B,MAAM,CAAC,wBAAwB,EAC/B,uDAAuD,CACxD,CAAC;IAEJ,IACE,wBAAwB,CAAC,IAAI;QAC3B,sBAAsB;QACxB,mBAAmB,KAAK,SAAS,EACjC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,qGAAqG,CACtG,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GACf,gBAAgB,CACd,MAAM,CAAC,WAAW,EAClB,0CAA0C,CAC3C,CAAC;IAEJ,IACE,MAAM,CAAC,gBAAgB;QACrB,YAAY;QACd,WAAW,CAAC,IAAI;YACd,gBAAgB,EAClB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,4FAA4F,CAC7F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EAAE,OAAO;QACtB,SAAS,EAAE,qBAAqB,CAC9B,MAAM,CAAC,SAAS,EAChB,wCAAwC,CACzC;QACD,4BAA4B,EAC1B,qBAAqB,CACnB,MAAM;aACH,4BAA4B,EAC/B,2DAA2D,CAC5D;QACH,yBAAyB,EACvB,qBAAqB,CACnB,MAAM;aACH,yBAAyB,EAC5B,wDAAwD,CACzD;QACH,sBAAsB,EACpB,qBAAqB,CACnB,MAAM,CAAC,sBAAsB,EAC7B,qDAAqD,CACtD;QACH,SAAS,EACP,qBAAqB,CACnB,MAAM,CAAC,SAAS,EAChB,wCAAwC,CACzC;QACH,gBAAgB,EACd,MAAM,CAAC,gBAAgB;QACzB,WAAW;QACX,QAAQ,EAAE,iBAAiB,CACzB,MAAM,CAAC,QAAQ,EACf,uCAAuC,CACxC;QACD,UAAU,EAAE,eAAe,CACzB,MAAM,CAAC,UAAU,EACjB,yCAAyC,CAC1C;QACD,uBAAuB,EACrB,4BAA4B,CAC1B,MAAM,CAAC,uBAAuB,EAC9B,sDAAsD,CACvD;QACH,kBAAkB,EAChB,uBAAuB,CACrB,MAAM,CAAC,kBAAkB,EACzB,iDAAiD,CAClD;QACH,qBAAqB,EACnB,0BAA0B,CACxB,MAAM,CAAC,qBAAqB,CAC7B;QACH,kBAAkB,EAChB,uBAAuB,CACrB,MAAM,CAAC,kBAAkB,CAC1B;QACH,GAAG,CAAC,mBAAmB;YACvB,SAAS;YACP,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,mBAAmB,EAAE,CAAC;QAC5B,wBAAwB;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,SACmC,EACnC,SACmC;IAEnC,IACE,SAAS,CAAC,YAAY;QACpB,SAAS;QACX,SAAS,CAAC,YAAY;YACpB,SAAS,CAAC,YAAY,EACxB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,SAAS;SACN,+BAA+B;QAChC,SAAS;QACX,SAAS;aACN,+BAA+B;YAChC,SAAS;iBACN,+BAA+B,EACpC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,SAAS,CAAC,YAAY;QACpB,SAAS;QACX,SAAS,CAAC,YAAY;YACpB,SAAS,CAAC,YAAY,EACxB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,sBAAsB,CAC7B,SACyC,EACzC,KACmC;IAEnC,MAAM,KAAK,GACT,KAAK,CAAC,IAAI;QACR,wDAAwD;QACxD,CAAC,CAAC,SAAS;aACN,sDAAsD;QAC3D,CAAC,CAAC,SAAS;aACN,+DAA+D,CAAC;IAEzE,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvB,KAAK,GAAG,CAAC,EACT,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,sBAAsB,CAC7B,KACkE,EAClE,KACmC;IAEnC,MAAM,KAAK,GACT,KAAK,CAAC,IAAI;QACR,wDAAwD;QACxD,CAAC,CAAC,KAAK;aACF,kEAAkE;QACvE,CAAC,CAAC,KAAK;aACF,iEAAiE,CAAC;IAE3E,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvB,KAAK,GAAG,CAAC,EACT,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,yBAAyB,CAChC,SACyC,EACzC,aACkD;IAElD,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IACjD,IACE,SAAS,CAAC,iBAAiB;QACzB,aAAa;aACV,yBAAyB;QAC9B,SAAS,CAAC,sBAAsB;YAC9B,aAAa;iBACV,sBAAsB;QAC3B,SAAS,CAAC,SAAS;YACjB,aAAa,CAAC,SAAS,EACzB,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,iEAAiE,CAClE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kCAAkC,CAChD,KACyC;IAEzC,gBAAgB,CAAC,KAAK,EAAE,oCAAoC,EAAE,CAAC,WAAW,EAAE,eAAe,EAAE,uBAAuB,CAAC,CAAC,CAAC;IACvH,yBAAyB,CACvB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,aAAa,CACpB,CAAC;IACF,MAAM,OAAO,GACX,wCAAwC,CACtC,KAAK,CAAC,qBAAqB,CAC5B,CAAC;IACJ,MAAM,QAAQ,GAEV,EAAE,CAAC;IAEP,IACE,CAAC,KAAK,CAAC,aAAa;SACjB,kCAAkC;QACrC,KAAK,CAAC,aAAa;aAChB,mBAAmB,KAAK,SAAS,EACpC,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IAED,IACE,OAAO,CAAC,4BAA4B;QACpC,KAAK,CAAC,aAAa;aAChB,oBAAoB,EACvB,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IACD,IACE,OAAO,CAAC,yBAAyB;QACjC,KAAK,CAAC,SAAS;aACZ,iBAAiB,EACpB,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,uCAAuC,CACxC,CAAC;IACJ,CAAC;IACD,IACE,OAAO,CAAC,sBAAsB;QAC9B,KAAK,CAAC,SAAS;aACZ,sBAAsB,EACzB,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,oCAAoC,CACrC,CAAC;IACJ,CAAC;IACD,IACE,OAAO,CAAC,SAAS;QACjB,KAAK,CAAC,SAAS,CAAC,SAAS,EACzB,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,qBAAqB,CACtB,CAAC;IACJ,CAAC;IAED,IACE,CAAC,KAAK,CAAC,SAAS;SACb,uBAAuB,EAC1B,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,6BAA6B,CAC9B,CAAC;IACJ,CAAC;SAAM,IACL,KAAK,CAAC,SAAS,CAAC,eAAe;QAC/B,OAAO,CAAC,uBAAuB;aAC5B,eAAe,EAClB,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,2BAA2B,CAC5B,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GACnB,KAAK,CAAC,SAAS;SACZ,yBAAyB,CAAC;IAC/B,IACE,eAAe,CAAC,OAAO;QACrB,OAAO,CAAC,uBAAuB;aAC5B,iBAAiB;QACtB,eAAe,CAAC,OAAO;YACrB,OAAO,CAAC,uBAAuB;iBAC5B,iBAAiB,EACtB,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,kDAAkD,CACnD,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GACf,sBAAsB,CACpB,KAAK,CAAC,SAAS,EACf,OAAO,CAAC,UAAU,CACnB,CAAC;IAEJ,IACE,WAAW;QACX,OAAO,CAAC,UAAU,CAAC,gBAAgB,EACnC,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,6BAA6B,CAC9B,CAAC;IACJ,CAAC;IACD,IACE,WAAW;QACX,OAAO,CAAC,UAAU,CAAC,gBAAgB,EACnC,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,6BAA6B,CAC9B,CAAC;IACJ,CAAC;IAED,MAAM,kBAAkB,GACtB,OAAO,CAAC,kBAAkB,IAAI;QAC5B,IAAI,EAAE,2BAAoC;KAC3C,CAAC;IACJ,MAAM,2BAA2B,GAUzB,EAAE,CAAC;IAEX,IACE,kBAAkB,CAAC,IAAI;QACrB,kBAAkB,EACpB,CAAC;QACD,KACE,MAAM,KAAK,IACX,KAAK,CAAC,SAAS,CAAC,aAAa,EAC7B,CAAC;YACD,IACE,KAAK,CAAC,2BAA2B;gBACjC,kBAAkB;qBACf,yBAAyB,EAC5B,CAAC;gBACD,QAAQ,CAAC,IAAI,CACX,oDAAoD,CACrD,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GACT,sBAAsB,CACpB,KAAK,EACL,OAAO,CAAC,UAAU,CACnB,CAAC;YACJ,2BAA2B,CAAC,IAAI,CAAC;gBAC/B,mBAAmB,EACjB,KAAK,CAAC,mBAAmB;gBAC3B,oBAAoB,EAClB,KAAK,CAAC,oBAAoB;gBAC5B,2BAA2B,EACzB,KAAK,CAAC,2BAA2B;gBACnC,IAAI,EACF,OAAO,CAAC,UAAU,CAAC,IAAI;gBACzB,IAAI,EACF,OAAO,CAAC,UAAU,CAAC,IAAI;gBACzB,KAAK;aACN,CAAC,CAAC;YAEH,IACE,KAAK;gBACL,OAAO,CAAC,UAAU;qBACf,gBAAgB,EACnB,CAAC;gBACD,QAAQ,CAAC,IAAI,CACX,0CAA0C,CAC3C,CAAC;YACJ,CAAC;YACD,IACE,KAAK;gBACL,OAAO,CAAC,UAAU;qBACf,gBAAgB,EACnB,CAAC;gBACD,QAAQ,CAAC,IAAI,CACX,0CAA0C,CAC3C,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IACE,OAAO,CAAC,qBAAqB,EAAE,IAAI;QACjC,8CAA8C,EAChD,CAAC;QACD,QAAQ,CAAC,IAAI,CACX,iDAAiD,CAClD,CAAC;IACJ,CAAC;IAED,IACE,OAAO,CAAC,wBAAwB,CAAC,IAAI;QACnC,sBAAsB,EACxB,CAAC;QACD,MAAM,mBAAmB,GACvB,OAAO,CAAC,mBAAoB,CAAC;QAC/B,IACE,KAAK,CAAC,aAAa;aAChB,mBAAmB;YACtB,SAAS,EACT,CAAC;YACD,QAAQ,CAAC,IAAI,CACX,mCAAmC,CACpC,CAAC;QACJ,CAAC;aAAM,IACL,CAAC,eAAe,CACd,mBAAmB,EACnB,KAAK,CAAC,aAAa;aAChB,mBAAmB,CACvB,EACD,CAAC;YACD,QAAQ,CAAC,IAAI,CACX,yCAAyC,CAC1C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GACd,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IAExB,MAAM,WAAW,GACf,KAAK,CAAC,aAAa;SAChB,mBAAmB;QACpB,0BAA0B;QAC5B,OAAO,CAAC,gBAAgB;YACtB,eAAe;QACjB,OAAO,CAAC,WAAW,CAAC,IAAI;YACtB,gBAAgB;QAClB,CACE,OAAO,CAAC,qBAAqB,EAAE,IAAI;YACjC,8CAA8C;YAChD,OAAO,CAAC,qBAAqB;iBAC1B,gBAAgB;gBACjB,eAAe,CAClB;QACD,CACE,kBAAkB,CAAC,IAAI;YACrB,kBAAkB;YACpB,kBAAkB;iBACf,gBAAgB;gBACjB,eAAe,CAClB;QACD,OAAO,CAAC,wBAAwB,CAAC,IAAI;YACnC,mBAAmB,CAAC;IAExB,MAAM,iBAAiB,GACrB,UAAU;QACV,kBAAkB,CAAC,IAAI;YACrB,kBAAkB,CAAC;IAEvB,MAAM,MAAM,GACV,UAAU;QACR,CAAC,CAAC,iBAAiB;YACjB,CAAC,CAAC,WAAW;gBACX,CAAC,CAAC,0CAA0C;gBAC5C,CAAC,CAAC,4BAA4B;YAChC,CAAC,CAAC,WAAW;gBACX,CAAC,CAAC,0CAA0C;gBAC5C,CAAC,CAAC,4BAA4B;QAClC,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,0BAA0B,GAC9B,OAAO,CAAC,wBAAwB,CAAC,IAAI;QACnC,mBAAmB;QACnB,CAAC,CAAC,OAAO,CAAC,wBAAwB;aAC7B,QAAQ;QACb,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,wBAAwB,GAC5B,OAAO,CAAC,qBAAqB,EAAE,IAAI;QACjC,8CAA8C;QAC9C,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,QAAQ;QACxC,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,gBAAgB,CACrB;QACE,uBAAuB,EACrB,OAAO,CAAC,SAAS;QACnB,4BAA4B,EAC1B,KAAK,CAAC,aAAa;aAChB,oBAAoB;QACzB,yBAAyB,EACvB,KAAK,CAAC,SAAS;aACZ,iBAAiB;QACtB,sBAAsB,EACpB,KAAK,CAAC,SAAS;aACZ,sBAAsB;QAC3B,SAAS,EACP,KAAK,CAAC,SAAS,CAAC,SAAS;QAC3B,kBAAkB,EAChB,KAAK,CAAC,aAAa;aAChB,kBAAkB;QACvB,UAAU,EACR,OAAO,CAAC,UAAU;QACpB,cAAc,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;YAC7B,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;YAC7B,KAAK,EAAE,WAAW;SACnB;QACD,uBAAuB,EACrB,OAAO,CAAC,uBAAuB;QACjC,kCAAkC,EAChC;YACE,GAAG,eAAe;SACnB;QACH,kBAAkB,EAChB,OAAO,CAAC,kBAAkB;QAC5B,kBAAkB;QAClB,GAAG,CAAC,2BAA2B,CAAC,MAAM;YACtC,CAAC;YACC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,2BAA2B;aAC5B,CAAC;QACN,sCAAsC,EACpC,kBAAkB,CAAC,IAAI;YACvB,kBAAkB;QACpB,qBAAqB,EACnB,OAAO,CAAC,qBAAqB,IAAI;YAC/B,IAAI,EAAE,iBAAiB;YACvB,UAAU,EACR,6DAA6D;SAChE;QACH,wBAAwB,EACtB,OAAO,CAAC,wBAAwB;QAClC,GAAG,CAAC,OAAO,CAAC,mBAAmB;YAC/B,SAAS;YACP,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,mBAAmB,EACjB,OAAO,CAAC,mBAAmB;aAC9B,CAAC;QACN,GAAG,CAAC,KAAK,CAAC,aAAa;aACpB,mBAAmB;YACtB,SAAS;YACP,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,mBAAmB,EACjB,KAAK,CAAC,aAAa;qBAChB,mBAAmB;aACzB,CAAC;QACN,mCAAmC,EACjC,IAAI;QACN,oCAAoC,EAClC,UAAU;QACZ,MAAM;QACN,QAAQ;QACR,gCAAgC,EAC9B,iBAAiB;QACnB,4BAA4B,EAC1B,KAAK;QACP,6BAA6B,EAC3B,KAAK;QACP,+BAA+B,EAC7B,KAAK;QACP,kCAAkC,EAChC,KAAK;QACP,kBAAkB,EAAE,KAAK;QACzB,yBAAyB,EACvB,KAAK;QACP,2BAA2B,EACzB,KAAK;QACP,0BAA0B,EACxB,KAAK;QACP,iBAAiB,EAAE;YACjB,cAAc,EACZ,OAAO,CAAC,QAAQ;YAClB,4BAA4B,EAC1B,0BAA0B;YAC5B,gBAAgB,EACd,wBAAwB;YAC1B,uBAAuB,EACrB,KAAK,CAAC,aAAa;iBAChB,iBAAiB;SACvB;KACF,EACD,4CAA4C,EAC5C,OAAO,EACP;QACE,qHAAqH;QACrH,2KAA2K;QAC3K,sOAAsO;QACtO,gLAAgL;QAChL,iJAAiJ;QACjJ,iMAAiM;QACjM,8LAA8L;QAC9L,6JAA6J;QAC7J,wJAAwJ;QACxJ,0KAA0K;QAC1K,mGAAmG;KACpG,CACF,CAAC;AACJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Response operating range: checks that the light input is inside the range where the measured\n * sensor response is valid (linear within a declared criterion).\n *\n * It keeps incident power and irradiance distinct, and respects wavelength coverage, reference\n * conditions and the declared non-linearity criterion. Converting each spectral bin needs that bin to\n * be in range and needs spatial linear superposition (the response to a sum of inputs is the sum of\n * the responses). A valid average must not hide a part of the aperture that is too bright.\n * @see docs/MOTION_AND_SIGNAL.md for equations, coordinate/unit conventions, blockers and support\n * limits.\n */\n\nimport {\n calculatedResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport type {\n SensorResponseApplicationCompatibilityAssessment,\n SensorResponseReferenceConditionPolicy,\n SensorResponseSignalPath\n} from \"./response-application-compatibility.js\";\nimport type {\n SensorSpectralReferenceConditions,\n SensorSpectralResponseScientificStatus,\n SensorSpectralResponseUncertainty,\n SpectralWavelengthBasis\n} from \"./spectral-response.js\";\nimport type {\n SensorSpatioSpectralIrradianceReduction\n} from \"./spatio-spectral-reduction.js\";\nimport { requireInputObject, requireInputKeys, rejectUnknownFields, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport type SensorResponseOperatingInputRange =\n | {\n kind:\n \"wavelength-integrated-geometric-aperture-radiant-power\";\n unit: \"W\";\n minimumInclusive: number;\n maximumInclusive: number;\n }\n | {\n kind:\n \"wavelength-integrated-spatial-average-irradiance\";\n unit: \"W/m^2\";\n minimumInclusive: number;\n maximumInclusive: number;\n };\n\nexport interface SensorResponseOperatingWavelengthApplicability {\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n minimumNanometers: number;\n maximumNanometers: number;\n containment:\n \"requested-range-must-be-contained\";\n}\n\nexport interface SensorResponseLinearityCriterion {\n maximumAbsoluteRelativeDeviation: number;\n}\n\nexport type SensorResponseOperatingSpectralInputModel =\n | {\n kind: \"broadband-integrated-only\";\n }\n | {\n kind: \"per-spectral-bin\";\n maximumBinWidthNanometers: number;\n scientificStatus:\n SensorSpectralResponseScientificStatus;\n evidence: readonly EvidenceProvenance[];\n limitation?: string;\n };\n\nexport type SensorResponseOperatingSpatialLinearityModel =\n | {\n kind:\n \"linear-superposition-over-geometric-aperture\";\n scientificStatus:\n SensorSpectralResponseScientificStatus;\n evidence: readonly EvidenceProvenance[];\n limitation?: string;\n }\n | {\n kind: \"not-established\";\n limitation: string;\n };\n\nexport interface SensorResponseOperatingRangeProfile {\n schemaVersion: \"0.1.0\";\n profileId: string;\n responseApplicationProfileId: string;\n spectralResponseProfileId: string;\n colorSamplingProfileId: string;\n channelId: string;\n scientificStatus:\n SensorSpectralResponseScientificStatus;\n uncertainty:\n SensorSpectralResponseUncertainty;\n evidence: readonly EvidenceProvenance[];\n inputRange:\n SensorResponseOperatingInputRange;\n wavelengthApplicability:\n SensorResponseOperatingWavelengthApplicability;\n linearityCriterion:\n SensorResponseLinearityCriterion;\n /**\n * Optional for backward compatibility. If omitted, it parses as \"not\n * established\", which blocks new response-rate conversions.\n */\n spatialLinearityModel?:\n SensorResponseOperatingSpatialLinearityModel;\n /**\n * Optional for backward compatibility. If omitted, the calibration only\n * establishes an operating range for broadband (wavelength-integrated) input,\n * and cannot allow wavelength-by-wavelength response conversion.\n */\n spectralInputModel?:\n SensorResponseOperatingSpectralInputModel;\n referenceConditions?:\n SensorSpectralReferenceConditions;\n referenceConditionPolicy:\n SensorResponseReferenceConditionPolicy;\n}\n\nexport interface AssessSensorResponseOperatingRangeInput {\n reduction:\n SensorSpatioSpectralIrradianceReduction;\n compatibility:\n SensorResponseApplicationCompatibilityAssessment;\n operatingRangeProfile:\n SensorResponseOperatingRangeProfile;\n}\n\nexport type SensorResponseOperatingRangeBlocker =\n | \"structural-compatibility-not-established\"\n | \"response-application-profile-id-mismatch\"\n | \"spectral-response-profile-id-mismatch\"\n | \"color-sampling-profile-id-mismatch\"\n | \"channel-id-mismatch\"\n | \"wavelength-basis-unresolved\"\n | \"wavelength-basis-mismatch\"\n | \"wavelength-range-outside-linearity-applicability\"\n | \"input-below-linearity-range\"\n | \"input-above-linearity-range\"\n | \"spectral-bin-width-outside-linearity-applicability\"\n | \"spectral-bin-input-below-linearity-range\"\n | \"spectral-bin-input-above-linearity-range\"\n | \"spatial-linearity-superposition-not-established\"\n | \"operating-conditions-not-declared\"\n | \"linearity-operating-conditions-mismatch\";\n\nexport interface SensorResponseOperatingRangeAssessment {\n operatingRangeProfileId: string;\n responseApplicationProfileId: string;\n spectralResponseProfileId: string;\n colorSamplingProfileId: string;\n channelId: string;\n requiredSignalPath:\n SensorResponseSignalPath;\n inputRange:\n SensorResponseOperatingInputRange;\n evaluatedInput: {\n kind:\n SensorResponseOperatingInputRange[\"kind\"];\n unit:\n SensorResponseOperatingInputRange[\"unit\"];\n value: number;\n };\n wavelengthApplicability:\n SensorResponseOperatingWavelengthApplicability;\n evaluatedWavelengthRangeNanometers: {\n minimum: number;\n maximum: number;\n };\n linearityCriterion:\n SensorResponseLinearityCriterion;\n spectralInputModel:\n SensorResponseOperatingSpectralInputModel;\n evaluatedSpectralNodeInputs?:\n readonly {\n spectralSampleIndex: number;\n wavelengthNanometers: number;\n wavelengthMeasureNanometers: number;\n kind:\n SensorResponseOperatingInputRange[\"kind\"];\n unit:\n SensorResponseOperatingInputRange[\"unit\"];\n value: number;\n }[];\n spectralNodeRangeCompatibilityAssessed:\n boolean;\n spatialLinearityModel:\n SensorResponseOperatingSpatialLinearityModel;\n referenceConditionPolicy:\n SensorResponseReferenceConditionPolicy;\n referenceConditions?:\n SensorSpectralReferenceConditions;\n operatingConditions?:\n SensorSpectralReferenceConditions;\n operatingRangeCompatibilityAssessed: true;\n instantaneousResponseRangeCompatible: boolean;\n status:\n | \"broadband-range-compatible\"\n | \"broadband-range-compatible-approximation\"\n | \"rate-conversion-authorized\"\n | \"rate-conversion-authorized-approximation\"\n | \"blocked\";\n blockers:\n readonly SensorResponseOperatingRangeBlocker[];\n responseRateConversionAuthorized: boolean;\n responseApplicationPerformed: false;\n temporalIntegrationAuthorized: false;\n exposureDomainLinearityAssessed: false;\n accumulatedChargeLinearityAssessed: false;\n saturationAssessed: false;\n photonConversionPerformed: false;\n electronConversionPerformed: false;\n currentConversionPerformed: false;\n componentEvidence: {\n operatingRange:\n readonly EvidenceProvenance[];\n referenceConditionAssumption:\n readonly EvidenceProvenance[];\n spatialLinearity:\n readonly EvidenceProvenance[];\n structuralCompatibility:\n SensorResponseApplicationCompatibilityAssessment[\"componentEvidence\"];\n };\n}\n\nfunction requireRecord(\n value: unknown,\n path: string,\n allowedKeys: readonly string[] | null\n): UnknownRecord {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be an object.\"\n );\n }\n if (allowedKeys !== null) rejectUnknownFields(value, allowedKeys, path);\n return value as UnknownRecord;\n}\n\nfunction requireNonEmptyString(\n value: unknown,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a non-empty string.\"\n );\n }\n return value;\n}\n\nfunction requireFiniteNonNegative(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < 0\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be finite and greater than or equal to zero.\"\n );\n }\n return value;\n}\n\nfunction requirePositiveFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value <= 0\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be finite and greater than zero.\"\n );\n }\n return value;\n}\n\nfunction parseUncertainty(\n value: unknown,\n path: string\n): SensorSpectralResponseUncertainty {\n const record =\n requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", UNCERTAINTY_VARIANT_FIELDS, path);\n\n if (record.kind === \"relative\") {\n const fraction =\n requireFiniteNonNegative(\n record.fraction,\n path + \".fraction\"\n );\n return {\n kind: \"relative\",\n fraction,\n basis: requireNonEmptyString(\n record.basis,\n path + \".basis\"\n )\n };\n }\n\n if (\n record.kind === \"not-quantified\"\n ) {\n return {\n kind: \"not-quantified\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseReferenceConditions(\n value: unknown,\n path: string\n): SensorSpectralReferenceConditions {\n const record =\n requireRecord(value, path, [\"temperatureC\", \"incidenceAngleDegreesFromNormal\", \"polarization\"]);\n const result:\n SensorSpectralReferenceConditions =\n {};\n\n if (\n record.temperatureC !== undefined\n ) {\n if (\n typeof record.temperatureC !==\n \"number\" ||\n !Number.isFinite(\n record.temperatureC\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \".temperatureC must be finite.\"\n );\n }\n result.temperatureC =\n record.temperatureC;\n }\n\n if (\n record.incidenceAngleDegreesFromNormal !==\n undefined\n ) {\n const angle =\n record\n .incidenceAngleDegreesFromNormal;\n if (\n typeof angle !== \"number\" ||\n !Number.isFinite(angle) ||\n angle < 0 ||\n angle > 90\n ) {\n throw new InvalidConfigurationError(\n path +\n \".incidenceAngleDegreesFromNormal must be finite from 0 through 90.\"\n );\n }\n result.incidenceAngleDegreesFromNormal =\n angle;\n }\n\n if (\n record.polarization !== undefined\n ) {\n if (\n record.polarization !==\n \"unpolarized\" &&\n record.polarization !==\n \"unspecified\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \".polarization is invalid.\"\n );\n }\n result.polarization =\n record.polarization;\n }\n\n if (\n result.temperatureC === undefined &&\n result\n .incidenceAngleDegreesFromNormal ===\n undefined &&\n result.polarization === undefined\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must declare at least one condition.\"\n );\n }\n\n return result;\n}\n\nfunction parseReferenceConditionPolicy(\n value: unknown,\n path: string\n): SensorResponseReferenceConditionPolicy {\n const record =\n requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", { \"exact-match-required\": [\"kind\"], \"assume-compatible\": [\"kind\", \"limitation\", \"evidence\"] }, path);\n\n if (\n record.kind ===\n \"exact-match-required\"\n ) {\n return {\n kind: \"exact-match-required\"\n };\n }\n\n if (\n record.kind === \"assume-compatible\"\n ) {\n return {\n kind: \"assume-compatible\",\n limitation:\n requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n ),\n evidence: parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n }\n\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseInputRange(\n value: unknown,\n path: string\n): SensorResponseOperatingInputRange {\n const record =\n requireRecord(value, path, [\"minimumInclusive\", \"maximumInclusive\", \"kind\", \"unit\"]);\n\n const minimumInclusive =\n requireFiniteNonNegative(\n record.minimumInclusive,\n path + \".minimumInclusive\"\n );\n const maximumInclusive =\n requirePositiveFinite(\n record.maximumInclusive,\n path + \".maximumInclusive\"\n );\n\n if (\n minimumInclusive >=\n maximumInclusive\n ) {\n throw new InvalidConfigurationError(\n path +\n \".minimumInclusive must be less than maximumInclusive.\"\n );\n }\n\n if (\n record.kind ===\n \"wavelength-integrated-geometric-aperture-radiant-power\"\n ) {\n if (record.unit !== \"W\") {\n throw new InvalidConfigurationError(\n path +\n '.unit must be \"W\".'\n );\n }\n return {\n kind:\n \"wavelength-integrated-geometric-aperture-radiant-power\",\n unit: \"W\",\n minimumInclusive,\n maximumInclusive\n };\n }\n\n if (\n record.kind ===\n \"wavelength-integrated-spatial-average-irradiance\"\n ) {\n if (record.unit !== \"W/m^2\") {\n throw new InvalidConfigurationError(\n path +\n '.unit must be \"W/m^2\".'\n );\n }\n return {\n kind:\n \"wavelength-integrated-spatial-average-irradiance\",\n unit: \"W/m^2\",\n minimumInclusive,\n maximumInclusive\n };\n }\n\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseWavelengthApplicability(\n value: unknown,\n path: string\n): SensorResponseOperatingWavelengthApplicability {\n const record =\n requireRecord(value, path, [\"wavelengthBasis\", \"minimumNanometers\", \"maximumNanometers\", \"containment\"]);\n\n if (\n record.wavelengthBasis !== \"air\" &&\n record.wavelengthBasis !==\n \"vacuum\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.wavelengthBasis must be \"air\" or \"vacuum\".'\n );\n }\n\n const minimumNanometers =\n requirePositiveFinite(\n record.minimumNanometers,\n path + \".minimumNanometers\"\n );\n const maximumNanometers =\n requirePositiveFinite(\n record.maximumNanometers,\n path + \".maximumNanometers\"\n );\n\n if (\n minimumNanometers >=\n maximumNanometers\n ) {\n throw new InvalidConfigurationError(\n path +\n \".minimumNanometers must be less than maximumNanometers.\"\n );\n }\n\n if (\n record.containment !==\n \"requested-range-must-be-contained\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.containment must be \"requested-range-must-be-contained\".'\n );\n }\n\n return {\n wavelengthBasis:\n record.wavelengthBasis,\n minimumNanometers,\n maximumNanometers,\n containment:\n \"requested-range-must-be-contained\"\n };\n}\n\nfunction parseLinearityCriterion(\n value: unknown,\n path: string\n): SensorResponseLinearityCriterion {\n const record =\n requireRecord(value, path, [\"maximumAbsoluteRelativeDeviation\"]);\n const maximumAbsoluteRelativeDeviation =\n requireFiniteNonNegative(\n record\n .maximumAbsoluteRelativeDeviation,\n path +\n \".maximumAbsoluteRelativeDeviation\"\n );\n\n if (\n maximumAbsoluteRelativeDeviation >\n 1\n ) {\n throw new InvalidConfigurationError(\n path +\n \".maximumAbsoluteRelativeDeviation must be a fraction from 0 through 1.\"\n );\n }\n\n return {\n maximumAbsoluteRelativeDeviation\n };\n}\n\nfunction parseSpectralInputModel(\n value: unknown\n): SensorResponseOperatingSpectralInputModel {\n if (value === undefined) {\n return {\n kind: \"broadband-integrated-only\"\n };\n }\n\n const record = requireRecord(\n value,\n \"sensorResponseOperatingRange.spectralInputModel\", null\n );\n rejectUnknownVariantFields(record, \"kind\", { \"broadband-integrated-only\": [\"kind\"], \"per-spectral-bin\": [\"kind\", \"maximumBinWidthNanometers\", \"scientificStatus\", \"evidence\", \"limitation\"] }, \"sensorResponseOperatingRange.spectralInputModel\");\n\n if (\n record.kind ===\n \"broadband-integrated-only\"\n ) {\n return {\n kind: \"broadband-integrated-only\"\n };\n }\n\n if (\n record.kind !==\n \"per-spectral-bin\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spectralInputModel.kind is invalid.\"\n );\n }\n\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spectralInputModel.scientificStatus is invalid.\"\n );\n }\n\n const maximumBinWidthNanometers =\n requirePositiveFinite(\n record.maximumBinWidthNanometers,\n \"sensorResponseOperatingRange.spectralInputModel.maximumBinWidthNanometers\"\n );\n const limitation =\n record.limitation === undefined\n ? undefined\n : requireNonEmptyString(\n record.limitation,\n \"sensorResponseOperatingRange.spectralInputModel.limitation\"\n );\n\n if (\n record.scientificStatus ===\n \"approximation\" &&\n limitation === undefined\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spectralInputModel.limitation is required for an approximation.\"\n );\n }\n\n return {\n kind: \"per-spectral-bin\",\n maximumBinWidthNanometers,\n scientificStatus:\n record.scientificStatus,\n evidence: parseEvidenceList(\n record.evidence,\n \"sensorResponseOperatingRange.spectralInputModel.evidence\"\n ),\n ...(limitation === undefined\n ? {}\n : { limitation })\n };\n}\n\nfunction parseSpatialLinearityModel(\n value: unknown\n): SensorResponseOperatingSpatialLinearityModel {\n if (value === undefined) {\n return {\n kind: \"not-established\",\n limitation:\n \"Spatial-distribution linear superposition was not declared.\"\n };\n }\n\n const record = requireRecord(\n value,\n \"sensorResponseOperatingRange.spatialLinearityModel\", null\n );\n rejectUnknownVariantFields(record, \"kind\", { \"not-established\": [\"kind\", \"limitation\"], \"linear-superposition-over-geometric-aperture\": [\"kind\", \"scientificStatus\", \"evidence\", \"limitation\"] }, \"sensorResponseOperatingRange.spatialLinearityModel\");\n\n if (\n record.kind === \"not-established\"\n ) {\n return {\n kind: \"not-established\",\n limitation: requireNonEmptyString(\n record.limitation,\n \"sensorResponseOperatingRange.spatialLinearityModel.limitation\"\n )\n };\n }\n\n if (\n record.kind !==\n \"linear-superposition-over-geometric-aperture\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spatialLinearityModel.kind is invalid.\"\n );\n }\n\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spatialLinearityModel.scientificStatus is invalid.\"\n );\n }\n\n const limitation =\n record.limitation === undefined\n ? undefined\n : requireNonEmptyString(\n record.limitation,\n \"sensorResponseOperatingRange.spatialLinearityModel.limitation\"\n );\n\n if (\n record.scientificStatus ===\n \"approximation\" &&\n limitation === undefined\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spatialLinearityModel.limitation is required for an approximation.\"\n );\n }\n\n return {\n kind:\n \"linear-superposition-over-geometric-aperture\",\n scientificStatus:\n record.scientificStatus,\n evidence: parseEvidenceList(\n record.evidence,\n \"sensorResponseOperatingRange.spatialLinearityModel.evidence\"\n ),\n ...(limitation === undefined\n ? {}\n : { limitation })\n };\n}\n\n/**\n * Validates untrusted input and returns it as a normalized, typed value. Unknown enum values,\n * missing required fields and inconsistent scientific data are rejected.\n *\n * The profile states the input quantity (incident power or irradiance), wavelength coverage,\n * reference conditions and non-linearity criterion of the calibrated operating range.\n * @param value - Untrusted data. TypeScript types alone are not validation.\n * @returns The result. Success does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the package export and its full type definitions.\n */\nexport function parseSensorResponseOperatingRangeProfile(\n value: unknown\n): SensorResponseOperatingRangeProfile {\n const record =\n requireRecord(\n value,\n \"sensorResponseOperatingRange\", [\"schemaVersion\", \"scientificStatus\", \"referenceConditions\", \"referenceConditionPolicy\", \"uncertainty\", \"profileId\", \"responseApplicationProfileId\", \"spectralResponseProfileId\", \"colorSamplingProfileId\", \"channelId\", \"evidence\", \"inputRange\", \"wavelengthApplicability\", \"linearityCriterion\", \"spatialLinearityModel\", \"spectralInputModel\"]\n );\n\n if (\n record.schemaVersion !== \"0.1.0\"\n ) {\n throw new InvalidConfigurationError(\n 'sensorResponseOperatingRange.schemaVersion must be \"0.1.0\".'\n );\n }\n\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.scientificStatus is invalid.\"\n );\n }\n\n const referenceConditions =\n record.referenceConditions ===\n undefined\n ? undefined\n : parseReferenceConditions(\n record.referenceConditions,\n \"sensorResponseOperatingRange.referenceConditions\"\n );\n\n const referenceConditionPolicy =\n parseReferenceConditionPolicy(\n record.referenceConditionPolicy,\n \"sensorResponseOperatingRange.referenceConditionPolicy\"\n );\n\n if (\n referenceConditionPolicy.kind ===\n \"exact-match-required\" &&\n referenceConditions === undefined\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.referenceConditions is required when exact-match-required is selected.\"\n );\n }\n\n const uncertainty =\n parseUncertainty(\n record.uncertainty,\n \"sensorResponseOperatingRange.uncertainty\"\n );\n\n if (\n record.scientificStatus ===\n \"calibrated\" &&\n uncertainty.kind ===\n \"not-quantified\"\n ) {\n throw new InvalidConfigurationError(\n \"A calibrated sensor response operating range must declare quantified relative uncertainty.\"\n );\n }\n\n return {\n schemaVersion: \"0.1.0\",\n profileId: requireNonEmptyString(\n record.profileId,\n \"sensorResponseOperatingRange.profileId\"\n ),\n responseApplicationProfileId:\n requireNonEmptyString(\n record\n .responseApplicationProfileId,\n \"sensorResponseOperatingRange.responseApplicationProfileId\"\n ),\n spectralResponseProfileId:\n requireNonEmptyString(\n record\n .spectralResponseProfileId,\n \"sensorResponseOperatingRange.spectralResponseProfileId\"\n ),\n colorSamplingProfileId:\n requireNonEmptyString(\n record.colorSamplingProfileId,\n \"sensorResponseOperatingRange.colorSamplingProfileId\"\n ),\n channelId:\n requireNonEmptyString(\n record.channelId,\n \"sensorResponseOperatingRange.channelId\"\n ),\n scientificStatus:\n record.scientificStatus,\n uncertainty,\n evidence: parseEvidenceList(\n record.evidence,\n \"sensorResponseOperatingRange.evidence\"\n ),\n inputRange: parseInputRange(\n record.inputRange,\n \"sensorResponseOperatingRange.inputRange\"\n ),\n wavelengthApplicability:\n parseWavelengthApplicability(\n record.wavelengthApplicability,\n \"sensorResponseOperatingRange.wavelengthApplicability\"\n ),\n linearityCriterion:\n parseLinearityCriterion(\n record.linearityCriterion,\n \"sensorResponseOperatingRange.linearityCriterion\"\n ),\n spatialLinearityModel:\n parseSpatialLinearityModel(\n record.spatialLinearityModel\n ),\n spectralInputModel:\n parseSpectralInputModel(\n record.spectralInputModel\n ),\n ...(referenceConditions ===\n undefined\n ? {}\n : { referenceConditions }),\n referenceConditionPolicy\n };\n}\n\nfunction conditionsMatch(\n reference:\n SensorSpectralReferenceConditions,\n operating:\n SensorSpectralReferenceConditions\n): boolean {\n if (\n reference.temperatureC !==\n undefined &&\n operating.temperatureC !==\n reference.temperatureC\n ) {\n return false;\n }\n if (\n reference\n .incidenceAngleDegreesFromNormal !==\n undefined &&\n operating\n .incidenceAngleDegreesFromNormal !==\n reference\n .incidenceAngleDegreesFromNormal\n ) {\n return false;\n }\n if (\n reference.polarization !==\n undefined &&\n operating.polarization !==\n reference.polarization\n ) {\n return false;\n }\n return true;\n}\n\nfunction requireReductionMetric(\n reduction:\n SensorSpatioSpectralIrradianceReduction,\n range:\n SensorResponseOperatingInputRange\n): number {\n const value =\n range.kind ===\n \"wavelength-integrated-geometric-aperture-radiant-power\"\n ? reduction\n .wavelengthIntegratedGeometricApertureIncidentFluxWatts\n : reduction\n .wavelengthIntegratedSpatialAverageIrradianceWattsPerSquareMeter;\n\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < 0\n ) {\n throw new InvalidScientificInputError(\n \"The selected operating-range input metric must be finite and nonnegative.\"\n );\n }\n return value;\n}\n\nfunction spectralNodeInputValue(\n entry:\n SensorSpatioSpectralIrradianceReduction[\"perWavelength\"][number],\n range:\n SensorResponseOperatingInputRange\n): number {\n const value =\n range.kind ===\n \"wavelength-integrated-geometric-aperture-radiant-power\"\n ? entry\n .wavelengthIntegratedGeometricApertureIncidentFluxContributionWatts\n : entry\n .wavelengthIntegratedSpatialAverageContributionWattsPerSquareMeter;\n\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < 0\n ) {\n throw new InvalidScientificInputError(\n \"Per-spectral-node operating-range input must be finite and nonnegative.\"\n );\n }\n return value;\n}\n\nfunction validateReductionIdentity(\n reduction:\n SensorSpatioSpectralIrradianceReduction,\n compatibility:\n SensorResponseApplicationCompatibilityAssessment\n): void {\n requireInputObject(reduction, \"reduction input\");\n if (\n reduction.responseProfileId !==\n compatibility\n .spectralResponseProfileId ||\n reduction.colorSamplingProfileId !==\n compatibility\n .colorSamplingProfileId ||\n reduction.channelId !==\n compatibility.channelId\n ) {\n throw new InvalidScientificInputError(\n \"reduction and compatibility assessment identities do not match.\"\n );\n }\n}\n\n/**\n * Checks every declared spectral-bin input against the operating range and the superposition\n * requirement, before any instantaneous response conversion is allowed.\n *\n * Each bin must be in range, and spatial linear superposition must hold. A valid average must not\n * hide a part of the aperture that is too bright.\n * @param input - The input; see `AssessSensorResponseOperatingRangeInput` for its fields, units and coordinates.\n * @returns The assessment. Read its structured blockers before acting on an authorization.\n *\n * @see docs/API_REFERENCE.md for the package export and its full type definitions.\n */\nexport function assessSensorResponseOperatingRange(\n input:\n AssessSensorResponseOperatingRangeInput\n): CalculationResult<SensorResponseOperatingRangeAssessment> {\n requireInputKeys(input, \"assessSensorResponseOperatingRange\", [\"reduction\", \"compatibility\", \"operatingRangeProfile\"]);\n validateReductionIdentity(\n input.reduction,\n input.compatibility\n );\n const profile =\n parseSensorResponseOperatingRangeProfile(\n input.operatingRangeProfile\n );\n const blockers:\n SensorResponseOperatingRangeBlocker[] =\n [];\n\n if (\n !input.compatibility\n .structuralCompatibilityEstablished ||\n input.compatibility\n .compatibilityStatus === \"blocked\"\n ) {\n blockers.push(\n \"structural-compatibility-not-established\"\n );\n }\n\n if (\n profile.responseApplicationProfileId !==\n input.compatibility\n .applicationProfileId\n ) {\n blockers.push(\n \"response-application-profile-id-mismatch\"\n );\n }\n if (\n profile.spectralResponseProfileId !==\n input.reduction\n .responseProfileId\n ) {\n blockers.push(\n \"spectral-response-profile-id-mismatch\"\n );\n }\n if (\n profile.colorSamplingProfileId !==\n input.reduction\n .colorSamplingProfileId\n ) {\n blockers.push(\n \"color-sampling-profile-id-mismatch\"\n );\n }\n if (\n profile.channelId !==\n input.reduction.channelId\n ) {\n blockers.push(\n \"channel-id-mismatch\"\n );\n }\n\n if (\n !input.reduction\n .wavelengthBasisResolved\n ) {\n blockers.push(\n \"wavelength-basis-unresolved\"\n );\n } else if (\n input.reduction.wavelengthBasis !==\n profile.wavelengthApplicability\n .wavelengthBasis\n ) {\n blockers.push(\n \"wavelength-basis-mismatch\"\n );\n }\n\n const wavelengthRange =\n input.reduction\n .wavelengthRangeNanometers;\n if (\n wavelengthRange.minimum <\n profile.wavelengthApplicability\n .minimumNanometers ||\n wavelengthRange.maximum >\n profile.wavelengthApplicability\n .maximumNanometers\n ) {\n blockers.push(\n \"wavelength-range-outside-linearity-applicability\"\n );\n }\n\n const metricValue =\n requireReductionMetric(\n input.reduction,\n profile.inputRange\n );\n\n if (\n metricValue <\n profile.inputRange.minimumInclusive\n ) {\n blockers.push(\n \"input-below-linearity-range\"\n );\n }\n if (\n metricValue >\n profile.inputRange.maximumInclusive\n ) {\n blockers.push(\n \"input-above-linearity-range\"\n );\n }\n\n const spectralInputModel =\n profile.spectralInputModel ?? {\n kind: \"broadband-integrated-only\" as const\n };\n const evaluatedSpectralNodeInputs:\n {\n spectralSampleIndex: number;\n wavelengthNanometers: number;\n wavelengthMeasureNanometers: number;\n kind:\n SensorResponseOperatingInputRange[\"kind\"];\n unit:\n SensorResponseOperatingInputRange[\"unit\"];\n value: number;\n }[] = [];\n\n if (\n spectralInputModel.kind ===\n \"per-spectral-bin\"\n ) {\n for (\n const entry of\n input.reduction.perWavelength\n ) {\n if (\n entry.wavelengthMeasureNanometers >\n spectralInputModel\n .maximumBinWidthNanometers\n ) {\n blockers.push(\n \"spectral-bin-width-outside-linearity-applicability\"\n );\n }\n\n const value =\n spectralNodeInputValue(\n entry,\n profile.inputRange\n );\n evaluatedSpectralNodeInputs.push({\n spectralSampleIndex:\n entry.spectralSampleIndex,\n wavelengthNanometers:\n entry.wavelengthNanometers,\n wavelengthMeasureNanometers:\n entry.wavelengthMeasureNanometers,\n kind:\n profile.inputRange.kind,\n unit:\n profile.inputRange.unit,\n value\n });\n\n if (\n value <\n profile.inputRange\n .minimumInclusive\n ) {\n blockers.push(\n \"spectral-bin-input-below-linearity-range\"\n );\n }\n if (\n value >\n profile.inputRange\n .maximumInclusive\n ) {\n blockers.push(\n \"spectral-bin-input-above-linearity-range\"\n );\n }\n }\n }\n\n if (\n profile.spatialLinearityModel?.kind !==\n \"linear-superposition-over-geometric-aperture\"\n ) {\n blockers.push(\n \"spatial-linearity-superposition-not-established\"\n );\n }\n\n if (\n profile.referenceConditionPolicy.kind ===\n \"exact-match-required\"\n ) {\n const referenceConditions =\n profile.referenceConditions!;\n if (\n input.compatibility\n .operatingConditions ===\n undefined\n ) {\n blockers.push(\n \"operating-conditions-not-declared\"\n );\n } else if (\n !conditionsMatch(\n referenceConditions,\n input.compatibility\n .operatingConditions\n )\n ) {\n blockers.push(\n \"linearity-operating-conditions-mismatch\"\n );\n }\n }\n\n const compatible =\n blockers.length === 0;\n\n const approximate =\n input.compatibility\n .compatibilityStatus ===\n \"compatible-approximation\" ||\n profile.scientificStatus ===\n \"approximation\" ||\n profile.uncertainty.kind ===\n \"not-quantified\" ||\n (\n profile.spatialLinearityModel?.kind ===\n \"linear-superposition-over-geometric-aperture\" &&\n profile.spatialLinearityModel\n .scientificStatus ===\n \"approximation\"\n ) ||\n (\n spectralInputModel.kind ===\n \"per-spectral-bin\" &&\n spectralInputModel\n .scientificStatus ===\n \"approximation\"\n ) ||\n profile.referenceConditionPolicy.kind ===\n \"assume-compatible\";\n\n const spectralRateReady =\n compatible &&\n spectralInputModel.kind ===\n \"per-spectral-bin\";\n\n const status =\n compatible\n ? spectralRateReady\n ? approximate\n ? \"rate-conversion-authorized-approximation\"\n : \"rate-conversion-authorized\"\n : approximate\n ? \"broadband-range-compatible-approximation\"\n : \"broadband-range-compatible\"\n : \"blocked\";\n\n const referenceConditionEvidence =\n profile.referenceConditionPolicy.kind ===\n \"assume-compatible\"\n ? profile.referenceConditionPolicy\n .evidence\n : [];\n const spatialLinearityEvidence =\n profile.spatialLinearityModel?.kind ===\n \"linear-superposition-over-geometric-aperture\"\n ? profile.spatialLinearityModel.evidence\n : [];\n\n return calculatedResult(\n {\n operatingRangeProfileId:\n profile.profileId,\n responseApplicationProfileId:\n input.compatibility\n .applicationProfileId,\n spectralResponseProfileId:\n input.reduction\n .responseProfileId,\n colorSamplingProfileId:\n input.reduction\n .colorSamplingProfileId,\n channelId:\n input.reduction.channelId,\n requiredSignalPath:\n input.compatibility\n .requiredSignalPath,\n inputRange:\n profile.inputRange,\n evaluatedInput: {\n kind: profile.inputRange.kind,\n unit: profile.inputRange.unit,\n value: metricValue\n },\n wavelengthApplicability:\n profile.wavelengthApplicability,\n evaluatedWavelengthRangeNanometers:\n {\n ...wavelengthRange\n },\n linearityCriterion:\n profile.linearityCriterion,\n spectralInputModel,\n ...(evaluatedSpectralNodeInputs.length ===\n 0\n ? {}\n : {\n evaluatedSpectralNodeInputs\n }),\n spectralNodeRangeCompatibilityAssessed:\n spectralInputModel.kind ===\n \"per-spectral-bin\",\n spatialLinearityModel:\n profile.spatialLinearityModel ?? {\n kind: \"not-established\",\n limitation:\n \"Spatial-distribution linear superposition was not declared.\"\n },\n referenceConditionPolicy:\n profile.referenceConditionPolicy,\n ...(profile.referenceConditions ===\n undefined\n ? {}\n : {\n referenceConditions:\n profile.referenceConditions\n }),\n ...(input.compatibility\n .operatingConditions ===\n undefined\n ? {}\n : {\n operatingConditions:\n input.compatibility\n .operatingConditions\n }),\n operatingRangeCompatibilityAssessed:\n true,\n instantaneousResponseRangeCompatible:\n compatible,\n status,\n blockers,\n responseRateConversionAuthorized:\n spectralRateReady,\n responseApplicationPerformed:\n false,\n temporalIntegrationAuthorized:\n false,\n exposureDomainLinearityAssessed:\n false,\n accumulatedChargeLinearityAssessed:\n false,\n saturationAssessed: false,\n photonConversionPerformed:\n false,\n electronConversionPerformed:\n false,\n currentConversionPerformed:\n false,\n componentEvidence: {\n operatingRange:\n profile.evidence,\n referenceConditionAssumption:\n referenceConditionEvidence,\n spatialLinearity:\n spatialLinearityEvidence,\n structuralCompatibility:\n input.compatibility\n .componentEvidence\n }\n },\n \"sensor-response-operating-range-assessment\",\n \"1.0.0\",\n [\n \"This gate assesses instantaneous response-law applicability only; it does not apply response or integrate exposure.\",\n \"The valid optical-input range is evidence-backed and must be expressed in the same wavelength-integrated power or irradiance domain produced by the pre-response reducer.\",\n \"Broadband-integrated range compatibility alone cannot authorize wavelength-dependent response conversion; per-spectral-bin applicability must be explicitly established and every bin must remain inside the calibrated input range.\",\n \"Per-spectral-bin applicability also declares a maximum supported bin width so a broad quadrature bin is not silently treated as an equivalent monochromatic calibration point.\",\n \"Linearity can depend on optical input level and wavelength; the reduction wavelength range must remain inside the declared applicability range.\",\n \"Post-spatial rate conversion additionally requires explicit linear superposition over the geometric aperture; otherwise sub-aperture illumination patterns could hide local nonlinear behavior.\",\n \"The maximumAbsoluteRelativeDeviation criterion documents the tolerated response nonlinearity for the declared valid range; this function does not derive that criterion from synthetic data.\",\n \"Reference conditions for the linearity calibration are separate from spectral-response reference conditions and must match when exact matching is required.\",\n \"Exposure-domain linearity, accumulated-charge saturation/full-well behavior, and downstream electronics linearity are intentionally not assessed here.\",\n \"A successful result authorizes only a future instantaneous rate conversion path: photon-rate→electrons for EQE/filter×EQE or radiant-power→current for A/W responsivity.\",\n \"Temporal integration, saturation, noise, ADC/RAW conversion and reconstruction remain downstream.\"\n ]\n );\n}\n"]}
1
+ {"version":3,"file":"response-operating-range.js","sourceRoot":"","sources":["../../src/sensor/response-operating-range.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Response operating range: checks that the light input is inside the range where the measured\n * sensor response is valid (linear within a declared criterion).\n *\n * It keeps incident power and irradiance distinct, and respects wavelength coverage, reference\n * conditions and the declared non-linearity criterion. Converting each spectral bin needs that bin to\n * be in range and needs spatial linear superposition (the response to a sum of inputs is the sum of\n * the responses). A valid average must not hide a part of the aperture that is too bright.\n * @see docs/MOTION_AND_SIGNAL.md for equations, coordinate/unit conventions, blockers and support\n * limits.\n */\n\nimport {\n calculatedResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport type {\n SensorResponseApplicationCompatibilityAssessment,\n SensorResponseReferenceConditionPolicy,\n SensorResponseSignalPath\n} from \"./response-application-compatibility.js\";\nimport type {\n SensorSpectralReferenceConditions,\n SensorSpectralResponseScientificStatus,\n SensorSpectralResponseUncertainty,\n SpectralWavelengthBasis\n} from \"./spectral-response.js\";\nimport type {\n SensorSpatioSpectralIrradianceReduction\n} from \"./spatio-spectral-reduction.js\";\nimport { requireInputObject, requireInputKeys, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS, requireConfigRecord as requireRecord, requireConfigString as requireNonEmptyString, requireConfigPositiveFinite as requirePositiveFinite, requireConfigNonNegativeFinite as requireFiniteNonNegative } from \"../core/record-validation.js\";\nimport { parseReferenceConditionPolicy, conditionsMatch } from \"./response-application-compatibility.js\";\n\nexport type SensorResponseOperatingInputRange =\n | {\n kind:\n \"wavelength-integrated-geometric-aperture-radiant-power\";\n unit: \"W\";\n minimumInclusive: number;\n maximumInclusive: number;\n }\n | {\n kind:\n \"wavelength-integrated-spatial-average-irradiance\";\n unit: \"W/m^2\";\n minimumInclusive: number;\n maximumInclusive: number;\n };\n\nexport interface SensorResponseOperatingWavelengthApplicability {\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n minimumNanometers: number;\n maximumNanometers: number;\n containment:\n \"requested-range-must-be-contained\";\n}\n\nexport interface SensorResponseLinearityCriterion {\n maximumAbsoluteRelativeDeviation: number;\n}\n\nexport type SensorResponseOperatingSpectralInputModel =\n | {\n kind: \"broadband-integrated-only\";\n }\n | {\n kind: \"per-spectral-bin\";\n maximumBinWidthNanometers: number;\n scientificStatus:\n SensorSpectralResponseScientificStatus;\n evidence: readonly EvidenceProvenance[];\n limitation?: string;\n };\n\nexport type SensorResponseOperatingSpatialLinearityModel =\n | {\n kind:\n \"linear-superposition-over-geometric-aperture\";\n scientificStatus:\n SensorSpectralResponseScientificStatus;\n evidence: readonly EvidenceProvenance[];\n limitation?: string;\n }\n | {\n kind: \"not-established\";\n limitation: string;\n };\n\nexport interface SensorResponseOperatingRangeProfile {\n schemaVersion: \"0.1.0\";\n profileId: string;\n responseApplicationProfileId: string;\n spectralResponseProfileId: string;\n colorSamplingProfileId: string;\n channelId: string;\n scientificStatus:\n SensorSpectralResponseScientificStatus;\n uncertainty:\n SensorSpectralResponseUncertainty;\n evidence: readonly EvidenceProvenance[];\n inputRange:\n SensorResponseOperatingInputRange;\n wavelengthApplicability:\n SensorResponseOperatingWavelengthApplicability;\n linearityCriterion:\n SensorResponseLinearityCriterion;\n /**\n * Optional for backward compatibility. If omitted, it parses as \"not\n * established\", which blocks new response-rate conversions.\n */\n spatialLinearityModel?:\n SensorResponseOperatingSpatialLinearityModel;\n /**\n * Optional for backward compatibility. If omitted, the calibration only\n * establishes an operating range for broadband (wavelength-integrated) input,\n * and cannot allow wavelength-by-wavelength response conversion.\n */\n spectralInputModel?:\n SensorResponseOperatingSpectralInputModel;\n referenceConditions?:\n SensorSpectralReferenceConditions;\n referenceConditionPolicy:\n SensorResponseReferenceConditionPolicy;\n}\n\nexport interface AssessSensorResponseOperatingRangeInput {\n reduction:\n SensorSpatioSpectralIrradianceReduction;\n compatibility:\n SensorResponseApplicationCompatibilityAssessment;\n operatingRangeProfile:\n SensorResponseOperatingRangeProfile;\n}\n\nexport type SensorResponseOperatingRangeBlocker =\n | \"structural-compatibility-not-established\"\n | \"response-application-profile-id-mismatch\"\n | \"spectral-response-profile-id-mismatch\"\n | \"color-sampling-profile-id-mismatch\"\n | \"channel-id-mismatch\"\n | \"wavelength-basis-unresolved\"\n | \"wavelength-basis-mismatch\"\n | \"wavelength-range-outside-linearity-applicability\"\n | \"input-below-linearity-range\"\n | \"input-above-linearity-range\"\n | \"spectral-bin-width-outside-linearity-applicability\"\n | \"spectral-bin-input-below-linearity-range\"\n | \"spectral-bin-input-above-linearity-range\"\n | \"spatial-linearity-superposition-not-established\"\n | \"operating-conditions-not-declared\"\n | \"linearity-operating-conditions-mismatch\";\n\nexport interface SensorResponseOperatingRangeAssessment {\n operatingRangeProfileId: string;\n responseApplicationProfileId: string;\n spectralResponseProfileId: string;\n colorSamplingProfileId: string;\n channelId: string;\n requiredSignalPath:\n SensorResponseSignalPath;\n inputRange:\n SensorResponseOperatingInputRange;\n evaluatedInput: {\n kind:\n SensorResponseOperatingInputRange[\"kind\"];\n unit:\n SensorResponseOperatingInputRange[\"unit\"];\n value: number;\n };\n wavelengthApplicability:\n SensorResponseOperatingWavelengthApplicability;\n evaluatedWavelengthRangeNanometers: {\n minimum: number;\n maximum: number;\n };\n linearityCriterion:\n SensorResponseLinearityCriterion;\n spectralInputModel:\n SensorResponseOperatingSpectralInputModel;\n evaluatedSpectralNodeInputs?:\n readonly {\n spectralSampleIndex: number;\n wavelengthNanometers: number;\n wavelengthMeasureNanometers: number;\n kind:\n SensorResponseOperatingInputRange[\"kind\"];\n unit:\n SensorResponseOperatingInputRange[\"unit\"];\n value: number;\n }[];\n spectralNodeRangeCompatibilityAssessed:\n boolean;\n spatialLinearityModel:\n SensorResponseOperatingSpatialLinearityModel;\n referenceConditionPolicy:\n SensorResponseReferenceConditionPolicy;\n referenceConditions?:\n SensorSpectralReferenceConditions;\n operatingConditions?:\n SensorSpectralReferenceConditions;\n operatingRangeCompatibilityAssessed: true;\n instantaneousResponseRangeCompatible: boolean;\n status:\n | \"broadband-range-compatible\"\n | \"broadband-range-compatible-approximation\"\n | \"rate-conversion-authorized\"\n | \"rate-conversion-authorized-approximation\"\n | \"blocked\";\n blockers:\n readonly SensorResponseOperatingRangeBlocker[];\n responseRateConversionAuthorized: boolean;\n responseApplicationPerformed: false;\n temporalIntegrationAuthorized: false;\n exposureDomainLinearityAssessed: false;\n accumulatedChargeLinearityAssessed: false;\n saturationAssessed: false;\n photonConversionPerformed: false;\n electronConversionPerformed: false;\n currentConversionPerformed: false;\n componentEvidence: {\n operatingRange:\n readonly EvidenceProvenance[];\n referenceConditionAssumption:\n readonly EvidenceProvenance[];\n spatialLinearity:\n readonly EvidenceProvenance[];\n structuralCompatibility:\n SensorResponseApplicationCompatibilityAssessment[\"componentEvidence\"];\n };\n}\n\nexport function parseUncertainty(\n value: unknown,\n path: string\n): SensorSpectralResponseUncertainty {\n const record =\n requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", UNCERTAINTY_VARIANT_FIELDS, path);\n\n if (record.kind === \"relative\") {\n const fraction =\n requireFiniteNonNegative(\n record.fraction,\n path + \".fraction\"\n );\n return {\n kind: \"relative\",\n fraction,\n basis: requireNonEmptyString(\n record.basis,\n path + \".basis\"\n )\n };\n }\n\n if (\n record.kind === \"not-quantified\"\n ) {\n return {\n kind: \"not-quantified\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseReferenceConditions(\n value: unknown,\n path: string\n): SensorSpectralReferenceConditions {\n const record =\n requireRecord(value, path, [\"temperatureC\", \"incidenceAngleDegreesFromNormal\", \"polarization\"]);\n const result:\n SensorSpectralReferenceConditions =\n {};\n\n if (\n record.temperatureC !== undefined\n ) {\n if (\n typeof record.temperatureC !==\n \"number\" ||\n !Number.isFinite(\n record.temperatureC\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \".temperatureC must be finite.\"\n );\n }\n result.temperatureC =\n record.temperatureC;\n }\n\n if (\n record.incidenceAngleDegreesFromNormal !==\n undefined\n ) {\n const angle =\n record\n .incidenceAngleDegreesFromNormal;\n if (\n typeof angle !== \"number\" ||\n !Number.isFinite(angle) ||\n angle < 0 ||\n angle > 90\n ) {\n throw new InvalidConfigurationError(\n path +\n \".incidenceAngleDegreesFromNormal must be finite from 0 through 90.\"\n );\n }\n result.incidenceAngleDegreesFromNormal =\n angle;\n }\n\n if (\n record.polarization !== undefined\n ) {\n if (\n record.polarization !==\n \"unpolarized\" &&\n record.polarization !==\n \"unspecified\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \".polarization is invalid.\"\n );\n }\n result.polarization =\n record.polarization;\n }\n\n if (\n result.temperatureC === undefined &&\n result\n .incidenceAngleDegreesFromNormal ===\n undefined &&\n result.polarization === undefined\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must declare at least one condition.\"\n );\n }\n\n return result;\n}\n\nfunction parseInputRange(\n value: unknown,\n path: string\n): SensorResponseOperatingInputRange {\n const record =\n requireRecord(value, path, [\"minimumInclusive\", \"maximumInclusive\", \"kind\", \"unit\"]);\n\n const minimumInclusive =\n requireFiniteNonNegative(\n record.minimumInclusive,\n path + \".minimumInclusive\"\n );\n const maximumInclusive =\n requirePositiveFinite(\n record.maximumInclusive,\n path + \".maximumInclusive\"\n );\n\n if (\n minimumInclusive >=\n maximumInclusive\n ) {\n throw new InvalidConfigurationError(\n path +\n \".minimumInclusive must be less than maximumInclusive.\"\n );\n }\n\n if (\n record.kind ===\n \"wavelength-integrated-geometric-aperture-radiant-power\"\n ) {\n if (record.unit !== \"W\") {\n throw new InvalidConfigurationError(\n path +\n '.unit must be \"W\".'\n );\n }\n return {\n kind:\n \"wavelength-integrated-geometric-aperture-radiant-power\",\n unit: \"W\",\n minimumInclusive,\n maximumInclusive\n };\n }\n\n if (\n record.kind ===\n \"wavelength-integrated-spatial-average-irradiance\"\n ) {\n if (record.unit !== \"W/m^2\") {\n throw new InvalidConfigurationError(\n path +\n '.unit must be \"W/m^2\".'\n );\n }\n return {\n kind:\n \"wavelength-integrated-spatial-average-irradiance\",\n unit: \"W/m^2\",\n minimumInclusive,\n maximumInclusive\n };\n }\n\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseWavelengthApplicability(\n value: unknown,\n path: string\n): SensorResponseOperatingWavelengthApplicability {\n const record =\n requireRecord(value, path, [\"wavelengthBasis\", \"minimumNanometers\", \"maximumNanometers\", \"containment\"]);\n\n if (\n record.wavelengthBasis !== \"air\" &&\n record.wavelengthBasis !==\n \"vacuum\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.wavelengthBasis must be \"air\" or \"vacuum\".'\n );\n }\n\n const minimumNanometers =\n requirePositiveFinite(\n record.minimumNanometers,\n path + \".minimumNanometers\"\n );\n const maximumNanometers =\n requirePositiveFinite(\n record.maximumNanometers,\n path + \".maximumNanometers\"\n );\n\n if (\n minimumNanometers >=\n maximumNanometers\n ) {\n throw new InvalidConfigurationError(\n path +\n \".minimumNanometers must be less than maximumNanometers.\"\n );\n }\n\n if (\n record.containment !==\n \"requested-range-must-be-contained\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.containment must be \"requested-range-must-be-contained\".'\n );\n }\n\n return {\n wavelengthBasis:\n record.wavelengthBasis,\n minimumNanometers,\n maximumNanometers,\n containment:\n \"requested-range-must-be-contained\"\n };\n}\n\nfunction parseLinearityCriterion(\n value: unknown,\n path: string\n): SensorResponseLinearityCriterion {\n const record =\n requireRecord(value, path, [\"maximumAbsoluteRelativeDeviation\"]);\n const maximumAbsoluteRelativeDeviation =\n requireFiniteNonNegative(\n record\n .maximumAbsoluteRelativeDeviation,\n path +\n \".maximumAbsoluteRelativeDeviation\"\n );\n\n if (\n maximumAbsoluteRelativeDeviation >\n 1\n ) {\n throw new InvalidConfigurationError(\n path +\n \".maximumAbsoluteRelativeDeviation must be a fraction from 0 through 1.\"\n );\n }\n\n return {\n maximumAbsoluteRelativeDeviation\n };\n}\n\nfunction parseSpectralInputModel(\n value: unknown\n): SensorResponseOperatingSpectralInputModel {\n if (value === undefined) {\n return {\n kind: \"broadband-integrated-only\"\n };\n }\n\n const record = requireRecord(\n value,\n \"sensorResponseOperatingRange.spectralInputModel\", null\n );\n rejectUnknownVariantFields(record, \"kind\", { \"broadband-integrated-only\": [\"kind\"], \"per-spectral-bin\": [\"kind\", \"maximumBinWidthNanometers\", \"scientificStatus\", \"evidence\", \"limitation\"] }, \"sensorResponseOperatingRange.spectralInputModel\");\n\n if (\n record.kind ===\n \"broadband-integrated-only\"\n ) {\n return {\n kind: \"broadband-integrated-only\"\n };\n }\n\n if (\n record.kind !==\n \"per-spectral-bin\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spectralInputModel.kind is invalid.\"\n );\n }\n\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spectralInputModel.scientificStatus is invalid.\"\n );\n }\n\n const maximumBinWidthNanometers =\n requirePositiveFinite(\n record.maximumBinWidthNanometers,\n \"sensorResponseOperatingRange.spectralInputModel.maximumBinWidthNanometers\"\n );\n const limitation =\n record.limitation === undefined\n ? undefined\n : requireNonEmptyString(\n record.limitation,\n \"sensorResponseOperatingRange.spectralInputModel.limitation\"\n );\n\n if (\n record.scientificStatus ===\n \"approximation\" &&\n limitation === undefined\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spectralInputModel.limitation is required for an approximation.\"\n );\n }\n\n return {\n kind: \"per-spectral-bin\",\n maximumBinWidthNanometers,\n scientificStatus:\n record.scientificStatus,\n evidence: parseEvidenceList(\n record.evidence,\n \"sensorResponseOperatingRange.spectralInputModel.evidence\"\n ),\n ...(limitation === undefined\n ? {}\n : { limitation })\n };\n}\n\nfunction parseSpatialLinearityModel(\n value: unknown\n): SensorResponseOperatingSpatialLinearityModel {\n if (value === undefined) {\n return {\n kind: \"not-established\",\n limitation:\n \"Spatial-distribution linear superposition was not declared.\"\n };\n }\n\n const record = requireRecord(\n value,\n \"sensorResponseOperatingRange.spatialLinearityModel\", null\n );\n rejectUnknownVariantFields(record, \"kind\", { \"not-established\": [\"kind\", \"limitation\"], \"linear-superposition-over-geometric-aperture\": [\"kind\", \"scientificStatus\", \"evidence\", \"limitation\"] }, \"sensorResponseOperatingRange.spatialLinearityModel\");\n\n if (\n record.kind === \"not-established\"\n ) {\n return {\n kind: \"not-established\",\n limitation: requireNonEmptyString(\n record.limitation,\n \"sensorResponseOperatingRange.spatialLinearityModel.limitation\"\n )\n };\n }\n\n if (\n record.kind !==\n \"linear-superposition-over-geometric-aperture\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spatialLinearityModel.kind is invalid.\"\n );\n }\n\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spatialLinearityModel.scientificStatus is invalid.\"\n );\n }\n\n const limitation =\n record.limitation === undefined\n ? undefined\n : requireNonEmptyString(\n record.limitation,\n \"sensorResponseOperatingRange.spatialLinearityModel.limitation\"\n );\n\n if (\n record.scientificStatus ===\n \"approximation\" &&\n limitation === undefined\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.spatialLinearityModel.limitation is required for an approximation.\"\n );\n }\n\n return {\n kind:\n \"linear-superposition-over-geometric-aperture\",\n scientificStatus:\n record.scientificStatus,\n evidence: parseEvidenceList(\n record.evidence,\n \"sensorResponseOperatingRange.spatialLinearityModel.evidence\"\n ),\n ...(limitation === undefined\n ? {}\n : { limitation })\n };\n}\n\n/**\n * Validates untrusted input and returns it as a normalized, typed value. Unknown enum values,\n * missing required fields and inconsistent scientific data are rejected.\n *\n * The profile states the input quantity (incident power or irradiance), wavelength coverage,\n * reference conditions and non-linearity criterion of the calibrated operating range.\n * @param value - Untrusted data. TypeScript types alone are not validation.\n * @returns The result. Success does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the package export and its full type definitions.\n */\nexport function parseSensorResponseOperatingRangeProfile(\n value: unknown\n): SensorResponseOperatingRangeProfile {\n const record =\n requireRecord(\n value,\n \"sensorResponseOperatingRange\", [\"schemaVersion\", \"scientificStatus\", \"referenceConditions\", \"referenceConditionPolicy\", \"uncertainty\", \"profileId\", \"responseApplicationProfileId\", \"spectralResponseProfileId\", \"colorSamplingProfileId\", \"channelId\", \"evidence\", \"inputRange\", \"wavelengthApplicability\", \"linearityCriterion\", \"spatialLinearityModel\", \"spectralInputModel\"]\n );\n\n if (\n record.schemaVersion !== \"0.1.0\"\n ) {\n throw new InvalidConfigurationError(\n 'sensorResponseOperatingRange.schemaVersion must be \"0.1.0\".'\n );\n }\n\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.scientificStatus is invalid.\"\n );\n }\n\n const referenceConditions =\n record.referenceConditions ===\n undefined\n ? undefined\n : parseReferenceConditions(\n record.referenceConditions,\n \"sensorResponseOperatingRange.referenceConditions\"\n );\n\n const referenceConditionPolicy =\n parseReferenceConditionPolicy(\n record.referenceConditionPolicy,\n \"sensorResponseOperatingRange.referenceConditionPolicy\"\n );\n\n if (\n referenceConditionPolicy.kind ===\n \"exact-match-required\" &&\n referenceConditions === undefined\n ) {\n throw new InvalidConfigurationError(\n \"sensorResponseOperatingRange.referenceConditions is required when exact-match-required is selected.\"\n );\n }\n\n const uncertainty =\n parseUncertainty(\n record.uncertainty,\n \"sensorResponseOperatingRange.uncertainty\"\n );\n\n if (\n record.scientificStatus ===\n \"calibrated\" &&\n uncertainty.kind ===\n \"not-quantified\"\n ) {\n throw new InvalidConfigurationError(\n \"A calibrated sensor response operating range must declare quantified relative uncertainty.\"\n );\n }\n\n return {\n schemaVersion: \"0.1.0\",\n profileId: requireNonEmptyString(\n record.profileId,\n \"sensorResponseOperatingRange.profileId\"\n ),\n responseApplicationProfileId:\n requireNonEmptyString(\n record\n .responseApplicationProfileId,\n \"sensorResponseOperatingRange.responseApplicationProfileId\"\n ),\n spectralResponseProfileId:\n requireNonEmptyString(\n record\n .spectralResponseProfileId,\n \"sensorResponseOperatingRange.spectralResponseProfileId\"\n ),\n colorSamplingProfileId:\n requireNonEmptyString(\n record.colorSamplingProfileId,\n \"sensorResponseOperatingRange.colorSamplingProfileId\"\n ),\n channelId:\n requireNonEmptyString(\n record.channelId,\n \"sensorResponseOperatingRange.channelId\"\n ),\n scientificStatus:\n record.scientificStatus,\n uncertainty,\n evidence: parseEvidenceList(\n record.evidence,\n \"sensorResponseOperatingRange.evidence\"\n ),\n inputRange: parseInputRange(\n record.inputRange,\n \"sensorResponseOperatingRange.inputRange\"\n ),\n wavelengthApplicability:\n parseWavelengthApplicability(\n record.wavelengthApplicability,\n \"sensorResponseOperatingRange.wavelengthApplicability\"\n ),\n linearityCriterion:\n parseLinearityCriterion(\n record.linearityCriterion,\n \"sensorResponseOperatingRange.linearityCriterion\"\n ),\n spatialLinearityModel:\n parseSpatialLinearityModel(\n record.spatialLinearityModel\n ),\n spectralInputModel:\n parseSpectralInputModel(\n record.spectralInputModel\n ),\n ...(referenceConditions ===\n undefined\n ? {}\n : { referenceConditions }),\n referenceConditionPolicy\n };\n}\n\nfunction requireReductionMetric(\n reduction:\n SensorSpatioSpectralIrradianceReduction,\n range:\n SensorResponseOperatingInputRange\n): number {\n const value =\n range.kind ===\n \"wavelength-integrated-geometric-aperture-radiant-power\"\n ? reduction\n .wavelengthIntegratedGeometricApertureIncidentFluxWatts\n : reduction\n .wavelengthIntegratedSpatialAverageIrradianceWattsPerSquareMeter;\n\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < 0\n ) {\n throw new InvalidScientificInputError(\n \"The selected operating-range input metric must be finite and nonnegative.\"\n );\n }\n return value;\n}\n\nfunction spectralNodeInputValue(\n entry:\n SensorSpatioSpectralIrradianceReduction[\"perWavelength\"][number],\n range:\n SensorResponseOperatingInputRange\n): number {\n const value =\n range.kind ===\n \"wavelength-integrated-geometric-aperture-radiant-power\"\n ? entry\n .wavelengthIntegratedGeometricApertureIncidentFluxContributionWatts\n : entry\n .wavelengthIntegratedSpatialAverageContributionWattsPerSquareMeter;\n\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < 0\n ) {\n throw new InvalidScientificInputError(\n \"Per-spectral-node operating-range input must be finite and nonnegative.\"\n );\n }\n return value;\n}\n\nfunction validateReductionIdentity(\n reduction:\n SensorSpatioSpectralIrradianceReduction,\n compatibility:\n SensorResponseApplicationCompatibilityAssessment\n): void {\n requireInputObject(reduction, \"reduction input\");\n if (\n reduction.responseProfileId !==\n compatibility\n .spectralResponseProfileId ||\n reduction.colorSamplingProfileId !==\n compatibility\n .colorSamplingProfileId ||\n reduction.channelId !==\n compatibility.channelId\n ) {\n throw new InvalidScientificInputError(\n \"reduction and compatibility assessment identities do not match.\"\n );\n }\n}\n\n/**\n * Checks every declared spectral-bin input against the operating range and the superposition\n * requirement, before any instantaneous response conversion is allowed.\n *\n * Each bin must be in range, and spatial linear superposition must hold. A valid average must not\n * hide a part of the aperture that is too bright.\n * @param input - The input; see `AssessSensorResponseOperatingRangeInput` for its fields, units and coordinates.\n * @returns The assessment. Read its structured blockers before acting on an authorization.\n *\n * @see docs/API_REFERENCE.md for the package export and its full type definitions.\n */\nexport function assessSensorResponseOperatingRange(\n input:\n AssessSensorResponseOperatingRangeInput\n): CalculationResult<SensorResponseOperatingRangeAssessment> {\n requireInputKeys(input, \"assessSensorResponseOperatingRange\", [\"reduction\", \"compatibility\", \"operatingRangeProfile\"]);\n validateReductionIdentity(\n input.reduction,\n input.compatibility\n );\n const profile =\n parseSensorResponseOperatingRangeProfile(\n input.operatingRangeProfile\n );\n const blockers:\n SensorResponseOperatingRangeBlocker[] =\n [];\n\n if (\n !input.compatibility\n .structuralCompatibilityEstablished ||\n input.compatibility\n .compatibilityStatus === \"blocked\"\n ) {\n blockers.push(\n \"structural-compatibility-not-established\"\n );\n }\n\n if (\n profile.responseApplicationProfileId !==\n input.compatibility\n .applicationProfileId\n ) {\n blockers.push(\n \"response-application-profile-id-mismatch\"\n );\n }\n if (\n profile.spectralResponseProfileId !==\n input.reduction\n .responseProfileId\n ) {\n blockers.push(\n \"spectral-response-profile-id-mismatch\"\n );\n }\n if (\n profile.colorSamplingProfileId !==\n input.reduction\n .colorSamplingProfileId\n ) {\n blockers.push(\n \"color-sampling-profile-id-mismatch\"\n );\n }\n if (\n profile.channelId !==\n input.reduction.channelId\n ) {\n blockers.push(\n \"channel-id-mismatch\"\n );\n }\n\n if (\n !input.reduction\n .wavelengthBasisResolved\n ) {\n blockers.push(\n \"wavelength-basis-unresolved\"\n );\n } else if (\n input.reduction.wavelengthBasis !==\n profile.wavelengthApplicability\n .wavelengthBasis\n ) {\n blockers.push(\n \"wavelength-basis-mismatch\"\n );\n }\n\n const wavelengthRange =\n input.reduction\n .wavelengthRangeNanometers;\n if (\n wavelengthRange.minimum <\n profile.wavelengthApplicability\n .minimumNanometers ||\n wavelengthRange.maximum >\n profile.wavelengthApplicability\n .maximumNanometers\n ) {\n blockers.push(\n \"wavelength-range-outside-linearity-applicability\"\n );\n }\n\n const metricValue =\n requireReductionMetric(\n input.reduction,\n profile.inputRange\n );\n\n if (\n metricValue <\n profile.inputRange.minimumInclusive\n ) {\n blockers.push(\n \"input-below-linearity-range\"\n );\n }\n if (\n metricValue >\n profile.inputRange.maximumInclusive\n ) {\n blockers.push(\n \"input-above-linearity-range\"\n );\n }\n\n const spectralInputModel =\n profile.spectralInputModel ?? {\n kind: \"broadband-integrated-only\" as const\n };\n const evaluatedSpectralNodeInputs:\n {\n spectralSampleIndex: number;\n wavelengthNanometers: number;\n wavelengthMeasureNanometers: number;\n kind:\n SensorResponseOperatingInputRange[\"kind\"];\n unit:\n SensorResponseOperatingInputRange[\"unit\"];\n value: number;\n }[] = [];\n\n if (\n spectralInputModel.kind ===\n \"per-spectral-bin\"\n ) {\n for (\n const entry of\n input.reduction.perWavelength\n ) {\n if (\n entry.wavelengthMeasureNanometers >\n spectralInputModel\n .maximumBinWidthNanometers\n ) {\n blockers.push(\n \"spectral-bin-width-outside-linearity-applicability\"\n );\n }\n\n const value =\n spectralNodeInputValue(\n entry,\n profile.inputRange\n );\n evaluatedSpectralNodeInputs.push({\n spectralSampleIndex:\n entry.spectralSampleIndex,\n wavelengthNanometers:\n entry.wavelengthNanometers,\n wavelengthMeasureNanometers:\n entry.wavelengthMeasureNanometers,\n kind:\n profile.inputRange.kind,\n unit:\n profile.inputRange.unit,\n value\n });\n\n if (\n value <\n profile.inputRange\n .minimumInclusive\n ) {\n blockers.push(\n \"spectral-bin-input-below-linearity-range\"\n );\n }\n if (\n value >\n profile.inputRange\n .maximumInclusive\n ) {\n blockers.push(\n \"spectral-bin-input-above-linearity-range\"\n );\n }\n }\n }\n\n if (\n profile.spatialLinearityModel?.kind !==\n \"linear-superposition-over-geometric-aperture\"\n ) {\n blockers.push(\n \"spatial-linearity-superposition-not-established\"\n );\n }\n\n if (\n profile.referenceConditionPolicy.kind ===\n \"exact-match-required\"\n ) {\n const referenceConditions =\n profile.referenceConditions!;\n if (\n input.compatibility\n .operatingConditions ===\n undefined\n ) {\n blockers.push(\n \"operating-conditions-not-declared\"\n );\n } else if (\n !conditionsMatch(\n referenceConditions,\n input.compatibility\n .operatingConditions\n )\n ) {\n blockers.push(\n \"linearity-operating-conditions-mismatch\"\n );\n }\n }\n\n const compatible =\n blockers.length === 0;\n\n const approximate =\n input.compatibility\n .compatibilityStatus ===\n \"compatible-approximation\" ||\n profile.scientificStatus ===\n \"approximation\" ||\n profile.uncertainty.kind ===\n \"not-quantified\" ||\n (\n profile.spatialLinearityModel?.kind ===\n \"linear-superposition-over-geometric-aperture\" &&\n profile.spatialLinearityModel\n .scientificStatus ===\n \"approximation\"\n ) ||\n (\n spectralInputModel.kind ===\n \"per-spectral-bin\" &&\n spectralInputModel\n .scientificStatus ===\n \"approximation\"\n ) ||\n profile.referenceConditionPolicy.kind ===\n \"assume-compatible\";\n\n const spectralRateReady =\n compatible &&\n spectralInputModel.kind ===\n \"per-spectral-bin\";\n\n const status =\n compatible\n ? spectralRateReady\n ? approximate\n ? \"rate-conversion-authorized-approximation\"\n : \"rate-conversion-authorized\"\n : approximate\n ? \"broadband-range-compatible-approximation\"\n : \"broadband-range-compatible\"\n : \"blocked\";\n\n const referenceConditionEvidence =\n profile.referenceConditionPolicy.kind ===\n \"assume-compatible\"\n ? profile.referenceConditionPolicy\n .evidence\n : [];\n const spatialLinearityEvidence =\n profile.spatialLinearityModel?.kind ===\n \"linear-superposition-over-geometric-aperture\"\n ? profile.spatialLinearityModel.evidence\n : [];\n\n return calculatedResult(\n {\n operatingRangeProfileId:\n profile.profileId,\n responseApplicationProfileId:\n input.compatibility\n .applicationProfileId,\n spectralResponseProfileId:\n input.reduction\n .responseProfileId,\n colorSamplingProfileId:\n input.reduction\n .colorSamplingProfileId,\n channelId:\n input.reduction.channelId,\n requiredSignalPath:\n input.compatibility\n .requiredSignalPath,\n inputRange:\n profile.inputRange,\n evaluatedInput: {\n kind: profile.inputRange.kind,\n unit: profile.inputRange.unit,\n value: metricValue\n },\n wavelengthApplicability:\n profile.wavelengthApplicability,\n evaluatedWavelengthRangeNanometers:\n {\n ...wavelengthRange\n },\n linearityCriterion:\n profile.linearityCriterion,\n spectralInputModel,\n ...(evaluatedSpectralNodeInputs.length ===\n 0\n ? {}\n : {\n evaluatedSpectralNodeInputs\n }),\n spectralNodeRangeCompatibilityAssessed:\n spectralInputModel.kind ===\n \"per-spectral-bin\",\n spatialLinearityModel:\n profile.spatialLinearityModel ?? {\n kind: \"not-established\",\n limitation:\n \"Spatial-distribution linear superposition was not declared.\"\n },\n referenceConditionPolicy:\n profile.referenceConditionPolicy,\n ...(profile.referenceConditions ===\n undefined\n ? {}\n : {\n referenceConditions:\n profile.referenceConditions\n }),\n ...(input.compatibility\n .operatingConditions ===\n undefined\n ? {}\n : {\n operatingConditions:\n input.compatibility\n .operatingConditions\n }),\n operatingRangeCompatibilityAssessed:\n true,\n instantaneousResponseRangeCompatible:\n compatible,\n status,\n blockers,\n responseRateConversionAuthorized:\n spectralRateReady,\n responseApplicationPerformed:\n false,\n temporalIntegrationAuthorized:\n false,\n exposureDomainLinearityAssessed:\n false,\n accumulatedChargeLinearityAssessed:\n false,\n saturationAssessed: false,\n photonConversionPerformed:\n false,\n electronConversionPerformed:\n false,\n currentConversionPerformed:\n false,\n componentEvidence: {\n operatingRange:\n profile.evidence,\n referenceConditionAssumption:\n referenceConditionEvidence,\n spatialLinearity:\n spatialLinearityEvidence,\n structuralCompatibility:\n input.compatibility\n .componentEvidence\n }\n },\n \"sensor-response-operating-range-assessment\",\n \"1.0.0\",\n [\n \"This gate assesses instantaneous response-law applicability only; it does not apply response or integrate exposure.\",\n \"The valid optical-input range is evidence-backed and must be expressed in the same wavelength-integrated power or irradiance domain produced by the pre-response reducer.\",\n \"Broadband-integrated range compatibility alone cannot authorize wavelength-dependent response conversion; per-spectral-bin applicability must be explicitly established and every bin must remain inside the calibrated input range.\",\n \"Per-spectral-bin applicability also declares a maximum supported bin width so a broad quadrature bin is not silently treated as an equivalent monochromatic calibration point.\",\n \"Linearity can depend on optical input level and wavelength; the reduction wavelength range must remain inside the declared applicability range.\",\n \"Post-spatial rate conversion additionally requires explicit linear superposition over the geometric aperture; otherwise sub-aperture illumination patterns could hide local nonlinear behavior.\",\n \"The maximumAbsoluteRelativeDeviation criterion documents the tolerated response nonlinearity for the declared valid range; this function does not derive that criterion from synthetic data.\",\n \"Reference conditions for the linearity calibration are separate from spectral-response reference conditions and must match when exact matching is required.\",\n \"Exposure-domain linearity, accumulated-charge saturation/full-well behavior, and downstream electronics linearity are intentionally not assessed here.\",\n \"A successful result authorizes only a future instantaneous rate conversion path: photon-rate→electrons for EQE/filter×EQE or radiant-power→current for A/W responsivity.\",\n \"Temporal integration, saturation, noise, ADC/RAW conversion and reconstruction remain downstream.\"\n ]\n );\n}\n"]}
@@ -17,96 +17,11 @@ import { parseEvidenceList } from "../core/evidence-provenance.js";
17
17
  import { InvalidScientificInputError } from "../core/validation.js";
18
18
  import { parseSensorColorSamplingProfile } from "./color-sampling.js";
19
19
  import { createSensorSpectralResponseChannelBinding, requireCurrentSensorSpectralResponseChannelBinding, parseSensorSpectralResponseProfile, resolveParsedSensorSpectralResponseAtWavelength } from "./spectral-response.js";
20
- import { requireInputObject, requireInputKeys, rejectUnknownFields, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS } from "../core/record-validation.js";
20
+ import { requireInputObject, requireInputKeys, rejectUnknownVariantFields, requireConfigRecord as requireRecord, requireConfigString as requireNonEmptyString, requireConfigPositiveFinite as requirePositiveFiniteConfiguration, requireInputNonNegativeFinite as requireNonNegativeFiniteInput, requireInputPositiveFinite as requirePositiveFiniteInput, requireInputNonNegativeSafeInteger as requireSafeNonNegativeInteger } from "../core/record-validation.js";
21
+ import { addCompensated } from "../core/shared-helpers.js";
22
+ import { parseReferenceConditionPolicy as parseConditionPolicy } from "./response-application-compatibility.js";
23
+ import { parseUncertainty } from "./response-operating-range.js";
21
24
  const REDUCTION_TOLERANCE = 1e-10;
22
- function addCompensated(state, value) {
23
- const adjusted = value - state.correction;
24
- const next = state.sum + adjusted;
25
- state.correction =
26
- (next - state.sum) - adjusted;
27
- state.sum = next;
28
- }
29
- function requireRecord(value, path, allowedKeys) {
30
- if (typeof value !== "object" ||
31
- value === null ||
32
- Array.isArray(value)) {
33
- throw new InvalidConfigurationError(path + " must be an object.");
34
- }
35
- if (allowedKeys !== null)
36
- rejectUnknownFields(value, allowedKeys, path);
37
- return value;
38
- }
39
- function requireNonEmptyString(value, path) {
40
- if (typeof value !== "string" ||
41
- value.trim().length === 0) {
42
- throw new InvalidConfigurationError(path + " must be a non-empty string.");
43
- }
44
- return value;
45
- }
46
- function requireFiniteNonNegative(value, path) {
47
- if (typeof value !== "number" ||
48
- !Number.isFinite(value) ||
49
- value < 0) {
50
- throw new InvalidConfigurationError(path +
51
- " must be finite and greater than or equal to zero.");
52
- }
53
- return value;
54
- }
55
- function requirePositiveFiniteConfiguration(value, path) {
56
- if (typeof value !== "number" ||
57
- !Number.isFinite(value) ||
58
- value <= 0) {
59
- throw new InvalidConfigurationError(path +
60
- " must be finite and greater than zero.");
61
- }
62
- return value;
63
- }
64
- function requirePositiveFiniteInput(value, path) {
65
- if (typeof value !== "number" ||
66
- !Number.isFinite(value) ||
67
- value <= 0) {
68
- throw new InvalidScientificInputError(path +
69
- " must be finite and greater than zero.");
70
- }
71
- return value;
72
- }
73
- function requireNonNegativeFiniteInput(value, path) {
74
- if (typeof value !== "number" ||
75
- !Number.isFinite(value) ||
76
- value < 0) {
77
- throw new InvalidScientificInputError(path +
78
- " must be finite and greater than or equal to zero.");
79
- }
80
- return value;
81
- }
82
- function requireSafeNonNegativeInteger(value, path) {
83
- if (typeof value !== "number" ||
84
- !Number.isSafeInteger(value) ||
85
- value < 0) {
86
- throw new InvalidScientificInputError(path +
87
- " must be a non-negative safe integer.");
88
- }
89
- return value;
90
- }
91
- function parseUncertainty(value, path) {
92
- const record = requireRecord(value, path, null);
93
- rejectUnknownVariantFields(record, "kind", UNCERTAINTY_VARIANT_FIELDS, path);
94
- if (record.kind === "relative") {
95
- const fraction = requireFiniteNonNegative(record.fraction, path + ".fraction");
96
- return {
97
- kind: "relative",
98
- fraction,
99
- basis: requireNonEmptyString(record.basis, path + ".basis")
100
- };
101
- }
102
- if (record.kind === "not-quantified") {
103
- return {
104
- kind: "not-quantified",
105
- limitation: requireNonEmptyString(record.limitation, path + ".limitation")
106
- };
107
- }
108
- throw new InvalidConfigurationError(path + ".kind is invalid.");
109
- }
110
25
  function parseElectricalConditions(value, path) {
111
26
  const record = requireRecord(value, path, ["bias", "readoutLoad"]);
112
27
  const bias = requireRecord(record.bias, path + ".bias", null);
@@ -151,25 +66,6 @@ function parseElectricalConditions(value, path) {
151
66
  readoutLoad: parsedReadout
152
67
  };
153
68
  }
154
- function parseConditionPolicy(value, path) {
155
- const record = requireRecord(value, path, null);
156
- rejectUnknownVariantFields(record, "kind", { "exact-match-required": ["kind"], "assume-compatible": ["kind", "limitation", "evidence"] }, path);
157
- if (record.kind ===
158
- "exact-match-required") {
159
- return {
160
- kind: "exact-match-required"
161
- };
162
- }
163
- if (record.kind ===
164
- "assume-compatible") {
165
- return {
166
- kind: "assume-compatible",
167
- limitation: requireNonEmptyString(record.limitation, path + ".limitation"),
168
- evidence: parseEvidenceList(record.evidence, path + ".evidence")
169
- };
170
- }
171
- throw new InvalidConfigurationError(path + ".kind is invalid.");
172
- }
173
69
  /**
174
70
  * Validates untrusted input and returns it as a normalized, typed value. Unknown enum values,
175
71
  * missing required fields and inconsistent scientific data are rejected.