@photivra/engine 2.13.0 → 2.14.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 (125) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +7 -7
  4. package/SECURITY.md +1 -1
  5. package/THIRD_PARTY.md +2 -0
  6. package/dist/camera/lens-projection.js +2 -1
  7. package/dist/camera/lens-projection.js.map +1 -1
  8. package/dist/capture/dng-import.js +1 -1
  9. package/dist/capture/dng-import.js.map +1 -1
  10. package/dist/capture/host-yield-cadence.js +1 -1
  11. package/dist/capture/host-yield-cadence.js.map +1 -1
  12. package/dist/capture/native-environment-optical-stage.js +1 -1
  13. package/dist/capture/native-environment-optical-stage.js.map +1 -1
  14. package/dist/capture/native-raw.js +1 -1
  15. package/dist/capture/native-raw.js.map +1 -1
  16. package/dist/capture/packed-sensor-raw.js +3 -3
  17. package/dist/capture/packed-sensor-raw.js.map +1 -1
  18. package/dist/capture/sensor-raw-producer.js +1 -1
  19. package/dist/capture/sensor-raw-producer.js.map +1 -1
  20. package/dist/color/capture-color.js +3 -3
  21. package/dist/color/capture-color.js.map +1 -1
  22. package/dist/color/chromatic-adaptation.js +2 -2
  23. package/dist/color/chromatic-adaptation.js.map +1 -1
  24. package/dist/color/color-matching-functions.js +1 -1
  25. package/dist/color/color-matching-functions.js.map +1 -1
  26. package/dist/color/colorimetry-math.js +2 -2
  27. package/dist/color/colorimetry-math.js.map +1 -1
  28. package/dist/color/illuminants.js +3 -3
  29. package/dist/color/illuminants.js.map +1 -1
  30. package/dist/color/rgb-color-spaces.js +1 -1
  31. package/dist/color/rgb-color-spaces.js.map +1 -1
  32. package/dist/color/sensor-color-development.js +1 -1
  33. package/dist/color/sensor-color-development.js.map +1 -1
  34. package/dist/core/record-validation.js +3 -3
  35. package/dist/core/record-validation.js.map +1 -1
  36. package/dist/core/version.d.ts +1 -1
  37. package/dist/core/version.js +1 -1
  38. package/dist/core/version.js.map +1 -1
  39. package/dist/equipment/generic-prime-lenses.js +3 -3
  40. package/dist/equipment/generic-prime-lenses.js.map +1 -1
  41. package/dist/equipment/generic-tier-assets.d.ts +23 -1
  42. package/dist/equipment/generic-tier-assets.js +58 -30
  43. package/dist/equipment/generic-tier-assets.js.map +1 -1
  44. package/dist/equipment/generic-tier-presets.d.ts +6 -3
  45. package/dist/equipment/generic-tier-presets.js +26 -13
  46. package/dist/equipment/generic-tier-presets.js.map +1 -1
  47. package/dist/exposure/auto-iso-slowest-shutter.js +2 -1
  48. package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
  49. package/dist/exposure/flash-ttl.js +1 -1
  50. package/dist/exposure/flash-ttl.js.map +1 -1
  51. package/dist/exposure/flash.js +1 -1
  52. package/dist/exposure/flash.js.map +1 -1
  53. package/dist/facade/chart-material-layers.js +2 -2
  54. package/dist/facade/chart-material-layers.js.map +1 -1
  55. package/dist/facade/chart-radiance-batch.js +1 -1
  56. package/dist/facade/chart-radiance-batch.js.map +1 -1
  57. package/dist/facade/chart-scenes.d.ts +45 -8
  58. package/dist/facade/chart-scenes.js +101 -44
  59. package/dist/facade/chart-scenes.js.map +1 -1
  60. package/dist/facade/color-patches.d.ts +129 -0
  61. package/dist/facade/color-patches.js +209 -0
  62. package/dist/facade/color-patches.js.map +1 -0
  63. package/dist/facade/display-view-gpu.js +1 -1
  64. package/dist/facade/display-view-gpu.js.map +1 -1
  65. package/dist/facade/scene-radiance.js +2 -2
  66. package/dist/facade/scene-radiance.js.map +1 -1
  67. package/dist/facade/simulate-capture.d.ts +47 -3
  68. package/dist/facade/simulate-capture.js +71 -22
  69. package/dist/facade/simulate-capture.js.map +1 -1
  70. package/dist/facade/simulate-display-view.js +2 -2
  71. package/dist/facade/simulate-display-view.js.map +1 -1
  72. package/dist/gpu/chart-composite-gpu.js +2 -2
  73. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  74. package/dist/gpu/display-view-composite-material-module.js +1 -1
  75. package/dist/gpu/display-view-composite-material-module.js.map +1 -1
  76. package/dist/gpu/image-kernel-execution.js +2 -2
  77. package/dist/gpu/image-kernel-execution.js.map +1 -1
  78. package/dist/gpu/temporal-sum-gpu.js +23 -23
  79. package/dist/gpu/webgpu-runtime.js +1 -1
  80. package/dist/gpu/webgpu-runtime.js.map +1 -1
  81. package/dist/gpu/wgsl-chart-composite-kernel.js +318 -318
  82. package/dist/gpu/wgsl-chart-composite-kernel.js.map +1 -1
  83. package/dist/gpu/wgsl-chart-kernel.js +117 -117
  84. package/dist/gpu/wgsl-chart-kernel.js.map +1 -1
  85. package/dist/gpu/wgsl-display-view-quality-kernel.js +505 -505
  86. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  87. package/dist/gpu/wgsl-display-view-speed-kernel.js +248 -248
  88. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  89. package/dist/gpu/wgsl-kernels.js +203 -203
  90. package/dist/gpu/wgsl-kernels.js.map +1 -1
  91. package/dist/gpu/wgsl-sensor-kernel.js +302 -302
  92. package/dist/gpu/wgsl-sensor-kernel.js.map +1 -1
  93. package/dist/index.d.ts +5 -3
  94. package/dist/index.js +4 -2
  95. package/dist/index.js.map +1 -1
  96. package/dist/motion/temporal-exposure-sum.js +1 -1
  97. package/dist/motion/temporal-exposure-sum.js.map +1 -1
  98. package/dist/optics/diffraction-psf-profile.js +4 -4
  99. package/dist/optics/diffraction-psf-profile.js.map +1 -1
  100. package/dist/optics/front-of-lens-filter.js +1 -1
  101. package/dist/optics/front-of-lens-filter.js.map +1 -1
  102. package/dist/optics/irradiance-convolution.js +1 -1
  103. package/dist/optics/irradiance-convolution.js.map +1 -1
  104. package/dist/output/native-capture-sdr.js +1 -1
  105. package/dist/output/native-capture-sdr.js.map +1 -1
  106. package/dist/output/png-encoder.js +2 -2
  107. package/dist/output/png-encoder.js.map +1 -1
  108. package/dist/output/print-jpeg.js +1 -1
  109. package/dist/output/print-jpeg.js.map +1 -1
  110. package/dist/sensor/fixed-pattern-noise.js +1 -1
  111. package/dist/sensor/fixed-pattern-noise.js.map +1 -1
  112. package/dist/sensor/readout-exposure-linkage.js +1 -1
  113. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  114. package/docs/API_REFERENCE.md +29 -1
  115. package/docs/QUICK_START.md +40 -5
  116. package/docs/USAGE.md +35 -1
  117. package/docs/api/core-version.md +1 -1
  118. package/docs/api/equipment-generic-tier-assets.md +41 -1
  119. package/docs/api/equipment-generic-tier-presets.md +11 -3
  120. package/docs/api/exports.json +107 -2
  121. package/docs/api/facade-chart-scenes.md +36 -5
  122. package/docs/api/facade-color-patches.md +150 -0
  123. package/docs/api/facade-simulate-capture.md +52 -2
  124. package/llms.txt +1 -0
  125. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"flash.js","sourceRoot":"","sources":["../../src/exposure/flash.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Manual flash and flash sync.\n *\n * The parsers validate untrusted input and return the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock.\n * - Ordinary front- or rear-curtain sync needs a real interval when the whole frame is open at once.\n * - High-speed sync (HSS; schema 0.2.0 sync profiles) is separate: a near-continuous burst that\n * covers the travelling shutter slit (resolveHighSpeedFlashSync).\n * - TTL pre-flash power and guide-number relations are in flash-ttl.ts.\n * Source brightness, optical transport and sensor integration have their own contracts.\n * @see docs/USAGE.md for the equations, units, coordinate conventions, known blockers and support\n * limits.\n */\n\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 ResolvedReleaseFrame\n} from \"../capture/release-sequence.js\";\nimport {\n parseSceneIlluminationProfile,\n type SceneIlluminationProfile,\n type SceneIlluminationSource\n} from \"../schema/illumination.js\";\nimport {\n parseSceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalWaveformSample\n} from \"../schema/illumination-temporal.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputObject, requireInputKeys, rejectUnknownFields } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const MANUAL_FLASH_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const FLASH_SYNC_CAPABILITY_SCHEMA_VERSION =\n \"0.1.0\" as const;\n/** Sync-capability schema that may declare high-speed sync (a fast pulse train that acts as continuous light). */\nexport const FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION =\n \"0.2.0\" as const;\n/** Model identity of the pulsed quasi-continuous high-speed-sync burst. */\nexport const HIGH_SPEED_SYNC_MODEL = Object.freeze({\n id: \"flash-hss-quasi-continuous-burst\",\n version: \"1.0.0\"\n} as const);\n\nexport type ManualFlashSyncMode =\n | \"front-curtain\"\n | \"rear-curtain\";\n\nexport type RequestedFlashSyncMode =\n | ManualFlashSyncMode\n | \"high-speed-sync\";\n\nexport interface ManualFlashPulseProfile {\n waveformId: string;\n scientificStatus: \"approximation\";\n supportDurationSeconds: number;\n interpolation: \"piecewise-linear\";\n samples:\n readonly SceneIlluminationTemporalWaveformSample[];\n normalization:\n \"relative-peak-one\";\n evidence:\n readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ManualFlashProfile {\n schemaVersion:\n typeof MANUAL_FLASH_PROFILE_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n sourceTemplate:\n Omit<\n SceneIlluminationSource,\n \"enabled\" |\n \"temporalBehavior\"\n >;\n pulse:\n ManualFlashPulseProfile;\n outputControl: {\n kind:\n \"relative-linear-source-scale\";\n scale: number;\n flashExposureCompensationStops:\n 0;\n };\n ttlModeled: false;\n highSpeedSyncModeled: false;\n recycleBehaviorModeled: false;\n redEyePreflashModeled: false;\n modelingLightModeled: false;\n afAssistModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface FlashSyncCapabilityProfile {\n schemaVersion:\n | typeof FLASH_SYNC_CAPABILITY_SCHEMA_VERSION\n | typeof FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n captureModeId: string;\n timingProfileId: string;\n supportedOrdinarySyncModes:\n readonly ManualFlashSyncMode[];\n /** Schema 0.1.0 is always false; schema 0.2.0 may declare HSS with {@link highSpeedSync}. */\n highSpeedSyncSupported: boolean;\n /** Present exactly when highSpeedSyncSupported is true (schema 0.2.0). */\n highSpeedSync?: {\n /**\n * η: energy of one full-power high-speed-sync burst, as a fraction of one full-power ordinary\n * pulse, in (0, 1]. The caller declares it from evidence (capacitor and thermal limits). It is\n * never inferred.\n */\n burstEnergyFractionOfFullPulse: number;\n evidence: readonly EvidenceProvenance[];\n };\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ResolveManualFlashSyncInput {\n flashEnabled: boolean;\n flashProfile:\n ManualFlashProfile;\n syncCapabilities:\n FlashSyncCapabilityProfile;\n timing:\n ResolvedCaptureModeTiming;\n syncMode:\n RequestedFlashSyncMode;\n releaseFrame?:\n ResolvedReleaseFrame;\n}\n\nexport interface ResolvedManualFlashSync {\n flashEnabled: boolean;\n flashProfileId: string;\n flashProfileVersion: string;\n sourceId: string;\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId:\n string;\n syncMode:\n RequestedFlashSyncMode;\n syncStatus:\n | \"disabled\"\n | \"ordinary-sync-resolved\";\n timeReference:\n \"first-opening-boundary-phase\";\n wholeActiveFrameOpenInterval:\n {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n pulseSupportDurationSeconds:\n number;\n pulseStartSecondsFromCaptureReference:\n number | null;\n pulseEndSecondsFromCaptureReference:\n number | null;\n waveformTimeZeroSecondsFromCaptureReference:\n number | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n number;\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n number;\n }\n | null;\n hssModeled: false;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n whiteBalanceModified: false;\n focusModified: false;\n exposureSettingsModified: false;\n driveModeModified: false;\n supportStateModified: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\n/** Fields of a resolved sync (ordinary or HSS) needed to register a flash overlay. */\nexport type FlashOverlaySyncRegistration = Pick<\n ResolvedManualFlashSync,\n | \"flashEnabled\"\n | \"flashProfileId\"\n | \"flashProfileVersion\"\n | \"sourceId\"\n | \"waveformTimeZeroSecondsFromCaptureReference\"\n | \"evidence\"\n>;\n\nexport interface CreateManualFlashIlluminationOverlayInput {\n baseIlluminationProfile:\n SceneIlluminationProfile;\n baseTemporalProfile?:\n SceneIlluminationTemporalProfile;\n flashProfile:\n ManualFlashProfile;\n resolvedSync:\n FlashOverlaySyncRegistration;\n illuminationProfileId: string;\n temporalProfileId: string;\n}\n\nexport interface ManualFlashIlluminationOverlay {\n flashApplied: boolean;\n illuminationProfile:\n SceneIlluminationProfile;\n temporalProfile:\n SceneIlluminationTemporalProfile | null;\n sourceId: string;\n waveformId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n sourceMagnitudeAppliedBySceneTransport:\n true;\n materialTransportOwnedBySceneRadiance:\n true;\n visibilityOwnedBySceneRadiance:\n true;\n indirectTransportOwnedBySceneRadiance:\n true;\n postRenderBrightnessMultiplierUsed:\n false;\n whiteBalanceModified: false;\n ambientMeteringModified: false;\n ttlMeteringIncluded: false;\n ambientTemporalBehaviorPreserved:\n true;\n}\n\nconst ORDINARY_SYNC_MODES =\n new Set<ManualFlashSyncMode>([\n \"front-curtain\",\n \"rear-curtain\"\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 +\n \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be finite.\"\n );\n }\n return value;\n}\n\nfunction requirePositiveFinite(\n value: unknown,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (parsed <= 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than zero.\"\n );\n }\n return parsed;\n}\n\nfunction parseLimitations(\n value: unknown,\n path: string\n): readonly string[] {\n if (!Array.isArray(value)) {\n throw new InvalidConfigurationError(\n path + \" must be an array.\"\n );\n }\n const parsed =\n value.map((entry, index) =>\n requireNonEmptyString(\n entry,\n path +\n \"[\" +\n index +\n \"]\"\n )\n );\n if (\n new Set(parsed).size !==\n parsed.length\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must not contain duplicates.\"\n );\n }\n return parsed;\n}\n\nfunction parsePulseSamples(\n value: unknown,\n supportDurationSeconds:\n number,\n path: string\n): readonly SceneIlluminationTemporalWaveformSample[] {\n if (\n !Array.isArray(value) ||\n value.length < 2\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must contain at least two waveform samples.\"\n );\n }\n const samples =\n value.map((entry, index) => {\n const samplePath =\n path +\n \"[\" +\n index +\n \"]\";\n const record =\n requireRecord(\n entry,\n samplePath, [\"timeSecondsFromWaveformReference\", \"relativeMagnitudeMultiplier\"]\n );\n const time =\n requireFinite(\n record\n .timeSecondsFromWaveformReference,\n samplePath +\n \".timeSecondsFromWaveformReference\"\n );\n const magnitude =\n requireFinite(\n record\n .relativeMagnitudeMultiplier,\n samplePath +\n \".relativeMagnitudeMultiplier\"\n );\n if (\n time < 0 ||\n time >\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n samplePath +\n \".timeSecondsFromWaveformReference must lie within the declared pulse support.\"\n );\n }\n if (magnitude < 0) {\n throw new InvalidConfigurationError(\n samplePath +\n \".relativeMagnitudeMultiplier must be nonnegative.\"\n );\n }\n return {\n timeSecondsFromWaveformReference:\n time,\n relativeMagnitudeMultiplier:\n magnitude\n };\n });\n\n for (\n let index = 1;\n index < samples.length;\n index += 1\n ) {\n if (\n !(\n samples[index]!\n .timeSecondsFromWaveformReference >\n samples[index - 1]!\n .timeSecondsFromWaveformReference\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \" times must be strictly increasing.\"\n );\n }\n }\n if (\n samples[0]!\n .timeSecondsFromWaveformReference !==\n 0 ||\n samples[\n samples.length - 1\n ]!\n .timeSecondsFromWaveformReference !==\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must start at waveform time 0 and end exactly at supportDurationSeconds.\"\n );\n }\n const peak =\n Math.max(\n ...samples.map(\n (sample) =>\n sample\n .relativeMagnitudeMultiplier\n )\n );\n if (\n Math.abs(peak - 1) >\n 1e-12\n ) {\n throw new InvalidConfigurationError(\n path +\n \" peak relative magnitude must equal one for relative-peak-one normalization.\"\n );\n }\n\n return samples;\n}\n\nfunction validateSourceTemplate(\n sourceTemplate:\n ManualFlashProfile[\"sourceTemplate\"]\n): ManualFlashProfile[\"sourceTemplate\"] {\n requireInputObject(sourceTemplate, \"manualFlashProfile.sourceTemplate\");\n const probe =\n parseSceneIlluminationProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n \"manual-flash-source-validation\",\n sceneId:\n \"manual-flash-source-validation\",\n evidence:\n sourceTemplate.evidence,\n sources: [{\n ...sourceTemplate,\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n }],\n sceneRadianceCalculated:\n false,\n materialResponseApplied:\n false,\n visibilityEvaluated:\n false,\n indirectTransportEvaluated:\n false,\n fluorescenceModeled:\n false,\n volumetricTransportModeled:\n false,\n polarizationModeled:\n false\n });\n const source =\n probe.sources[0];\n if (source === undefined) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.sourceTemplate must produce one valid illumination source.\"\n );\n }\n return {\n sourceId:\n source.sourceId,\n family:\n source.family,\n geometry:\n source.geometry,\n magnitude:\n source.magnitude,\n spectrum:\n source.spectrum,\n evidence:\n source.evidence,\n ...(source.limitations ===\n undefined\n ? {}\n : {\n limitations:\n source.limitations\n })\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns ManualFlashProfile. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseManualFlashProfile(\n value: unknown\n): ManualFlashProfile {\n const record =\n requireRecord(\n value,\n \"manualFlashProfile\", [\"schemaVersion\", \"pulse\", \"outputControl\", \"profileId\", \"profileVersion\", \"sourceTemplate\", \"evidence\", \"limitations\", \"ttlModeled\", \"highSpeedSyncModeled\", \"recycleBehaviorModeled\", \"redEyePreflashModeled\", \"modelingLightModeled\", \"afAssistModeled\"]\n );\n if (\n record.schemaVersion !==\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'manualFlashProfile.schemaVersion must be \"' +\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n for (\n const [key, expected] of [\n [\"ttlModeled\", false],\n [\"highSpeedSyncModeled\", false],\n [\"recycleBehaviorModeled\", false],\n [\"redEyePreflashModeled\", false],\n [\"modelingLightModeled\", false],\n [\"afAssistModeled\", false]\n ] as const\n ) {\n if (record[key] !== expected) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.\" +\n key +\n \" must be false in schema 0.1.0.\"\n );\n }\n }\n\n const pulse =\n requireRecord(\n record.pulse,\n \"manualFlashProfile.pulse\", [\"supportDurationSeconds\", \"scientificStatus\", \"interpolation\", \"normalization\", \"waveformId\", \"samples\", \"evidence\", \"limitations\"]\n );\n const supportDurationSeconds =\n requirePositiveFinite(\n pulse.supportDurationSeconds,\n \"manualFlashProfile.pulse.supportDurationSeconds\"\n );\n if (\n pulse.scientificStatus !==\n \"approximation\" ||\n pulse.interpolation !==\n \"piecewise-linear\" ||\n pulse.normalization !==\n \"relative-peak-one\"\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.pulse scientificStatus/interpolation/normalization is invalid.\"\n );\n }\n\n const output =\n requireRecord(\n record.outputControl,\n \"manualFlashProfile.outputControl\", [\"kind\", \"flashExposureCompensationStops\", \"scale\"]\n );\n if (\n output.kind !==\n \"relative-linear-source-scale\" ||\n output\n .flashExposureCompensationStops !==\n 0\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.outputControl must use relative-linear-source-scale with zero flash exposure compensation in the manual-only schema.\"\n );\n }\n\n return {\n schemaVersion:\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"manualFlashProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"manualFlashProfile.profileVersion\"\n ),\n sourceTemplate:\n validateSourceTemplate(\n record.sourceTemplate as\n ManualFlashProfile[\"sourceTemplate\"]\n ),\n pulse: {\n waveformId:\n requireNonEmptyString(\n pulse.waveformId,\n \"manualFlashProfile.pulse.waveformId\"\n ),\n scientificStatus:\n \"approximation\",\n supportDurationSeconds,\n interpolation:\n \"piecewise-linear\",\n samples:\n parsePulseSamples(\n pulse.samples,\n supportDurationSeconds,\n \"manualFlashProfile.pulse.samples\"\n ),\n normalization:\n \"relative-peak-one\",\n evidence:\n parseEvidenceList(\n pulse.evidence,\n \"manualFlashProfile.pulse.evidence\"\n ),\n limitations:\n parseLimitations(\n pulse.limitations,\n \"manualFlashProfile.pulse.limitations\"\n )\n },\n outputControl: {\n kind:\n \"relative-linear-source-scale\",\n scale:\n requirePositiveFinite(\n output.scale,\n \"manualFlashProfile.outputControl.scale\"\n ),\n flashExposureCompensationStops:\n 0\n },\n ttlModeled: false,\n highSpeedSyncModeled: false,\n recycleBehaviorModeled:\n false,\n redEyePreflashModeled:\n false,\n modelingLightModeled:\n false,\n afAssistModeled: false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"manualFlashProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"manualFlashProfile.limitations\"\n )\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns FlashSyncCapabilityProfile. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseFlashSyncCapabilityProfile(\n value: unknown\n): FlashSyncCapabilityProfile {\n const record =\n requireRecord(\n value,\n \"flashSyncCapabilityProfile\", [\"schemaVersion\", \"highSpeedSyncSupported\", \"ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed\", \"highSpeedSync\", \"supportedOrdinarySyncModes\", \"profileId\", \"profileVersion\", \"captureModeId\", \"timingProfileId\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION &&\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'flashSyncCapabilityProfile.schemaVersion must be \"' +\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION +\n '\" or \"' +\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION +\n '\".'\n );\n }\n const hssSchema =\n record.schemaVersion ===\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n if (\n (hssSchema\n ? typeof record.highSpeedSyncSupported !==\n \"boolean\"\n : record.highSpeedSyncSupported !==\n false) ||\n record\n .ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed !==\n true\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile schema 0.1.0 supports ordinary whole-frame sync only and must not claim HSS.\"\n );\n }\n let highSpeedSync:\n FlashSyncCapabilityProfile[\"highSpeedSync\"];\n if (record.highSpeedSyncSupported === true) {\n const hss = requireRecord(\n record.highSpeedSync,\n \"flashSyncCapabilityProfile.highSpeedSync\", [\"burstEnergyFractionOfFullPulse\", \"evidence\"]\n );\n const fraction = requirePositiveFinite(\n hss.burstEnergyFractionOfFullPulse,\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse\"\n );\n if (fraction > 1) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse must be at most 1.\"\n );\n }\n highSpeedSync = {\n burstEnergyFractionOfFullPulse:\n fraction,\n evidence: parseEvidenceList(\n hss.evidence,\n \"flashSyncCapabilityProfile.highSpeedSync.evidence\"\n )\n };\n } else if (\n record.highSpeedSync !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync must be omitted when HSS is unsupported.\"\n );\n }\n if (\n !Array.isArray(\n record.supportedOrdinarySyncModes\n ) ||\n record\n .supportedOrdinarySyncModes\n .length === 0\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must be a non-empty array.\"\n );\n }\n const modes =\n record\n .supportedOrdinarySyncModes\n .map((entry, index) => {\n if (\n typeof entry !==\n \"string\" ||\n !ORDINARY_SYNC_MODES.has(\n entry as ManualFlashSyncMode\n )\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes[\" +\n index +\n \"] is invalid.\"\n );\n }\n return entry as\n ManualFlashSyncMode;\n });\n if (\n new Set(modes).size !==\n modes.length\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must not contain duplicates.\"\n );\n }\n\n return {\n schemaVersion: hssSchema\n ? FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n : FLASH_SYNC_CAPABILITY_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"flashSyncCapabilityProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"flashSyncCapabilityProfile.profileVersion\"\n ),\n captureModeId:\n requireNonEmptyString(\n record.captureModeId,\n \"flashSyncCapabilityProfile.captureModeId\"\n ),\n timingProfileId:\n requireNonEmptyString(\n record.timingProfileId,\n \"flashSyncCapabilityProfile.timingProfileId\"\n ),\n supportedOrdinarySyncModes:\n modes,\n highSpeedSyncSupported:\n highSpeedSync !== undefined,\n ...(highSpeedSync === undefined\n ? {}\n : { highSpeedSync }),\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"flashSyncCapabilityProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"flashSyncCapabilityProfile.limitations\"\n )\n };\n}\n\n/**\n * Shape guard for the resolved capture-mode timing record read by the flash sync functions: every\n * nested object read below must be an object, so a malformed record fails with\n * InvalidConfigurationError instead of a raw TypeError. Values are checked where they are used.\n */\nfunction requireTimingRecordShape(timing: unknown, path: string): void {\n requireInputObject(timing, path);\n const record = timing as Record<string, unknown>;\n if (!Array.isArray(record.evidence)) throw new InvalidConfigurationError(path + \".evidence must be an array.\");\n requireInputObject(record.exposureWindows, path + \".exposureWindows\");\n const windows = record.exposureWindows as Record<string, unknown>;\n requireInputObject(windows.nominalExposureDurationSeconds, path + \".exposureWindows.nominalExposureDurationSeconds\");\n requireInputObject(windows.localExposureDurationRangeSeconds, path + \".exposureWindows.localExposureDurationRangeSeconds\");\n for (const boundary of [\"opening\", \"closing\"] as const) {\n requireInputObject(windows[boundary], path + \".exposureWindows.\" + boundary);\n const schedule = (windows[boundary] as Record<string, unknown>).schedule;\n requireInputObject(schedule, path + \".exposureWindows.\" + boundary + \".schedule\");\n if ((schedule as Record<string, unknown>).kind !== \"simultaneous\") {\n requireInputObject((schedule as Record<string, unknown>).traversalDurationSeconds, path + \".exposureWindows.\" + boundary + \".schedule.traversalDurationSeconds\");\n }\n }\n}\n\nfunction wholeFrameOpenInterval(\n timing:\n ResolvedCaptureModeTiming\n): {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n} {\n const opening =\n timing.exposureWindows.opening\n .schedule;\n const latestOpening =\n opening.kind ===\n \"simultaneous\"\n ? 0\n : opening\n .traversalDurationSeconds\n .value;\n const earliestClosing =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const duration =\n earliestClosing -\n latestOpening;\n return {\n startSecondsFromCaptureReference:\n latestOpening,\n endSecondsFromCaptureReference:\n earliestClosing,\n durationSeconds:\n Math.max(0, duration)\n };\n}\n\nfunction validateReleaseBinding(\n release:\n ResolvedReleaseFrame,\n timing:\n ResolvedCaptureModeTiming\n): void {\n requireInputObject(release, \"releaseFrame\");\n requireInputObject(release.exposure, \"releaseFrame.exposure\");\n const nominal =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const scale =\n Math.max(\n 1,\n Math.abs(nominal),\n Math.abs(\n release.exposure\n .shutterSeconds\n )\n );\n if (\n Math.abs(\n release.exposure\n .shutterSeconds -\n nominal\n ) >\n Number.EPSILON *\n 16 *\n scale\n ) {\n throw new InvalidScientificInputError(\n \"releaseFrame shutter duration must match the exposure duration of the capture-mode exposure-window timing.\"\n );\n }\n}\n\n/**\n * Places a declared ordinary flash pulse inside the actual interval when the whole frame is open, for\n * front- or rear-curtain sync. Otherwise returns a structured incompatibility.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - ResolveManualFlashSyncInput. See that type for coordinates, units and profile binding.\n * @returns ResolvedManualFlashSync. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function resolveManualFlashSync(\n input:\n ResolveManualFlashSyncInput\n): ResolvedManualFlashSync {\n requireInputKeys(input, \"resolveManualFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"syncMode\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveManualFlashSync timing\");\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const capabilities =\n parseFlashSyncCapabilityProfile(\n input.syncCapabilities\n );\n\n if (\n capabilities.captureModeId !==\n input.timing.captureModeId ||\n capabilities.timingProfileId !==\n input.timing.timingProfileId\n ) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (\n input.releaseFrame !==\n undefined\n ) {\n validateReleaseBinding(\n input.releaseFrame,\n input.timing\n );\n }\n\n const openInterval =\n wholeFrameOpenInterval(\n input.timing\n );\n const base = {\n flashProfileId:\n flash.profileId,\n flashProfileVersion:\n flash.profileVersion,\n sourceId:\n flash.sourceTemplate.sourceId,\n captureModeId:\n input.timing.captureModeId,\n timingProfileId:\n input.timing.timingProfileId,\n syncCapabilityProfileId:\n capabilities.profileId,\n syncMode:\n input.syncMode,\n timeReference:\n \"first-opening-boundary-phase\" as const,\n wholeActiveFrameOpenInterval:\n openInterval,\n pulseSupportDurationSeconds:\n flash.pulse\n .supportDurationSeconds,\n hssModeled: false as const,\n ttlModeled: false as const,\n sensorReadoutTimingUsedAsExposureTiming:\n false as const,\n whiteBalanceModified:\n false as const,\n focusModified: false as const,\n exposureSettingsModified:\n false as const,\n driveModeModified:\n false as const,\n supportStateModified:\n false as const,\n evidence: [\n ...flash.evidence,\n ...capabilities.evidence,\n ...input.timing.evidence\n ],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"Ordinary flash synchronization is registered to exposure-boundary timing, never sensor data-readout timing.\",\n \"Schema 0.1.0 does not model HSS, TTL/preflash metering, recycle/thermal limits, red-eye preflash, modeling lights, AF-assist or branded flash protocols.\"\n ]\n };\n\n if (!input.flashEnabled) {\n return {\n flashEnabled: false,\n ...base,\n syncStatus:\n \"disabled\",\n pulseStartSecondsFromCaptureReference:\n null,\n pulseEndSecondsFromCaptureReference:\n null,\n waveformTimeZeroSecondsFromCaptureReference:\n null,\n releaseFrameBinding:\n null\n };\n }\n\n if (\n input.syncMode ===\n \"high-speed-sync\"\n ) {\n throw new InvalidScientificInputError(\n \"High-speed sync is not an ordinary sync mode; ordinary single-pulse flash cannot be used as an HSS substitute. Use resolveHighSpeedFlashSync with an HSS-capable sync profile.\"\n );\n }\n if (\n !capabilities\n .supportedOrdinarySyncModes\n .includes(\n input.syncMode\n )\n ) {\n throw new InvalidScientificInputError(\n \"Requested ordinary flash sync mode is not supported by the capability profile.\"\n );\n }\n if (\n openInterval.durationSeconds <=\n 0\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary one-pulse flash cannot uniformly expose the active frame because the exposure-window timing has no whole-frame-open interval.\"\n );\n }\n if (\n flash.pulse\n .supportDurationSeconds >\n openInterval.durationSeconds\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary flash pulse support does not fit inside the whole-active-frame-open interval.\"\n );\n }\n\n const pulseStart =\n input.syncMode ===\n \"front-curtain\"\n ? openInterval\n .startSecondsFromCaptureReference\n : openInterval\n .endSecondsFromCaptureReference -\n flash.pulse\n .supportDurationSeconds;\n const pulseEnd =\n pulseStart +\n flash.pulse\n .supportDurationSeconds;\n\n const releaseBinding =\n input.releaseFrame ===\n undefined\n ? null\n : {\n sequenceId:\n input.releaseFrame\n .sequenceId,\n releaseFrameId:\n input.releaseFrame\n .releaseFrameId,\n frameIndex:\n input.releaseFrame\n .frameIndex,\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseStart,\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseEnd\n };\n\n return {\n flashEnabled: true,\n ...base,\n syncStatus:\n \"ordinary-sync-resolved\",\n pulseStartSecondsFromCaptureReference:\n pulseStart,\n pulseEndSecondsFromCaptureReference:\n pulseEnd,\n waveformTimeZeroSecondsFromCaptureReference:\n pulseStart,\n releaseFrameBinding:\n releaseBinding\n };\n}\n\nfunction scaledFlashSource(\n flash:\n ManualFlashProfile\n): SceneIlluminationSource {\n const template =\n flash.sourceTemplate;\n const magnitude =\n template.magnitude;\n if (\n magnitude.kind !==\n \"relative-linear-scale\"\n ) {\n throw new InvalidScientificInputError(\n \"Manual flash schema 0.1.0 relative output control requires a relative-linear-scale illumination source magnitude; calibrated physical flash energy belongs to a later profile.\"\n );\n }\n\n return {\n ...template,\n magnitude: {\n ...magnitude,\n scale:\n magnitude.scale *\n flash.outputControl.scale\n },\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n };\n}\n\n/**\n * Builds a temporal illumination overlay from the resolved manual pulse. The identity of the base\n * ambient light source is kept.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - CreateManualFlashIlluminationOverlayInput. See that type for coordinates, units and profile binding.\n * @returns ManualFlashIlluminationOverlay. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function createManualFlashIlluminationOverlay(\n input:\n CreateManualFlashIlluminationOverlayInput\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createManualFlashIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"resolvedSync\", \"illuminationProfileId\", \"temporalProfileId\"]);\n const base =\n parseSceneIlluminationProfile(\n input\n .baseIlluminationProfile\n );\n const baseTemporal =\n input.baseTemporalProfile ===\n undefined\n ? null\n : parseSceneIlluminationTemporalProfile(\n input.baseTemporalProfile\n );\n if (\n baseTemporal !== null &&\n (\n baseTemporal.sceneId !==\n base.sceneId ||\n baseTemporal\n .illuminationProfileId !==\n base.profileId\n )\n ) {\n throw new InvalidScientificInputError(\n \"baseTemporalProfile must exactly match the base illumination profile scene/profile identities.\"\n );\n }\n\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const sync =\n input.resolvedSync;\n requireInputObject(sync, \"createManualFlashIlluminationOverlay resolvedSync\");\n if (!Array.isArray(sync.evidence)) throw new InvalidConfigurationError(\"createManualFlashIlluminationOverlay resolvedSync.evidence must be an array.\");\n\n if (\n sync.flashProfileId !==\n flash.profileId ||\n sync.flashProfileVersion !==\n flash.profileVersion ||\n sync.sourceId !==\n flash.sourceTemplate.sourceId\n ) {\n throw new InvalidScientificInputError(\n \"Resolved flash sync identity must match the manual flash profile.\"\n );\n }\n if (\n base.sources.some(\n (source) =>\n source.sourceId ===\n flash.sourceTemplate\n .sourceId\n )\n ) {\n throw new InvalidScientificInputError(\n \"Flash sourceId must be unique within the base illumination profile.\"\n );\n }\n\n if (!sync.flashEnabled) {\n return {\n flashApplied: false,\n illuminationProfile:\n base,\n temporalProfile:\n baseTemporal,\n sourceId:\n flash.sourceTemplate\n .sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n }\n if (\n sync\n .waveformTimeZeroSecondsFromCaptureReference ===\n null\n ) {\n throw new InvalidScientificInputError(\n \"Enabled flash sync must provide an authoritative waveform time-zero registration.\"\n );\n }\n\n const flashSource =\n scaledFlashSource(\n flash\n );\n const illumination =\n parseSceneIlluminationProfile({\n ...base,\n profileId:\n requireNonEmptyString(\n input.illuminationProfileId,\n \"illuminationProfileId\"\n ),\n sources: [\n ...base.sources,\n flashSource\n ]\n });\n\n const temporal =\n parseSceneIlluminationTemporalProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n requireNonEmptyString(\n input.temporalProfileId,\n \"temporalProfileId\"\n ),\n sceneId:\n illumination.sceneId,\n illuminationProfileId:\n illumination.profileId,\n evidence: [\n ...(baseTemporal?.evidence ?? []),\n ...flash.evidence,\n ...sync.evidence\n ],\n waveforms: [\n ...(baseTemporal?.waveforms ?? []),\n {\n waveformId:\n flash.pulse.waveformId,\n kind:\n \"aperiodic-relative-multiplier\",\n timeUnit: \"s\",\n scientificStatus:\n \"approximation\",\n uncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Manual flash pulse timing/shape is an explicit approximation.\"\n },\n evidence:\n flash.pulse.evidence,\n interpolation:\n \"piecewise-linear\",\n samples:\n flash.pulse.samples,\n outsideSupportBehavior:\n \"zero\"\n }\n ],\n sourceBindings: [\n ...(baseTemporal?.sourceBindings ?? []),\n {\n bindingId:\n flash.profileId +\n \":sync\",\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n captureTimeReference:\n \"first-opening-boundary-phase\",\n waveformTimeZeroSecondsFromCaptureReference:\n sync\n .waveformTimeZeroSecondsFromCaptureReference,\n scientificStatus:\n \"approximation\",\n timingUncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Schema 0.1.0 uses ideal deterministic flash trigger registration within the declared exposure-window schedule.\"\n },\n evidence:\n sync.evidence\n }\n ],\n baseIlluminationProfileRemainsAuthoritative:\n true,\n sensorReadoutTimingUsedAsExposureTiming:\n false,\n automaticExposurePolicyIncluded:\n false\n });\n\n return {\n flashApplied: true,\n illuminationProfile:\n illumination,\n temporalProfile:\n temporal,\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n}\n\nexport interface ResolveHighSpeedFlashSyncInput {\n flashEnabled: boolean;\n /** Ordinary full-power pulse definition; its integral defines the full-power pulse energy. */\n flashProfile: ManualFlashProfile;\n /** Schema 0.2.0 profile with highSpeedSyncSupported true. */\n syncCapabilities: FlashSyncCapabilityProfile;\n timing: ResolvedCaptureModeTiming;\n /** Commanded output as a fraction of full power, (0, 1]. */\n powerFraction: number;\n releaseFrame?: ResolvedReleaseFrame;\n}\n\nexport interface ResolvedHighSpeedFlashSync extends FlashOverlaySyncRegistration {\n modelId: typeof HIGH_SPEED_SYNC_MODEL.id;\n modelVersion: typeof HIGH_SPEED_SYNC_MODEL.version;\n syncMode: \"high-speed-sync\";\n syncStatus: \"disabled\" | \"high-speed-sync-resolved\";\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId: string;\n timeReference: \"first-opening-boundary-phase\";\n powerFraction: number;\n /** η from the sync capability profile. */\n burstEnergyFractionOfFullPulse: number;\n /** ∫ pulse(t) dt of the declared ordinary pulse, whose relative peak is 1 (relative multiplier · s). */\n singlePulseIntegratedRelativeSeconds: number;\n /** D: burst support covering the first line opening to the last line closing. */\n burstStartSecondsFromCaptureReference: number;\n burstEndSecondsFromCaptureReference: number;\n burstDurationSeconds: number;\n /** Local (slit) exposure durations t_e over the active frame. */\n localExposureDurationRangeSeconds: { minimum: number; maximum: number };\n /** Flash energy each line receives relative to one ordinary pulse at the same power: η·t_e/D. */\n energyFractionOfSinglePulseRange: { minimum: number; maximum: number };\n /** Effective guide-number factor relative to the same-power ordinary pulse: √(η·t_e/D). */\n guideNumberFactorRange: { minimum: number; maximum: number };\n uniformAcrossActiveFrame: boolean;\n /** The rectangular high-speed-sync burst, written as a manual pulse profile for the illumination overlay. */\n burstFlashProfile: ManualFlashProfile | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtBurstStart: number;\n sceneTimeSecondsFromSequenceStartAtBurstEnd: number;\n }\n | null;\n hssModeled: true;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming: false;\n limitations: readonly string[];\n}\n\nfunction integratePulse(samples: readonly SceneIlluminationTemporalWaveformSample[]): number {\n let area = 0;\n for (let index = 1; index < samples.length; index += 1) {\n const a = samples[index - 1]!, b = samples[index]!;\n area += (b.timeSecondsFromWaveformReference - a.timeSecondsFromWaveformReference) *\n (a.relativeMagnitudeMultiplier + b.relativeMagnitudeMultiplier) / 2;\n }\n return area;\n}\n\n/**\n * Resolves high-speed (focal-plane) sync (HSS): a fast pulse train that acts as continuous light and\n * covers the whole travelling-slit exposure.\n *\n * At shutter speeds faster than the ordinary sync limit, the shutter's opening and closing edges\n * cross the frame as a slit, and the whole frame is never open at once. A single short pulse would\n * light only a band.\n *\n * HSS instead fires a rapid pulse train. It behaves like constant output P over the burst D, from\n * the first line opening to the last line closing. Each line collects P·t_e over its slit time t_e.\n * - The burst energy is E_burst = η·p·E_pulse. η comes from the sync profile, p is the power\n * fraction and E_pulse is the energy of an ordinary full-power pulse.\n * - So P = E_burst/D, and each line receives η·p·E_pulse·t_e/D.\n * - Exposure ∝ GN² (inverse-square law, GN = d·N). So, relative to an ordinary pulse at the same\n * power, the effective guide number is GN_HSS/GN = √(η·t_e/D).\n * Shortening t_e by one stop therefore costs half a stop of guide number.\n *\n * Approximations: the pulse train is treated as continuous (pulse period ≪ t_e). Recycle and thermal\n * limits are folded into η. Front/rear-curtain placement does not apply, because the burst covers\n * the whole exposure.\n * @see docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md#high-speed-sync\n */\nexport function resolveHighSpeedFlashSync(input: ResolveHighSpeedFlashSyncInput): ResolvedHighSpeedFlashSync {\n requireInputKeys(input, \"resolveHighSpeedFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"powerFraction\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveHighSpeedFlashSync timing\");\n const flash = parseManualFlashProfile(input.flashProfile);\n const capabilities = parseFlashSyncCapabilityProfile(input.syncCapabilities);\n if (capabilities.captureModeId !== input.timing.captureModeId || capabilities.timingProfileId !== input.timing.timingProfileId) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (!capabilities.highSpeedSyncSupported || capabilities.highSpeedSync === undefined) {\n throw new InvalidScientificInputError(\"The flash sync capability profile does not declare high-speed sync.\");\n }\n const power = input.powerFraction;\n if (typeof power !== \"number\" || !Number.isFinite(power) || power <= 0 || power > 1) {\n throw new InvalidScientificInputError(\"HSS powerFraction must lie in (0, 1].\");\n }\n if (input.releaseFrame !== undefined) validateReleaseBinding(input.releaseFrame, input.timing);\n\n const windows = input.timing.exposureWindows;\n const closing = windows.closing.schedule;\n const burstEnd = windows.nominalExposureDurationSeconds.value +\n (closing.kind === \"simultaneous\" ? 0 : closing.traversalDurationSeconds.value);\n const eta = capabilities.highSpeedSync.burstEnergyFractionOfFullPulse;\n const local = windows.localExposureDurationRangeSeconds;\n const fraction = { minimum: eta * local.minimum / burstEnd, maximum: eta * local.maximum / burstEnd };\n const pulseEnergy = integratePulse(flash.pulse.samples);\n const burstFlashProfile: ManualFlashProfile = {\n ...flash,\n pulse: {\n ...flash.pulse,\n waveformId: flash.pulse.waveformId + \"-hss-burst\",\n supportDurationSeconds: burstEnd,\n samples: [\n { timeSecondsFromWaveformReference: 0, relativeMagnitudeMultiplier: 1 },\n { timeSecondsFromWaveformReference: burstEnd, relativeMagnitudeMultiplier: 1 }\n ],\n limitations: [...flash.pulse.limitations,\n \"Quasi-continuous HSS burst: the pulse train is approximated by constant output over the burst support.\"]\n },\n outputControl: { ...flash.outputControl, scale: flash.outputControl.scale * power * eta * pulseEnergy / burstEnd }\n };\n const enabled = input.flashEnabled;\n return {\n modelId: HIGH_SPEED_SYNC_MODEL.id,\n modelVersion: HIGH_SPEED_SYNC_MODEL.version,\n flashEnabled: enabled,\n flashProfileId: flash.profileId,\n flashProfileVersion: flash.profileVersion,\n sourceId: flash.sourceTemplate.sourceId,\n syncMode: \"high-speed-sync\",\n syncStatus: enabled ? \"high-speed-sync-resolved\" : \"disabled\",\n captureModeId: input.timing.captureModeId,\n timingProfileId: input.timing.timingProfileId,\n syncCapabilityProfileId: capabilities.profileId,\n timeReference: \"first-opening-boundary-phase\",\n powerFraction: power,\n burstEnergyFractionOfFullPulse: eta,\n singlePulseIntegratedRelativeSeconds: pulseEnergy,\n burstStartSecondsFromCaptureReference: 0,\n burstEndSecondsFromCaptureReference: burstEnd,\n burstDurationSeconds: burstEnd,\n localExposureDurationRangeSeconds: { minimum: local.minimum, maximum: local.maximum },\n energyFractionOfSinglePulseRange: fraction,\n guideNumberFactorRange: { minimum: Math.sqrt(fraction.minimum), maximum: Math.sqrt(fraction.maximum) },\n uniformAcrossActiveFrame: local.minimum === local.maximum,\n burstFlashProfile: enabled ? burstFlashProfile : null,\n waveformTimeZeroSecondsFromCaptureReference: enabled ? 0 : null,\n releaseFrameBinding: !enabled || input.releaseFrame === undefined ? null : {\n sequenceId: input.releaseFrame.sequenceId,\n releaseFrameId: input.releaseFrame.releaseFrameId,\n frameIndex: input.releaseFrame.frameIndex,\n sceneTimeSecondsFromSequenceStartAtBurstStart: input.releaseFrame.sceneTimeSecondsFromSequenceStart,\n sceneTimeSecondsFromSequenceStartAtBurstEnd: input.releaseFrame.sceneTimeSecondsFromSequenceStart + burstEnd\n },\n hssModeled: true,\n ttlModeled: false,\n sensorReadoutTimingUsedAsExposureTiming: false,\n evidence: [...flash.evidence, ...capabilities.evidence, ...capabilities.highSpeedSync.evidence, ...input.timing.evidence],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"HSS burst is registered to exposure-boundary timing (first line opening to last line closing), never sensor data-readout timing.\",\n \"Pulse-train ripple, recycle/thermal limits beyond the declared burst energy fraction and branded flash protocols are not modeled.\"\n ]\n };\n}\n\n/**\n * Registers a resolved high-speed-sync burst as a temporal illumination overlay: a rectangular\n * waveform over [0, D]. Each line then collects the burst over its own local exposure window.\n */\nexport function createHighSpeedSyncIlluminationOverlay(\n input: Omit<CreateManualFlashIlluminationOverlayInput, \"resolvedSync\"> & { resolvedSync: ResolvedHighSpeedFlashSync }\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createHighSpeedSyncIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"illuminationProfileId\", \"temporalProfileId\", \"resolvedSync\"]);\n requireInputObject(input.resolvedSync, \"createHighSpeedSyncIlluminationOverlay resolvedSync\");\n return createManualFlashIlluminationOverlay({ ...input,\n flashProfile: input.resolvedSync.burstFlashProfile ?? input.flashProfile });\n}\n"]}
1
+ {"version":3,"file":"flash.js","sourceRoot":"","sources":["../../src/exposure/flash.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Manual flash and flash sync.\n *\n * The parsers validate untrusted input and return the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock.\n * - Ordinary front- or rear-curtain sync needs a real interval when the whole frame is open at once.\n * - High-speed sync (HSS; schema 0.2.0 sync profiles) is separate: a near-continuous burst that\n * covers the travelling shutter slit (resolveHighSpeedFlashSync).\n * - TTL pre-flash power and guide-number relations are in flash-ttl.ts.\n * Source brightness, optical transport and sensor integration have their own contracts.\n * @see docs/USAGE.md for the equations, units, coordinate conventions, known blockers and support\n * limits.\n */\n\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 ResolvedReleaseFrame\n} from \"../capture/release-sequence.js\";\nimport {\n parseSceneIlluminationProfile,\n type SceneIlluminationProfile,\n type SceneIlluminationSource\n} from \"../schema/illumination.js\";\nimport {\n parseSceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalWaveformSample\n} from \"../schema/illumination-temporal.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputObject, requireInputKeys, rejectUnknownFields } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const MANUAL_FLASH_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const FLASH_SYNC_CAPABILITY_SCHEMA_VERSION =\n \"0.1.0\" as const;\n/** Sync-capability schema that may declare high-speed sync (a fast pulse train that acts as continuous light). */\nexport const FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION =\n \"0.2.0\" as const;\n/** Model identity of the pulsed quasi-continuous high-speed-sync burst. */\nexport const HIGH_SPEED_SYNC_MODEL = /* @__PURE__ */ Object.freeze({\n id: \"flash-hss-quasi-continuous-burst\",\n version: \"1.0.0\"\n} as const);\n\nexport type ManualFlashSyncMode =\n | \"front-curtain\"\n | \"rear-curtain\";\n\nexport type RequestedFlashSyncMode =\n | ManualFlashSyncMode\n | \"high-speed-sync\";\n\nexport interface ManualFlashPulseProfile {\n waveformId: string;\n scientificStatus: \"approximation\";\n supportDurationSeconds: number;\n interpolation: \"piecewise-linear\";\n samples:\n readonly SceneIlluminationTemporalWaveformSample[];\n normalization:\n \"relative-peak-one\";\n evidence:\n readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ManualFlashProfile {\n schemaVersion:\n typeof MANUAL_FLASH_PROFILE_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n sourceTemplate:\n Omit<\n SceneIlluminationSource,\n \"enabled\" |\n \"temporalBehavior\"\n >;\n pulse:\n ManualFlashPulseProfile;\n outputControl: {\n kind:\n \"relative-linear-source-scale\";\n scale: number;\n flashExposureCompensationStops:\n 0;\n };\n ttlModeled: false;\n highSpeedSyncModeled: false;\n recycleBehaviorModeled: false;\n redEyePreflashModeled: false;\n modelingLightModeled: false;\n afAssistModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface FlashSyncCapabilityProfile {\n schemaVersion:\n | typeof FLASH_SYNC_CAPABILITY_SCHEMA_VERSION\n | typeof FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n captureModeId: string;\n timingProfileId: string;\n supportedOrdinarySyncModes:\n readonly ManualFlashSyncMode[];\n /** Schema 0.1.0 is always false; schema 0.2.0 may declare HSS with {@link highSpeedSync}. */\n highSpeedSyncSupported: boolean;\n /** Present exactly when highSpeedSyncSupported is true (schema 0.2.0). */\n highSpeedSync?: {\n /**\n * η: energy of one full-power high-speed-sync burst, as a fraction of one full-power ordinary\n * pulse, in (0, 1]. The caller declares it from evidence (capacitor and thermal limits). It is\n * never inferred.\n */\n burstEnergyFractionOfFullPulse: number;\n evidence: readonly EvidenceProvenance[];\n };\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ResolveManualFlashSyncInput {\n flashEnabled: boolean;\n flashProfile:\n ManualFlashProfile;\n syncCapabilities:\n FlashSyncCapabilityProfile;\n timing:\n ResolvedCaptureModeTiming;\n syncMode:\n RequestedFlashSyncMode;\n releaseFrame?:\n ResolvedReleaseFrame;\n}\n\nexport interface ResolvedManualFlashSync {\n flashEnabled: boolean;\n flashProfileId: string;\n flashProfileVersion: string;\n sourceId: string;\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId:\n string;\n syncMode:\n RequestedFlashSyncMode;\n syncStatus:\n | \"disabled\"\n | \"ordinary-sync-resolved\";\n timeReference:\n \"first-opening-boundary-phase\";\n wholeActiveFrameOpenInterval:\n {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n pulseSupportDurationSeconds:\n number;\n pulseStartSecondsFromCaptureReference:\n number | null;\n pulseEndSecondsFromCaptureReference:\n number | null;\n waveformTimeZeroSecondsFromCaptureReference:\n number | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n number;\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n number;\n }\n | null;\n hssModeled: false;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n whiteBalanceModified: false;\n focusModified: false;\n exposureSettingsModified: false;\n driveModeModified: false;\n supportStateModified: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\n/** Fields of a resolved sync (ordinary or HSS) needed to register a flash overlay. */\nexport type FlashOverlaySyncRegistration = Pick<\n ResolvedManualFlashSync,\n | \"flashEnabled\"\n | \"flashProfileId\"\n | \"flashProfileVersion\"\n | \"sourceId\"\n | \"waveformTimeZeroSecondsFromCaptureReference\"\n | \"evidence\"\n>;\n\nexport interface CreateManualFlashIlluminationOverlayInput {\n baseIlluminationProfile:\n SceneIlluminationProfile;\n baseTemporalProfile?:\n SceneIlluminationTemporalProfile;\n flashProfile:\n ManualFlashProfile;\n resolvedSync:\n FlashOverlaySyncRegistration;\n illuminationProfileId: string;\n temporalProfileId: string;\n}\n\nexport interface ManualFlashIlluminationOverlay {\n flashApplied: boolean;\n illuminationProfile:\n SceneIlluminationProfile;\n temporalProfile:\n SceneIlluminationTemporalProfile | null;\n sourceId: string;\n waveformId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n sourceMagnitudeAppliedBySceneTransport:\n true;\n materialTransportOwnedBySceneRadiance:\n true;\n visibilityOwnedBySceneRadiance:\n true;\n indirectTransportOwnedBySceneRadiance:\n true;\n postRenderBrightnessMultiplierUsed:\n false;\n whiteBalanceModified: false;\n ambientMeteringModified: false;\n ttlMeteringIncluded: false;\n ambientTemporalBehaviorPreserved:\n true;\n}\n\nconst ORDINARY_SYNC_MODES =\n new Set<ManualFlashSyncMode>([\n \"front-curtain\",\n \"rear-curtain\"\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 +\n \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be finite.\"\n );\n }\n return value;\n}\n\nfunction requirePositiveFinite(\n value: unknown,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (parsed <= 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than zero.\"\n );\n }\n return parsed;\n}\n\nfunction parseLimitations(\n value: unknown,\n path: string\n): readonly string[] {\n if (!Array.isArray(value)) {\n throw new InvalidConfigurationError(\n path + \" must be an array.\"\n );\n }\n const parsed =\n value.map((entry, index) =>\n requireNonEmptyString(\n entry,\n path +\n \"[\" +\n index +\n \"]\"\n )\n );\n if (\n new Set(parsed).size !==\n parsed.length\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must not contain duplicates.\"\n );\n }\n return parsed;\n}\n\nfunction parsePulseSamples(\n value: unknown,\n supportDurationSeconds:\n number,\n path: string\n): readonly SceneIlluminationTemporalWaveformSample[] {\n if (\n !Array.isArray(value) ||\n value.length < 2\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must contain at least two waveform samples.\"\n );\n }\n const samples =\n value.map((entry, index) => {\n const samplePath =\n path +\n \"[\" +\n index +\n \"]\";\n const record =\n requireRecord(\n entry,\n samplePath, [\"timeSecondsFromWaveformReference\", \"relativeMagnitudeMultiplier\"]\n );\n const time =\n requireFinite(\n record\n .timeSecondsFromWaveformReference,\n samplePath +\n \".timeSecondsFromWaveformReference\"\n );\n const magnitude =\n requireFinite(\n record\n .relativeMagnitudeMultiplier,\n samplePath +\n \".relativeMagnitudeMultiplier\"\n );\n if (\n time < 0 ||\n time >\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n samplePath +\n \".timeSecondsFromWaveformReference must lie within the declared pulse support.\"\n );\n }\n if (magnitude < 0) {\n throw new InvalidConfigurationError(\n samplePath +\n \".relativeMagnitudeMultiplier must be nonnegative.\"\n );\n }\n return {\n timeSecondsFromWaveformReference:\n time,\n relativeMagnitudeMultiplier:\n magnitude\n };\n });\n\n for (\n let index = 1;\n index < samples.length;\n index += 1\n ) {\n if (\n !(\n samples[index]!\n .timeSecondsFromWaveformReference >\n samples[index - 1]!\n .timeSecondsFromWaveformReference\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \" times must be strictly increasing.\"\n );\n }\n }\n if (\n samples[0]!\n .timeSecondsFromWaveformReference !==\n 0 ||\n samples[\n samples.length - 1\n ]!\n .timeSecondsFromWaveformReference !==\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must start at waveform time 0 and end exactly at supportDurationSeconds.\"\n );\n }\n const peak =\n Math.max(\n ...samples.map(\n (sample) =>\n sample\n .relativeMagnitudeMultiplier\n )\n );\n if (\n Math.abs(peak - 1) >\n 1e-12\n ) {\n throw new InvalidConfigurationError(\n path +\n \" peak relative magnitude must equal one for relative-peak-one normalization.\"\n );\n }\n\n return samples;\n}\n\nfunction validateSourceTemplate(\n sourceTemplate:\n ManualFlashProfile[\"sourceTemplate\"]\n): ManualFlashProfile[\"sourceTemplate\"] {\n requireInputObject(sourceTemplate, \"manualFlashProfile.sourceTemplate\");\n const probe =\n parseSceneIlluminationProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n \"manual-flash-source-validation\",\n sceneId:\n \"manual-flash-source-validation\",\n evidence:\n sourceTemplate.evidence,\n sources: [{\n ...sourceTemplate,\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n }],\n sceneRadianceCalculated:\n false,\n materialResponseApplied:\n false,\n visibilityEvaluated:\n false,\n indirectTransportEvaluated:\n false,\n fluorescenceModeled:\n false,\n volumetricTransportModeled:\n false,\n polarizationModeled:\n false\n });\n const source =\n probe.sources[0];\n if (source === undefined) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.sourceTemplate must produce one valid illumination source.\"\n );\n }\n return {\n sourceId:\n source.sourceId,\n family:\n source.family,\n geometry:\n source.geometry,\n magnitude:\n source.magnitude,\n spectrum:\n source.spectrum,\n evidence:\n source.evidence,\n ...(source.limitations ===\n undefined\n ? {}\n : {\n limitations:\n source.limitations\n })\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns ManualFlashProfile. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseManualFlashProfile(\n value: unknown\n): ManualFlashProfile {\n const record =\n requireRecord(\n value,\n \"manualFlashProfile\", [\"schemaVersion\", \"pulse\", \"outputControl\", \"profileId\", \"profileVersion\", \"sourceTemplate\", \"evidence\", \"limitations\", \"ttlModeled\", \"highSpeedSyncModeled\", \"recycleBehaviorModeled\", \"redEyePreflashModeled\", \"modelingLightModeled\", \"afAssistModeled\"]\n );\n if (\n record.schemaVersion !==\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'manualFlashProfile.schemaVersion must be \"' +\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n for (\n const [key, expected] of [\n [\"ttlModeled\", false],\n [\"highSpeedSyncModeled\", false],\n [\"recycleBehaviorModeled\", false],\n [\"redEyePreflashModeled\", false],\n [\"modelingLightModeled\", false],\n [\"afAssistModeled\", false]\n ] as const\n ) {\n if (record[key] !== expected) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.\" +\n key +\n \" must be false in schema 0.1.0.\"\n );\n }\n }\n\n const pulse =\n requireRecord(\n record.pulse,\n \"manualFlashProfile.pulse\", [\"supportDurationSeconds\", \"scientificStatus\", \"interpolation\", \"normalization\", \"waveformId\", \"samples\", \"evidence\", \"limitations\"]\n );\n const supportDurationSeconds =\n requirePositiveFinite(\n pulse.supportDurationSeconds,\n \"manualFlashProfile.pulse.supportDurationSeconds\"\n );\n if (\n pulse.scientificStatus !==\n \"approximation\" ||\n pulse.interpolation !==\n \"piecewise-linear\" ||\n pulse.normalization !==\n \"relative-peak-one\"\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.pulse scientificStatus/interpolation/normalization is invalid.\"\n );\n }\n\n const output =\n requireRecord(\n record.outputControl,\n \"manualFlashProfile.outputControl\", [\"kind\", \"flashExposureCompensationStops\", \"scale\"]\n );\n if (\n output.kind !==\n \"relative-linear-source-scale\" ||\n output\n .flashExposureCompensationStops !==\n 0\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.outputControl must use relative-linear-source-scale with zero flash exposure compensation in the manual-only schema.\"\n );\n }\n\n return {\n schemaVersion:\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"manualFlashProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"manualFlashProfile.profileVersion\"\n ),\n sourceTemplate:\n validateSourceTemplate(\n record.sourceTemplate as\n ManualFlashProfile[\"sourceTemplate\"]\n ),\n pulse: {\n waveformId:\n requireNonEmptyString(\n pulse.waveformId,\n \"manualFlashProfile.pulse.waveformId\"\n ),\n scientificStatus:\n \"approximation\",\n supportDurationSeconds,\n interpolation:\n \"piecewise-linear\",\n samples:\n parsePulseSamples(\n pulse.samples,\n supportDurationSeconds,\n \"manualFlashProfile.pulse.samples\"\n ),\n normalization:\n \"relative-peak-one\",\n evidence:\n parseEvidenceList(\n pulse.evidence,\n \"manualFlashProfile.pulse.evidence\"\n ),\n limitations:\n parseLimitations(\n pulse.limitations,\n \"manualFlashProfile.pulse.limitations\"\n )\n },\n outputControl: {\n kind:\n \"relative-linear-source-scale\",\n scale:\n requirePositiveFinite(\n output.scale,\n \"manualFlashProfile.outputControl.scale\"\n ),\n flashExposureCompensationStops:\n 0\n },\n ttlModeled: false,\n highSpeedSyncModeled: false,\n recycleBehaviorModeled:\n false,\n redEyePreflashModeled:\n false,\n modelingLightModeled:\n false,\n afAssistModeled: false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"manualFlashProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"manualFlashProfile.limitations\"\n )\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns FlashSyncCapabilityProfile. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseFlashSyncCapabilityProfile(\n value: unknown\n): FlashSyncCapabilityProfile {\n const record =\n requireRecord(\n value,\n \"flashSyncCapabilityProfile\", [\"schemaVersion\", \"highSpeedSyncSupported\", \"ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed\", \"highSpeedSync\", \"supportedOrdinarySyncModes\", \"profileId\", \"profileVersion\", \"captureModeId\", \"timingProfileId\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION &&\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'flashSyncCapabilityProfile.schemaVersion must be \"' +\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION +\n '\" or \"' +\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION +\n '\".'\n );\n }\n const hssSchema =\n record.schemaVersion ===\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n if (\n (hssSchema\n ? typeof record.highSpeedSyncSupported !==\n \"boolean\"\n : record.highSpeedSyncSupported !==\n false) ||\n record\n .ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed !==\n true\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile schema 0.1.0 supports ordinary whole-frame sync only and must not claim HSS.\"\n );\n }\n let highSpeedSync:\n FlashSyncCapabilityProfile[\"highSpeedSync\"];\n if (record.highSpeedSyncSupported === true) {\n const hss = requireRecord(\n record.highSpeedSync,\n \"flashSyncCapabilityProfile.highSpeedSync\", [\"burstEnergyFractionOfFullPulse\", \"evidence\"]\n );\n const fraction = requirePositiveFinite(\n hss.burstEnergyFractionOfFullPulse,\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse\"\n );\n if (fraction > 1) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse must be at most 1.\"\n );\n }\n highSpeedSync = {\n burstEnergyFractionOfFullPulse:\n fraction,\n evidence: parseEvidenceList(\n hss.evidence,\n \"flashSyncCapabilityProfile.highSpeedSync.evidence\"\n )\n };\n } else if (\n record.highSpeedSync !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync must be omitted when HSS is unsupported.\"\n );\n }\n if (\n !Array.isArray(\n record.supportedOrdinarySyncModes\n ) ||\n record\n .supportedOrdinarySyncModes\n .length === 0\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must be a non-empty array.\"\n );\n }\n const modes =\n record\n .supportedOrdinarySyncModes\n .map((entry, index) => {\n if (\n typeof entry !==\n \"string\" ||\n !ORDINARY_SYNC_MODES.has(\n entry as ManualFlashSyncMode\n )\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes[\" +\n index +\n \"] is invalid.\"\n );\n }\n return entry as\n ManualFlashSyncMode;\n });\n if (\n new Set(modes).size !==\n modes.length\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must not contain duplicates.\"\n );\n }\n\n return {\n schemaVersion: hssSchema\n ? FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n : FLASH_SYNC_CAPABILITY_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"flashSyncCapabilityProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"flashSyncCapabilityProfile.profileVersion\"\n ),\n captureModeId:\n requireNonEmptyString(\n record.captureModeId,\n \"flashSyncCapabilityProfile.captureModeId\"\n ),\n timingProfileId:\n requireNonEmptyString(\n record.timingProfileId,\n \"flashSyncCapabilityProfile.timingProfileId\"\n ),\n supportedOrdinarySyncModes:\n modes,\n highSpeedSyncSupported:\n highSpeedSync !== undefined,\n ...(highSpeedSync === undefined\n ? {}\n : { highSpeedSync }),\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"flashSyncCapabilityProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"flashSyncCapabilityProfile.limitations\"\n )\n };\n}\n\n/**\n * Shape guard for the resolved capture-mode timing record read by the flash sync functions: every\n * nested object read below must be an object, so a malformed record fails with\n * InvalidConfigurationError instead of a raw TypeError. Values are checked where they are used.\n */\nfunction requireTimingRecordShape(timing: unknown, path: string): void {\n requireInputObject(timing, path);\n const record = timing as Record<string, unknown>;\n if (!Array.isArray(record.evidence)) throw new InvalidConfigurationError(path + \".evidence must be an array.\");\n requireInputObject(record.exposureWindows, path + \".exposureWindows\");\n const windows = record.exposureWindows as Record<string, unknown>;\n requireInputObject(windows.nominalExposureDurationSeconds, path + \".exposureWindows.nominalExposureDurationSeconds\");\n requireInputObject(windows.localExposureDurationRangeSeconds, path + \".exposureWindows.localExposureDurationRangeSeconds\");\n for (const boundary of [\"opening\", \"closing\"] as const) {\n requireInputObject(windows[boundary], path + \".exposureWindows.\" + boundary);\n const schedule = (windows[boundary] as Record<string, unknown>).schedule;\n requireInputObject(schedule, path + \".exposureWindows.\" + boundary + \".schedule\");\n if ((schedule as Record<string, unknown>).kind !== \"simultaneous\") {\n requireInputObject((schedule as Record<string, unknown>).traversalDurationSeconds, path + \".exposureWindows.\" + boundary + \".schedule.traversalDurationSeconds\");\n }\n }\n}\n\nfunction wholeFrameOpenInterval(\n timing:\n ResolvedCaptureModeTiming\n): {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n} {\n const opening =\n timing.exposureWindows.opening\n .schedule;\n const latestOpening =\n opening.kind ===\n \"simultaneous\"\n ? 0\n : opening\n .traversalDurationSeconds\n .value;\n const earliestClosing =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const duration =\n earliestClosing -\n latestOpening;\n return {\n startSecondsFromCaptureReference:\n latestOpening,\n endSecondsFromCaptureReference:\n earliestClosing,\n durationSeconds:\n Math.max(0, duration)\n };\n}\n\nfunction validateReleaseBinding(\n release:\n ResolvedReleaseFrame,\n timing:\n ResolvedCaptureModeTiming\n): void {\n requireInputObject(release, \"releaseFrame\");\n requireInputObject(release.exposure, \"releaseFrame.exposure\");\n const nominal =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const scale =\n Math.max(\n 1,\n Math.abs(nominal),\n Math.abs(\n release.exposure\n .shutterSeconds\n )\n );\n if (\n Math.abs(\n release.exposure\n .shutterSeconds -\n nominal\n ) >\n Number.EPSILON *\n 16 *\n scale\n ) {\n throw new InvalidScientificInputError(\n \"releaseFrame shutter duration must match the exposure duration of the capture-mode exposure-window timing.\"\n );\n }\n}\n\n/**\n * Places a declared ordinary flash pulse inside the actual interval when the whole frame is open, for\n * front- or rear-curtain sync. Otherwise returns a structured incompatibility.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - ResolveManualFlashSyncInput. See that type for coordinates, units and profile binding.\n * @returns ResolvedManualFlashSync. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function resolveManualFlashSync(\n input:\n ResolveManualFlashSyncInput\n): ResolvedManualFlashSync {\n requireInputKeys(input, \"resolveManualFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"syncMode\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveManualFlashSync timing\");\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const capabilities =\n parseFlashSyncCapabilityProfile(\n input.syncCapabilities\n );\n\n if (\n capabilities.captureModeId !==\n input.timing.captureModeId ||\n capabilities.timingProfileId !==\n input.timing.timingProfileId\n ) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (\n input.releaseFrame !==\n undefined\n ) {\n validateReleaseBinding(\n input.releaseFrame,\n input.timing\n );\n }\n\n const openInterval =\n wholeFrameOpenInterval(\n input.timing\n );\n const base = {\n flashProfileId:\n flash.profileId,\n flashProfileVersion:\n flash.profileVersion,\n sourceId:\n flash.sourceTemplate.sourceId,\n captureModeId:\n input.timing.captureModeId,\n timingProfileId:\n input.timing.timingProfileId,\n syncCapabilityProfileId:\n capabilities.profileId,\n syncMode:\n input.syncMode,\n timeReference:\n \"first-opening-boundary-phase\" as const,\n wholeActiveFrameOpenInterval:\n openInterval,\n pulseSupportDurationSeconds:\n flash.pulse\n .supportDurationSeconds,\n hssModeled: false as const,\n ttlModeled: false as const,\n sensorReadoutTimingUsedAsExposureTiming:\n false as const,\n whiteBalanceModified:\n false as const,\n focusModified: false as const,\n exposureSettingsModified:\n false as const,\n driveModeModified:\n false as const,\n supportStateModified:\n false as const,\n evidence: [\n ...flash.evidence,\n ...capabilities.evidence,\n ...input.timing.evidence\n ],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"Ordinary flash synchronization is registered to exposure-boundary timing, never sensor data-readout timing.\",\n \"Schema 0.1.0 does not model HSS, TTL/preflash metering, recycle/thermal limits, red-eye preflash, modeling lights, AF-assist or branded flash protocols.\"\n ]\n };\n\n if (!input.flashEnabled) {\n return {\n flashEnabled: false,\n ...base,\n syncStatus:\n \"disabled\",\n pulseStartSecondsFromCaptureReference:\n null,\n pulseEndSecondsFromCaptureReference:\n null,\n waveformTimeZeroSecondsFromCaptureReference:\n null,\n releaseFrameBinding:\n null\n };\n }\n\n if (\n input.syncMode ===\n \"high-speed-sync\"\n ) {\n throw new InvalidScientificInputError(\n \"High-speed sync is not an ordinary sync mode; ordinary single-pulse flash cannot be used as an HSS substitute. Use resolveHighSpeedFlashSync with an HSS-capable sync profile.\"\n );\n }\n if (\n !capabilities\n .supportedOrdinarySyncModes\n .includes(\n input.syncMode\n )\n ) {\n throw new InvalidScientificInputError(\n \"Requested ordinary flash sync mode is not supported by the capability profile.\"\n );\n }\n if (\n openInterval.durationSeconds <=\n 0\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary one-pulse flash cannot uniformly expose the active frame because the exposure-window timing has no whole-frame-open interval.\"\n );\n }\n if (\n flash.pulse\n .supportDurationSeconds >\n openInterval.durationSeconds\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary flash pulse support does not fit inside the whole-active-frame-open interval.\"\n );\n }\n\n const pulseStart =\n input.syncMode ===\n \"front-curtain\"\n ? openInterval\n .startSecondsFromCaptureReference\n : openInterval\n .endSecondsFromCaptureReference -\n flash.pulse\n .supportDurationSeconds;\n const pulseEnd =\n pulseStart +\n flash.pulse\n .supportDurationSeconds;\n\n const releaseBinding =\n input.releaseFrame ===\n undefined\n ? null\n : {\n sequenceId:\n input.releaseFrame\n .sequenceId,\n releaseFrameId:\n input.releaseFrame\n .releaseFrameId,\n frameIndex:\n input.releaseFrame\n .frameIndex,\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseStart,\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseEnd\n };\n\n return {\n flashEnabled: true,\n ...base,\n syncStatus:\n \"ordinary-sync-resolved\",\n pulseStartSecondsFromCaptureReference:\n pulseStart,\n pulseEndSecondsFromCaptureReference:\n pulseEnd,\n waveformTimeZeroSecondsFromCaptureReference:\n pulseStart,\n releaseFrameBinding:\n releaseBinding\n };\n}\n\nfunction scaledFlashSource(\n flash:\n ManualFlashProfile\n): SceneIlluminationSource {\n const template =\n flash.sourceTemplate;\n const magnitude =\n template.magnitude;\n if (\n magnitude.kind !==\n \"relative-linear-scale\"\n ) {\n throw new InvalidScientificInputError(\n \"Manual flash schema 0.1.0 relative output control requires a relative-linear-scale illumination source magnitude; calibrated physical flash energy belongs to a later profile.\"\n );\n }\n\n return {\n ...template,\n magnitude: {\n ...magnitude,\n scale:\n magnitude.scale *\n flash.outputControl.scale\n },\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n };\n}\n\n/**\n * Builds a temporal illumination overlay from the resolved manual pulse. The identity of the base\n * ambient light source is kept.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - CreateManualFlashIlluminationOverlayInput. See that type for coordinates, units and profile binding.\n * @returns ManualFlashIlluminationOverlay. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function createManualFlashIlluminationOverlay(\n input:\n CreateManualFlashIlluminationOverlayInput\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createManualFlashIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"resolvedSync\", \"illuminationProfileId\", \"temporalProfileId\"]);\n const base =\n parseSceneIlluminationProfile(\n input\n .baseIlluminationProfile\n );\n const baseTemporal =\n input.baseTemporalProfile ===\n undefined\n ? null\n : parseSceneIlluminationTemporalProfile(\n input.baseTemporalProfile\n );\n if (\n baseTemporal !== null &&\n (\n baseTemporal.sceneId !==\n base.sceneId ||\n baseTemporal\n .illuminationProfileId !==\n base.profileId\n )\n ) {\n throw new InvalidScientificInputError(\n \"baseTemporalProfile must exactly match the base illumination profile scene/profile identities.\"\n );\n }\n\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const sync =\n input.resolvedSync;\n requireInputObject(sync, \"createManualFlashIlluminationOverlay resolvedSync\");\n if (!Array.isArray(sync.evidence)) throw new InvalidConfigurationError(\"createManualFlashIlluminationOverlay resolvedSync.evidence must be an array.\");\n\n if (\n sync.flashProfileId !==\n flash.profileId ||\n sync.flashProfileVersion !==\n flash.profileVersion ||\n sync.sourceId !==\n flash.sourceTemplate.sourceId\n ) {\n throw new InvalidScientificInputError(\n \"Resolved flash sync identity must match the manual flash profile.\"\n );\n }\n if (\n base.sources.some(\n (source) =>\n source.sourceId ===\n flash.sourceTemplate\n .sourceId\n )\n ) {\n throw new InvalidScientificInputError(\n \"Flash sourceId must be unique within the base illumination profile.\"\n );\n }\n\n if (!sync.flashEnabled) {\n return {\n flashApplied: false,\n illuminationProfile:\n base,\n temporalProfile:\n baseTemporal,\n sourceId:\n flash.sourceTemplate\n .sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n }\n if (\n sync\n .waveformTimeZeroSecondsFromCaptureReference ===\n null\n ) {\n throw new InvalidScientificInputError(\n \"Enabled flash sync must provide an authoritative waveform time-zero registration.\"\n );\n }\n\n const flashSource =\n scaledFlashSource(\n flash\n );\n const illumination =\n parseSceneIlluminationProfile({\n ...base,\n profileId:\n requireNonEmptyString(\n input.illuminationProfileId,\n \"illuminationProfileId\"\n ),\n sources: [\n ...base.sources,\n flashSource\n ]\n });\n\n const temporal =\n parseSceneIlluminationTemporalProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n requireNonEmptyString(\n input.temporalProfileId,\n \"temporalProfileId\"\n ),\n sceneId:\n illumination.sceneId,\n illuminationProfileId:\n illumination.profileId,\n evidence: [\n ...(baseTemporal?.evidence ?? []),\n ...flash.evidence,\n ...sync.evidence\n ],\n waveforms: [\n ...(baseTemporal?.waveforms ?? []),\n {\n waveformId:\n flash.pulse.waveformId,\n kind:\n \"aperiodic-relative-multiplier\",\n timeUnit: \"s\",\n scientificStatus:\n \"approximation\",\n uncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Manual flash pulse timing/shape is an explicit approximation.\"\n },\n evidence:\n flash.pulse.evidence,\n interpolation:\n \"piecewise-linear\",\n samples:\n flash.pulse.samples,\n outsideSupportBehavior:\n \"zero\"\n }\n ],\n sourceBindings: [\n ...(baseTemporal?.sourceBindings ?? []),\n {\n bindingId:\n flash.profileId +\n \":sync\",\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n captureTimeReference:\n \"first-opening-boundary-phase\",\n waveformTimeZeroSecondsFromCaptureReference:\n sync\n .waveformTimeZeroSecondsFromCaptureReference,\n scientificStatus:\n \"approximation\",\n timingUncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Schema 0.1.0 uses ideal deterministic flash trigger registration within the declared exposure-window schedule.\"\n },\n evidence:\n sync.evidence\n }\n ],\n baseIlluminationProfileRemainsAuthoritative:\n true,\n sensorReadoutTimingUsedAsExposureTiming:\n false,\n automaticExposurePolicyIncluded:\n false\n });\n\n return {\n flashApplied: true,\n illuminationProfile:\n illumination,\n temporalProfile:\n temporal,\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n}\n\nexport interface ResolveHighSpeedFlashSyncInput {\n flashEnabled: boolean;\n /** Ordinary full-power pulse definition; its integral defines the full-power pulse energy. */\n flashProfile: ManualFlashProfile;\n /** Schema 0.2.0 profile with highSpeedSyncSupported true. */\n syncCapabilities: FlashSyncCapabilityProfile;\n timing: ResolvedCaptureModeTiming;\n /** Commanded output as a fraction of full power, (0, 1]. */\n powerFraction: number;\n releaseFrame?: ResolvedReleaseFrame;\n}\n\nexport interface ResolvedHighSpeedFlashSync extends FlashOverlaySyncRegistration {\n modelId: typeof HIGH_SPEED_SYNC_MODEL.id;\n modelVersion: typeof HIGH_SPEED_SYNC_MODEL.version;\n syncMode: \"high-speed-sync\";\n syncStatus: \"disabled\" | \"high-speed-sync-resolved\";\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId: string;\n timeReference: \"first-opening-boundary-phase\";\n powerFraction: number;\n /** η from the sync capability profile. */\n burstEnergyFractionOfFullPulse: number;\n /** ∫ pulse(t) dt of the declared ordinary pulse, whose relative peak is 1 (relative multiplier · s). */\n singlePulseIntegratedRelativeSeconds: number;\n /** D: burst support covering the first line opening to the last line closing. */\n burstStartSecondsFromCaptureReference: number;\n burstEndSecondsFromCaptureReference: number;\n burstDurationSeconds: number;\n /** Local (slit) exposure durations t_e over the active frame. */\n localExposureDurationRangeSeconds: { minimum: number; maximum: number };\n /** Flash energy each line receives relative to one ordinary pulse at the same power: η·t_e/D. */\n energyFractionOfSinglePulseRange: { minimum: number; maximum: number };\n /** Effective guide-number factor relative to the same-power ordinary pulse: √(η·t_e/D). */\n guideNumberFactorRange: { minimum: number; maximum: number };\n uniformAcrossActiveFrame: boolean;\n /** The rectangular high-speed-sync burst, written as a manual pulse profile for the illumination overlay. */\n burstFlashProfile: ManualFlashProfile | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtBurstStart: number;\n sceneTimeSecondsFromSequenceStartAtBurstEnd: number;\n }\n | null;\n hssModeled: true;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming: false;\n limitations: readonly string[];\n}\n\nfunction integratePulse(samples: readonly SceneIlluminationTemporalWaveformSample[]): number {\n let area = 0;\n for (let index = 1; index < samples.length; index += 1) {\n const a = samples[index - 1]!, b = samples[index]!;\n area += (b.timeSecondsFromWaveformReference - a.timeSecondsFromWaveformReference) *\n (a.relativeMagnitudeMultiplier + b.relativeMagnitudeMultiplier) / 2;\n }\n return area;\n}\n\n/**\n * Resolves high-speed (focal-plane) sync (HSS): a fast pulse train that acts as continuous light and\n * covers the whole travelling-slit exposure.\n *\n * At shutter speeds faster than the ordinary sync limit, the shutter's opening and closing edges\n * cross the frame as a slit, and the whole frame is never open at once. A single short pulse would\n * light only a band.\n *\n * HSS instead fires a rapid pulse train. It behaves like constant output P over the burst D, from\n * the first line opening to the last line closing. Each line collects P·t_e over its slit time t_e.\n * - The burst energy is E_burst = η·p·E_pulse. η comes from the sync profile, p is the power\n * fraction and E_pulse is the energy of an ordinary full-power pulse.\n * - So P = E_burst/D, and each line receives η·p·E_pulse·t_e/D.\n * - Exposure ∝ GN² (inverse-square law, GN = d·N). So, relative to an ordinary pulse at the same\n * power, the effective guide number is GN_HSS/GN = √(η·t_e/D).\n * Shortening t_e by one stop therefore costs half a stop of guide number.\n *\n * Approximations: the pulse train is treated as continuous (pulse period ≪ t_e). Recycle and thermal\n * limits are folded into η. Front/rear-curtain placement does not apply, because the burst covers\n * the whole exposure.\n * @see docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md#high-speed-sync\n */\nexport function resolveHighSpeedFlashSync(input: ResolveHighSpeedFlashSyncInput): ResolvedHighSpeedFlashSync {\n requireInputKeys(input, \"resolveHighSpeedFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"powerFraction\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveHighSpeedFlashSync timing\");\n const flash = parseManualFlashProfile(input.flashProfile);\n const capabilities = parseFlashSyncCapabilityProfile(input.syncCapabilities);\n if (capabilities.captureModeId !== input.timing.captureModeId || capabilities.timingProfileId !== input.timing.timingProfileId) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (!capabilities.highSpeedSyncSupported || capabilities.highSpeedSync === undefined) {\n throw new InvalidScientificInputError(\"The flash sync capability profile does not declare high-speed sync.\");\n }\n const power = input.powerFraction;\n if (typeof power !== \"number\" || !Number.isFinite(power) || power <= 0 || power > 1) {\n throw new InvalidScientificInputError(\"HSS powerFraction must lie in (0, 1].\");\n }\n if (input.releaseFrame !== undefined) validateReleaseBinding(input.releaseFrame, input.timing);\n\n const windows = input.timing.exposureWindows;\n const closing = windows.closing.schedule;\n const burstEnd = windows.nominalExposureDurationSeconds.value +\n (closing.kind === \"simultaneous\" ? 0 : closing.traversalDurationSeconds.value);\n const eta = capabilities.highSpeedSync.burstEnergyFractionOfFullPulse;\n const local = windows.localExposureDurationRangeSeconds;\n const fraction = { minimum: eta * local.minimum / burstEnd, maximum: eta * local.maximum / burstEnd };\n const pulseEnergy = integratePulse(flash.pulse.samples);\n const burstFlashProfile: ManualFlashProfile = {\n ...flash,\n pulse: {\n ...flash.pulse,\n waveformId: flash.pulse.waveformId + \"-hss-burst\",\n supportDurationSeconds: burstEnd,\n samples: [\n { timeSecondsFromWaveformReference: 0, relativeMagnitudeMultiplier: 1 },\n { timeSecondsFromWaveformReference: burstEnd, relativeMagnitudeMultiplier: 1 }\n ],\n limitations: [...flash.pulse.limitations,\n \"Quasi-continuous HSS burst: the pulse train is approximated by constant output over the burst support.\"]\n },\n outputControl: { ...flash.outputControl, scale: flash.outputControl.scale * power * eta * pulseEnergy / burstEnd }\n };\n const enabled = input.flashEnabled;\n return {\n modelId: HIGH_SPEED_SYNC_MODEL.id,\n modelVersion: HIGH_SPEED_SYNC_MODEL.version,\n flashEnabled: enabled,\n flashProfileId: flash.profileId,\n flashProfileVersion: flash.profileVersion,\n sourceId: flash.sourceTemplate.sourceId,\n syncMode: \"high-speed-sync\",\n syncStatus: enabled ? \"high-speed-sync-resolved\" : \"disabled\",\n captureModeId: input.timing.captureModeId,\n timingProfileId: input.timing.timingProfileId,\n syncCapabilityProfileId: capabilities.profileId,\n timeReference: \"first-opening-boundary-phase\",\n powerFraction: power,\n burstEnergyFractionOfFullPulse: eta,\n singlePulseIntegratedRelativeSeconds: pulseEnergy,\n burstStartSecondsFromCaptureReference: 0,\n burstEndSecondsFromCaptureReference: burstEnd,\n burstDurationSeconds: burstEnd,\n localExposureDurationRangeSeconds: { minimum: local.minimum, maximum: local.maximum },\n energyFractionOfSinglePulseRange: fraction,\n guideNumberFactorRange: { minimum: Math.sqrt(fraction.minimum), maximum: Math.sqrt(fraction.maximum) },\n uniformAcrossActiveFrame: local.minimum === local.maximum,\n burstFlashProfile: enabled ? burstFlashProfile : null,\n waveformTimeZeroSecondsFromCaptureReference: enabled ? 0 : null,\n releaseFrameBinding: !enabled || input.releaseFrame === undefined ? null : {\n sequenceId: input.releaseFrame.sequenceId,\n releaseFrameId: input.releaseFrame.releaseFrameId,\n frameIndex: input.releaseFrame.frameIndex,\n sceneTimeSecondsFromSequenceStartAtBurstStart: input.releaseFrame.sceneTimeSecondsFromSequenceStart,\n sceneTimeSecondsFromSequenceStartAtBurstEnd: input.releaseFrame.sceneTimeSecondsFromSequenceStart + burstEnd\n },\n hssModeled: true,\n ttlModeled: false,\n sensorReadoutTimingUsedAsExposureTiming: false,\n evidence: [...flash.evidence, ...capabilities.evidence, ...capabilities.highSpeedSync.evidence, ...input.timing.evidence],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"HSS burst is registered to exposure-boundary timing (first line opening to last line closing), never sensor data-readout timing.\",\n \"Pulse-train ripple, recycle/thermal limits beyond the declared burst energy fraction and branded flash protocols are not modeled.\"\n ]\n };\n}\n\n/**\n * Registers a resolved high-speed-sync burst as a temporal illumination overlay: a rectangular\n * waveform over [0, D]. Each line then collects the burst over its own local exposure window.\n */\nexport function createHighSpeedSyncIlluminationOverlay(\n input: Omit<CreateManualFlashIlluminationOverlayInput, \"resolvedSync\"> & { resolvedSync: ResolvedHighSpeedFlashSync }\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createHighSpeedSyncIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"illuminationProfileId\", \"temporalProfileId\", \"resolvedSync\"]);\n requireInputObject(input.resolvedSync, \"createHighSpeedSyncIlluminationOverlay resolvedSync\");\n return createManualFlashIlluminationOverlay({ ...input,\n flashProfile: input.resolvedSync.burstFlashProfile ?? input.flashProfile });\n}\n"]}
@@ -23,9 +23,9 @@ import { InvalidConfigurationError } from "../core/configuration-error.js";
23
23
  import { requireInputKeys, requireInputObject } from "../core/record-validation.js";
24
24
  import { resolveChartScene, resolveChartMaterial, chartMaterialInputs } from "./chart-scenes.js";
25
25
  /** The cell index grain of every layer: cells across and down the mask box. */
26
- export const CHART_MASK_INDEX_GRAIN = Object.freeze({ cellsX: 64, cellsY: 16 });
26
+ export const CHART_MASK_INDEX_GRAIN = /* @__PURE__ */ Object.freeze({ cellsX: 64, cellsY: 16 });
27
27
  /** Limits of a declared scene. */
28
- export const CHART_MATERIAL_LAYER_LIMITS = Object.freeze({ maximumLayers: 16, maximumShapes: 4096, maximumRings: 256, maximumEdges: 65_536 });
28
+ export const CHART_MATERIAL_LAYER_LIMITS = /* @__PURE__ */ Object.freeze({ maximumLayers: 16, maximumShapes: 4096, maximumRings: 256, maximumEdges: 65_536 });
29
29
  const SCENE_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/u;
30
30
  const finite = (value, name) => {
31
31
  if (typeof value !== "number" || !Number.isFinite(value))
@@ -1 +1 @@
1
- {"version":3,"file":"chart-material-layers.js","sourceRoot":"","sources":["../../src/facade/chart-material-layers.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Declared material scenes (#477): an engine chart under shape-mask layers, given as data rather than as a\n * `materialAt` function, so that both the float64 reference and the `webgpu-f32` chart stage can evaluate\n * them. An application that prints a label on a chart (a logo and a line of text as filled polygons and\n * stroked rings, in the label's own units) describes it here; the engine holds no label of its own.\n *\n * A layer maps its mask box, [0, unitsWidth] × [0, unitsHeight] with y down, onto a frame rectangle. Inside\n * that rectangle the layer decides the material: the ink material where any of its shapes contains the\n * point, its background material elsewhere. Later layers cover earlier ones, and the chart shows outside\n * every layer. Shapes are polygons under the non-zero winding rule (several rings per shape; a stroked\n * polyline is its rectangles as rings of one orientation) and annuli (stroked circles).\n *\n * Each layer carries a cell index of {@link CHART_MASK_INDEX_GRAIN} cells over its box: a cell lists the\n * shapes whose bounding box meets the cell grown by one cell on every side, so `containsUnits` tests only\n * those. A computed cell can be off by one from the true one only through the rounding of one subtraction\n * and one multiplication, far less than a cell (the grain is checked against the coordinates' magnitude\n * when the layer is resolved), and a shape left out of a cell's list lies a whole cell away from any point\n * that resolves to it, so the indexed test gives the full test's answer at every point. The GPU uses the same\n * index (docs/WEBGPU.md, \"Scene radiance on the GPU\").\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireInputKeys, requireInputObject } from \"../core/record-validation.js\";\nimport { resolveChartScene, resolveChartMaterial, chartMaterialInputs, type ChartReflectance, type ChartScene, type ResolvedChartScene } from \"./chart-scenes.js\";\nimport type { CallerMaterialScene, SceneMaterialPoint } from \"./scene-radiance.js\";\n\n/** A filled polygon: rings as flat [x0, y0, x1, y1, …] in mask units (y down), non-zero winding over all rings. */\nexport interface ChartMaskPolygon { kind: \"polygon\"; rings: readonly (readonly number[])[] }\n/** A stroked circle: the points at distance innerRadius ≤ d ≤ outerRadius from the centre, mask units. */\nexport interface ChartMaskAnnulus { kind: \"annulus\"; centerX: number; centerY: number; innerRadius: number; outerRadius: number }\nexport type ChartMaskShape = ChartMaskPolygon | ChartMaskAnnulus;\n/** A shape mask printed over the chart: its box [0, unitsWidth] × [0, unitsHeight] (y down) fills `rectangle` (frame units, v up). */\nexport interface ChartMaskLayer {\n kind: \"shape-mask\";\n rectangle: { u0: number; v0: number; u1: number; v1: number };\n unitsWidth: number;\n unitsHeight: number;\n /** 1 to 4096 shapes, in order; the ink material where any contains the point. */\n shapes: readonly ChartMaskShape[];\n backgroundReflectance: ChartReflectance;\n inkReflectance: ChartReflectance;\n}\n/** A chart under 1 to 16 shape-mask layers, as data; `resolveChartMaterialLayers` evaluates it. */\nexport interface ChartMaterialLayerScene { kind: \"material-layers\"; sceneId: string; chart: ChartScene; layers: readonly ChartMaskLayer[] }\n\n/** The cell index grain of every layer: cells across and down the mask box. */\nexport const CHART_MASK_INDEX_GRAIN = Object.freeze({ cellsX: 64, cellsY: 16 });\n/** Limits of a declared scene. */\nexport const CHART_MATERIAL_LAYER_LIMITS = Object.freeze({ maximumLayers: 16, maximumShapes: 4096, maximumRings: 256, maximumEdges: 65_536 });\n\n/** Internal: a shape with its bounding box and flattened edges (polygon) or squared radii (annulus). */\nexport type ResolvedChartMaskShape =\n | { kind: \"polygon\"; box: readonly [number, number, number, number]; edges: Float64Array }\n | { kind: \"annulus\"; box: readonly [number, number, number, number]; centerX: number; centerY: number; inner2: number; outer2: number };\nexport interface ResolvedChartMaskLayer {\n rectangle: { u0: number; v0: number; u1: number; v1: number };\n unitsWidth: number;\n unitsHeight: number;\n /** Mask units per frame unit: unitsWidth / (u1 − u0) and unitsHeight / (v1 − v0). */\n scaleX: number;\n scaleY: number;\n shapes: readonly ResolvedChartMaskShape[];\n cellsX: number;\n cellsY: number;\n cellWidth: number;\n cellHeight: number;\n /** Per cell (row by row), the shape indices whose bounding box meets the cell grown by one cell. */\n cells: readonly Uint32Array[];\n backgroundMaterial: number;\n inkMaterial: number;\n /** Whether a point in mask units is ink (through the cell index). */\n containsUnits(x: number, y: number): boolean;\n}\nexport interface ResolvedChartMaterialLayers {\n kind: \"material-layers\";\n sceneId: string;\n /** The chart under the layers; its materials come first in `materials`. */\n chart: ResolvedChartScene;\n layers: readonly ResolvedChartMaskLayer[];\n materials: ResolvedChartScene[\"materials\"];\n /** Internal: the caller input behind each material (undefined for an engine neutral), for the scene digest. */\n materialInputs: readonly unknown[];\n /** Material index at a frame point (u right, v up): the topmost layer whose rectangle holds the point, else the chart. */\n materialAt(u: number, v: number): number;\n /** The same scene as a caller material scene for `simulateCapture` and the display view (chart-local coordinates when the chart has a size). */\n callerScene: CallerMaterialScene;\n}\n\nconst SCENE_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/u;\nconst finite = (value: unknown, name: string): number => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) throw new InvalidConfigurationError(name + \" must be a finite number.\");\n return value;\n};\n/** The smallest cell the one-cell margin covers: the rounding of (x − 0)·scale is a few units in the last place of the coordinates. */\nconst minimumCell = (extent: number): number => Math.max(extent, Number.MIN_VALUE) * 2 ** -20;\n\nfunction resolvePolygon(shape: ChartMaskPolygon, name: string): ResolvedChartMaskShape {\n const rings = shape.rings;\n if (!Array.isArray(rings) || rings.length < 1 || rings.length > CHART_MATERIAL_LAYER_LIMITS.maximumRings) throw new InvalidConfigurationError(name + \" needs 1 to 256 rings.\");\n let count = 0;\n for (const ring of rings) {\n if (!Array.isArray(ring) || ring.length < 6 || ring.length % 2 !== 0) throw new InvalidConfigurationError(name + \" rings need at least three (x, y) vertices.\");\n count += ring.length / 2;\n }\n if (count > CHART_MATERIAL_LAYER_LIMITS.maximumEdges) throw new InvalidConfigurationError(name + \" has more than 65536 edges.\");\n const edges = new Float64Array(4 * count);\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity, e = 0;\n for (const ring of rings) {\n const n = ring.length / 2;\n for (let k = 0; k < n; k++) {\n const x0 = finite(ring[2 * k], name + \" vertex\"), y0 = finite(ring[2 * k + 1], name + \" vertex\");\n const next = k + 1 === n ? 0 : k + 1, x1 = finite(ring[2 * next], name + \" vertex\"), y1 = finite(ring[2 * next + 1], name + \" vertex\");\n edges[e++] = x0; edges[e++] = y0; edges[e++] = x1; edges[e++] = y1;\n minX = Math.min(minX, x0); minY = Math.min(minY, y0); maxX = Math.max(maxX, x0); maxY = Math.max(maxY, y0);\n }\n }\n return { kind: \"polygon\", box: [minX, minY, maxX, maxY], edges };\n}\n\n/** Non-zero winding over the edges (x0, y0, x1, y1), as the reference evaluates it; the GPU runs the same comparisons. */\nexport function polygonWinding(edges: Float64Array, x: number, y: number): number {\n let winding = 0;\n for (let k = 0; k < edges.length; k += 4) {\n const x0 = edges[k]!, y0 = edges[k + 1]!, x1 = edges[k + 2]!, y1 = edges[k + 3]!;\n const side = (x1 - x0) * (y - y0) - (x - x0) * (y1 - y0);\n if (y0 <= y) {\n if (y1 > y && side > 0) winding++;\n } else if (y1 <= y && side < 0) winding--;\n }\n return winding;\n}\n/** Whether a resolved shape contains a point in mask units (the full test, without the cell index). */\nexport function shapeContains(shape: ResolvedChartMaskShape, x: number, y: number): boolean {\n const b = shape.box;\n if (!(x >= b[0] && x <= b[2] && y >= b[1] && y <= b[3])) return false;\n if (shape.kind === \"annulus\") {\n const d2 = (x - shape.centerX) * (x - shape.centerX) + (y - shape.centerY) * (y - shape.centerY);\n return d2 >= shape.inner2 && d2 <= shape.outer2;\n }\n return polygonWinding(shape.edges, x, y) !== 0;\n}\n\nfunction resolveLayer(value: unknown, name: string, aspect: number, materials: ResolvedChartScene[\"materials\"][number][], inputs: unknown[]): ResolvedChartMaskLayer {\n requireInputObject(value, name);\n const layer = value as Record<string, unknown>;\n for (const key of Object.keys(layer)) {\n if (![\"kind\", \"rectangle\", \"unitsWidth\", \"unitsHeight\", \"shapes\", \"backgroundReflectance\", \"inkReflectance\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + name + \" field: \" + key + \".\");\n }\n if (layer.kind !== \"shape-mask\") throw new InvalidConfigurationError(name + \".kind must be shape-mask.\");\n requireInputObject(layer.rectangle, name + \".rectangle\");\n const r = layer.rectangle as Record<string, unknown>;\n for (const key of Object.keys(r)) if (![\"u0\", \"v0\", \"u1\", \"v1\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + name + \".rectangle field: \" + key + \".\");\n const u0 = finite(r.u0, name + \".rectangle.u0\"), v0 = finite(r.v0, name + \".rectangle.v0\"), u1 = finite(r.u1, name + \".rectangle.u1\"), v1 = finite(r.v1, name + \".rectangle.v1\");\n if (!(u1 > u0 && v1 > v0) || Math.max(Math.abs(u0), Math.abs(u1)) > 1e6 || Math.max(Math.abs(v0), Math.abs(v1)) > 1e6 * Math.max(1, aspect)) {\n throw new InvalidConfigurationError(name + \".rectangle needs u0 < u1 and v0 < v1 within 10^6 frame units.\");\n }\n const unitsWidth = finite(layer.unitsWidth, name + \".unitsWidth\"), unitsHeight = finite(layer.unitsHeight, name + \".unitsHeight\");\n if (!(unitsWidth > 0 && unitsHeight > 0 && unitsWidth <= 1e9 && unitsHeight <= 1e9)) throw new InvalidConfigurationError(name + \" units must be positive and at most 10^9.\");\n const list = layer.shapes;\n if (!Array.isArray(list) || list.length < 1 || list.length > CHART_MATERIAL_LAYER_LIMITS.maximumShapes) throw new InvalidConfigurationError(name + \".shapes must list 1 to 4096 shapes.\");\n const shapes = list.map((shape: unknown, index: number): ResolvedChartMaskShape => {\n const label = name + \".shapes[\" + index + \"]\";\n requireInputObject(shape, label);\n const s = shape as Record<string, unknown>;\n if (s.kind === \"polygon\") {\n for (const key of Object.keys(s)) if (key !== \"kind\" && key !== \"rings\") throw new InvalidConfigurationError(\"Unknown \" + label + \" field: \" + key + \".\");\n return resolvePolygon(s as unknown as ChartMaskPolygon, label);\n }\n if (s.kind !== \"annulus\") throw new InvalidConfigurationError(label + \".kind must be polygon or annulus.\");\n for (const key of Object.keys(s)) if (![\"kind\", \"centerX\", \"centerY\", \"innerRadius\", \"outerRadius\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + label + \" field: \" + key + \".\");\n const cx = finite(s.centerX, label + \".centerX\"), cy = finite(s.centerY, label + \".centerY\");\n const inner = finite(s.innerRadius, label + \".innerRadius\"), outer = finite(s.outerRadius, label + \".outerRadius\");\n if (!(inner >= 0 && outer > inner)) throw new InvalidConfigurationError(label + \" needs 0 ≤ innerRadius < outerRadius.\");\n return { kind: \"annulus\", box: [cx - outer, cy - outer, cx + outer, cy + outer], centerX: cx, centerY: cy, inner2: inner * inner, outer2: outer * outer };\n });\n for (const shape of shapes) {\n if (!shape.box.every((c) => Math.abs(c) <= 1e9)) throw new InvalidConfigurationError(name + \" shape coordinates must stay within 10^9 units.\");\n }\n const backgroundMaterial = materials.length;\n materials.push(resolveChartMaterial(layer.backgroundReflectance, name + \".backgroundReflectance\"));\n inputs.push(typeof layer.backgroundReflectance === \"number\" ? undefined : layer.backgroundReflectance);\n const inkMaterial = materials.length;\n materials.push(resolveChartMaterial(layer.inkReflectance, name + \".inkReflectance\"));\n inputs.push(typeof layer.inkReflectance === \"number\" ? undefined : layer.inkReflectance);\n // The cell index over the mask box; the grain must stay large against the coordinates' rounding (see the header).\n const { cellsX, cellsY } = CHART_MASK_INDEX_GRAIN, cellWidth = unitsWidth / cellsX, cellHeight = unitsHeight / cellsY;\n const extentX = Math.max(unitsWidth, ...shapes.map((s) => Math.max(Math.abs(s.box[0]), Math.abs(s.box[2]))));\n const extentY = Math.max(unitsHeight, ...shapes.map((s) => Math.max(Math.abs(s.box[1]), Math.abs(s.box[3]))));\n if (!(cellWidth > minimumCell(extentX) && cellHeight > minimumCell(extentY))) throw new InvalidConfigurationError(name + \": the shapes extend too far beyond the mask box for its cell index.\");\n const cells: Uint32Array[] = [];\n for (let j = 0; j < cellsY; j++) {\n for (let i = 0; i < cellsX; i++) {\n const x0 = (i - 1) * cellWidth, x1 = (i + 2) * cellWidth, y0 = (j - 1) * cellHeight, y1 = (j + 2) * cellHeight, listed: number[] = [];\n shapes.forEach((s, k) => { if (s.box[0] <= x1 && s.box[2] >= x0 && s.box[1] <= y1 && s.box[3] >= y0) listed.push(k); });\n cells.push(Uint32Array.from(listed));\n }\n }\n const scaleX = unitsWidth / (u1 - u0), scaleY = unitsHeight / (v1 - v0);\n return Object.freeze({ rectangle: Object.freeze({ u0, v0, u1, v1 }), unitsWidth, unitsHeight, scaleX, scaleY, shapes: Object.freeze(shapes), cellsX, cellsY, cellWidth, cellHeight,\n cells: Object.freeze(cells), backgroundMaterial, inkMaterial,\n containsUnits(x: number, y: number): boolean {\n let i = Math.floor(x / cellWidth), j = Math.floor(y / cellHeight);\n if (!(i > 0)) i = 0; else if (i >= cellsX) i = cellsX - 1;\n if (!(j > 0)) j = 0; else if (j >= cellsY) j = cellsY - 1;\n const list = cells[j * cellsX + i]!;\n for (let k = 0; k < list.length; k++) if (shapeContains(shapes[list[k]!]!, x, y)) return true;\n return false;\n } });\n}\n\n/**\n * Validates a declared material scene and resolves its chart (in a frame of `aspect` = height / width) and its\n * layers. `materialAt` is the float64 reference the GPU stage is checked against, and `callerScene` is the same\n * scene for `simulateCapture`'s `scene` option.\n */\nexport function resolveChartMaterialLayers(input: { scene: ChartMaterialLayerScene; aspect: number }): ResolvedChartMaterialLayers {\n requireInputKeys(input, \"resolveChartMaterialLayers\", [\"scene\", \"aspect\"]);\n const { scene, aspect } = input;\n requireInputObject(scene, \"scene\");\n const record = scene as unknown as Record<string, unknown>;\n for (const key of Object.keys(record)) if (![\"kind\", \"sceneId\", \"chart\", \"layers\"].includes(key)) throw new InvalidConfigurationError(\"Unknown scene field: \" + key + \".\");\n if (record.kind !== \"material-layers\") throw new InvalidConfigurationError(\"scene.kind must be material-layers.\");\n if (typeof record.sceneId !== \"string\" || !SCENE_ID.test(record.sceneId)) throw new InvalidConfigurationError(\"A material-layers scene needs a public sceneId.\");\n if (typeof aspect !== \"number\" || !Number.isFinite(aspect) || aspect <= 0) throw new InvalidConfigurationError(\"Chart aspect must be positive.\");\n const chart = resolveChartScene({ scene: record.chart as ChartScene, aspect });\n const list = record.layers;\n if (!Array.isArray(list) || list.length < 1 || list.length > CHART_MATERIAL_LAYER_LIMITS.maximumLayers) throw new InvalidConfigurationError(\"layers must list 1 to 16 shape-mask layers.\");\n const materials: ResolvedChartScene[\"materials\"][number][] = [...chart.materials], inputs: unknown[] = [...chartMaterialInputs(chart)];\n const layers = list.map((layer: unknown, index: number) => resolveLayer(layer, \"layers[\" + index + \"]\", aspect, materials, inputs));\n const materialAt = (u: number, v: number): number => {\n for (let l = layers.length - 1; l >= 0; l--) {\n const layer = layers[l]!, r = layer.rectangle;\n if (u < r.u0 || u > r.u1 || v < r.v0 || v > r.v1) continue;\n return layer.containsUnits((u - r.u0) * layer.scaleX, (r.v1 - v) * layer.scaleY) ? layer.inkMaterial : layer.backgroundMaterial;\n }\n return chart.materialAt(u, v);\n };\n const callerMaterials = materials.map((m, k) => (m.kind === \"neutral\" ? m.reflectance : inputs[k] as ChartReflectance));\n const callerScene: CallerMaterialScene = Object.freeze({ kind: \"material-function\" as const, sceneId: record.sceneId, materials: Object.freeze(callerMaterials),\n materialAt: (p: Readonly<SceneMaterialPoint>) => materialAt(p.chartU ?? p.u, p.chartV ?? p.v) });\n return Object.freeze({ kind: \"material-layers\" as const, sceneId: record.sceneId, chart, layers: Object.freeze(layers), materials: Object.freeze(materials),\n materialInputs: Object.freeze(inputs), materialAt, callerScene });\n}\n"]}
1
+ {"version":3,"file":"chart-material-layers.js","sourceRoot":"","sources":["../../src/facade/chart-material-layers.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Declared material scenes (#477): an engine chart under shape-mask layers, given as data rather than as a\n * `materialAt` function, so that both the float64 reference and the `webgpu-f32` chart stage can evaluate\n * them. An application that prints a label on a chart (a logo and a line of text as filled polygons and\n * stroked rings, in the label's own units) describes it here; the engine holds no label of its own.\n *\n * A layer maps its mask box, [0, unitsWidth] × [0, unitsHeight] with y down, onto a frame rectangle. Inside\n * that rectangle the layer decides the material: the ink material where any of its shapes contains the\n * point, its background material elsewhere. Later layers cover earlier ones, and the chart shows outside\n * every layer. Shapes are polygons under the non-zero winding rule (several rings per shape; a stroked\n * polyline is its rectangles as rings of one orientation) and annuli (stroked circles).\n *\n * Each layer carries a cell index of {@link CHART_MASK_INDEX_GRAIN} cells over its box: a cell lists the\n * shapes whose bounding box meets the cell grown by one cell on every side, so `containsUnits` tests only\n * those. A computed cell can be off by one from the true one only through the rounding of one subtraction\n * and one multiplication, far less than a cell (the grain is checked against the coordinates' magnitude\n * when the layer is resolved), and a shape left out of a cell's list lies a whole cell away from any point\n * that resolves to it, so the indexed test gives the full test's answer at every point. The GPU uses the same\n * index (docs/WEBGPU.md, \"Scene radiance on the GPU\").\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireInputKeys, requireInputObject } from \"../core/record-validation.js\";\nimport { resolveChartScene, resolveChartMaterial, chartMaterialInputs, type ChartReflectance, type ChartScene, type ResolvedChartScene } from \"./chart-scenes.js\";\nimport type { CallerMaterialScene, SceneMaterialPoint } from \"./scene-radiance.js\";\n\n/** A filled polygon: rings as flat [x0, y0, x1, y1, …] in mask units (y down), non-zero winding over all rings. */\nexport interface ChartMaskPolygon { kind: \"polygon\"; rings: readonly (readonly number[])[] }\n/** A stroked circle: the points at distance innerRadius ≤ d ≤ outerRadius from the centre, mask units. */\nexport interface ChartMaskAnnulus { kind: \"annulus\"; centerX: number; centerY: number; innerRadius: number; outerRadius: number }\nexport type ChartMaskShape = ChartMaskPolygon | ChartMaskAnnulus;\n/** A shape mask printed over the chart: its box [0, unitsWidth] × [0, unitsHeight] (y down) fills `rectangle` (frame units, v up). */\nexport interface ChartMaskLayer {\n kind: \"shape-mask\";\n rectangle: { u0: number; v0: number; u1: number; v1: number };\n unitsWidth: number;\n unitsHeight: number;\n /** 1 to 4096 shapes, in order; the ink material where any contains the point. */\n shapes: readonly ChartMaskShape[];\n backgroundReflectance: ChartReflectance;\n inkReflectance: ChartReflectance;\n}\n/** A chart under 1 to 16 shape-mask layers, as data; `resolveChartMaterialLayers` evaluates it. */\nexport interface ChartMaterialLayerScene { kind: \"material-layers\"; sceneId: string; chart: ChartScene; layers: readonly ChartMaskLayer[] }\n\n/** The cell index grain of every layer: cells across and down the mask box. */\nexport const CHART_MASK_INDEX_GRAIN = /* @__PURE__ */ Object.freeze({ cellsX: 64, cellsY: 16 });\n/** Limits of a declared scene. */\nexport const CHART_MATERIAL_LAYER_LIMITS = /* @__PURE__ */ Object.freeze({ maximumLayers: 16, maximumShapes: 4096, maximumRings: 256, maximumEdges: 65_536 });\n\n/** Internal: a shape with its bounding box and flattened edges (polygon) or squared radii (annulus). */\nexport type ResolvedChartMaskShape =\n | { kind: \"polygon\"; box: readonly [number, number, number, number]; edges: Float64Array }\n | { kind: \"annulus\"; box: readonly [number, number, number, number]; centerX: number; centerY: number; inner2: number; outer2: number };\nexport interface ResolvedChartMaskLayer {\n rectangle: { u0: number; v0: number; u1: number; v1: number };\n unitsWidth: number;\n unitsHeight: number;\n /** Mask units per frame unit: unitsWidth / (u1 − u0) and unitsHeight / (v1 − v0). */\n scaleX: number;\n scaleY: number;\n shapes: readonly ResolvedChartMaskShape[];\n cellsX: number;\n cellsY: number;\n cellWidth: number;\n cellHeight: number;\n /** Per cell (row by row), the shape indices whose bounding box meets the cell grown by one cell. */\n cells: readonly Uint32Array[];\n backgroundMaterial: number;\n inkMaterial: number;\n /** Whether a point in mask units is ink (through the cell index). */\n containsUnits(x: number, y: number): boolean;\n}\nexport interface ResolvedChartMaterialLayers {\n kind: \"material-layers\";\n sceneId: string;\n /** The chart under the layers; its materials come first in `materials`. */\n chart: ResolvedChartScene;\n layers: readonly ResolvedChartMaskLayer[];\n materials: ResolvedChartScene[\"materials\"];\n /** Internal: the caller input behind each material (undefined for an engine neutral), for the scene digest. */\n materialInputs: readonly unknown[];\n /** Material index at a frame point (u right, v up): the topmost layer whose rectangle holds the point, else the chart. */\n materialAt(u: number, v: number): number;\n /** The same scene as a caller material scene for `simulateCapture` and the display view (chart-local coordinates when the chart has a size). */\n callerScene: CallerMaterialScene;\n}\n\nconst SCENE_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/u;\nconst finite = (value: unknown, name: string): number => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) throw new InvalidConfigurationError(name + \" must be a finite number.\");\n return value;\n};\n/** The smallest cell the one-cell margin covers: the rounding of (x − 0)·scale is a few units in the last place of the coordinates. */\nconst minimumCell = (extent: number): number => Math.max(extent, Number.MIN_VALUE) * 2 ** -20;\n\nfunction resolvePolygon(shape: ChartMaskPolygon, name: string): ResolvedChartMaskShape {\n const rings = shape.rings;\n if (!Array.isArray(rings) || rings.length < 1 || rings.length > CHART_MATERIAL_LAYER_LIMITS.maximumRings) throw new InvalidConfigurationError(name + \" needs 1 to 256 rings.\");\n let count = 0;\n for (const ring of rings) {\n if (!Array.isArray(ring) || ring.length < 6 || ring.length % 2 !== 0) throw new InvalidConfigurationError(name + \" rings need at least three (x, y) vertices.\");\n count += ring.length / 2;\n }\n if (count > CHART_MATERIAL_LAYER_LIMITS.maximumEdges) throw new InvalidConfigurationError(name + \" has more than 65536 edges.\");\n const edges = new Float64Array(4 * count);\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity, e = 0;\n for (const ring of rings) {\n const n = ring.length / 2;\n for (let k = 0; k < n; k++) {\n const x0 = finite(ring[2 * k], name + \" vertex\"), y0 = finite(ring[2 * k + 1], name + \" vertex\");\n const next = k + 1 === n ? 0 : k + 1, x1 = finite(ring[2 * next], name + \" vertex\"), y1 = finite(ring[2 * next + 1], name + \" vertex\");\n edges[e++] = x0; edges[e++] = y0; edges[e++] = x1; edges[e++] = y1;\n minX = Math.min(minX, x0); minY = Math.min(minY, y0); maxX = Math.max(maxX, x0); maxY = Math.max(maxY, y0);\n }\n }\n return { kind: \"polygon\", box: [minX, minY, maxX, maxY], edges };\n}\n\n/** Non-zero winding over the edges (x0, y0, x1, y1), as the reference evaluates it; the GPU runs the same comparisons. */\nexport function polygonWinding(edges: Float64Array, x: number, y: number): number {\n let winding = 0;\n for (let k = 0; k < edges.length; k += 4) {\n const x0 = edges[k]!, y0 = edges[k + 1]!, x1 = edges[k + 2]!, y1 = edges[k + 3]!;\n const side = (x1 - x0) * (y - y0) - (x - x0) * (y1 - y0);\n if (y0 <= y) {\n if (y1 > y && side > 0) winding++;\n } else if (y1 <= y && side < 0) winding--;\n }\n return winding;\n}\n/** Whether a resolved shape contains a point in mask units (the full test, without the cell index). */\nexport function shapeContains(shape: ResolvedChartMaskShape, x: number, y: number): boolean {\n const b = shape.box;\n if (!(x >= b[0] && x <= b[2] && y >= b[1] && y <= b[3])) return false;\n if (shape.kind === \"annulus\") {\n const d2 = (x - shape.centerX) * (x - shape.centerX) + (y - shape.centerY) * (y - shape.centerY);\n return d2 >= shape.inner2 && d2 <= shape.outer2;\n }\n return polygonWinding(shape.edges, x, y) !== 0;\n}\n\nfunction resolveLayer(value: unknown, name: string, aspect: number, materials: ResolvedChartScene[\"materials\"][number][], inputs: unknown[]): ResolvedChartMaskLayer {\n requireInputObject(value, name);\n const layer = value as Record<string, unknown>;\n for (const key of Object.keys(layer)) {\n if (![\"kind\", \"rectangle\", \"unitsWidth\", \"unitsHeight\", \"shapes\", \"backgroundReflectance\", \"inkReflectance\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + name + \" field: \" + key + \".\");\n }\n if (layer.kind !== \"shape-mask\") throw new InvalidConfigurationError(name + \".kind must be shape-mask.\");\n requireInputObject(layer.rectangle, name + \".rectangle\");\n const r = layer.rectangle as Record<string, unknown>;\n for (const key of Object.keys(r)) if (![\"u0\", \"v0\", \"u1\", \"v1\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + name + \".rectangle field: \" + key + \".\");\n const u0 = finite(r.u0, name + \".rectangle.u0\"), v0 = finite(r.v0, name + \".rectangle.v0\"), u1 = finite(r.u1, name + \".rectangle.u1\"), v1 = finite(r.v1, name + \".rectangle.v1\");\n if (!(u1 > u0 && v1 > v0) || Math.max(Math.abs(u0), Math.abs(u1)) > 1e6 || Math.max(Math.abs(v0), Math.abs(v1)) > 1e6 * Math.max(1, aspect)) {\n throw new InvalidConfigurationError(name + \".rectangle needs u0 < u1 and v0 < v1 within 10^6 frame units.\");\n }\n const unitsWidth = finite(layer.unitsWidth, name + \".unitsWidth\"), unitsHeight = finite(layer.unitsHeight, name + \".unitsHeight\");\n if (!(unitsWidth > 0 && unitsHeight > 0 && unitsWidth <= 1e9 && unitsHeight <= 1e9)) throw new InvalidConfigurationError(name + \" units must be positive and at most 10^9.\");\n const list = layer.shapes;\n if (!Array.isArray(list) || list.length < 1 || list.length > CHART_MATERIAL_LAYER_LIMITS.maximumShapes) throw new InvalidConfigurationError(name + \".shapes must list 1 to 4096 shapes.\");\n const shapes = list.map((shape: unknown, index: number): ResolvedChartMaskShape => {\n const label = name + \".shapes[\" + index + \"]\";\n requireInputObject(shape, label);\n const s = shape as Record<string, unknown>;\n if (s.kind === \"polygon\") {\n for (const key of Object.keys(s)) if (key !== \"kind\" && key !== \"rings\") throw new InvalidConfigurationError(\"Unknown \" + label + \" field: \" + key + \".\");\n return resolvePolygon(s as unknown as ChartMaskPolygon, label);\n }\n if (s.kind !== \"annulus\") throw new InvalidConfigurationError(label + \".kind must be polygon or annulus.\");\n for (const key of Object.keys(s)) if (![\"kind\", \"centerX\", \"centerY\", \"innerRadius\", \"outerRadius\"].includes(key)) throw new InvalidConfigurationError(\"Unknown \" + label + \" field: \" + key + \".\");\n const cx = finite(s.centerX, label + \".centerX\"), cy = finite(s.centerY, label + \".centerY\");\n const inner = finite(s.innerRadius, label + \".innerRadius\"), outer = finite(s.outerRadius, label + \".outerRadius\");\n if (!(inner >= 0 && outer > inner)) throw new InvalidConfigurationError(label + \" needs 0 ≤ innerRadius < outerRadius.\");\n return { kind: \"annulus\", box: [cx - outer, cy - outer, cx + outer, cy + outer], centerX: cx, centerY: cy, inner2: inner * inner, outer2: outer * outer };\n });\n for (const shape of shapes) {\n if (!shape.box.every((c) => Math.abs(c) <= 1e9)) throw new InvalidConfigurationError(name + \" shape coordinates must stay within 10^9 units.\");\n }\n const backgroundMaterial = materials.length;\n materials.push(resolveChartMaterial(layer.backgroundReflectance, name + \".backgroundReflectance\"));\n inputs.push(typeof layer.backgroundReflectance === \"number\" ? undefined : layer.backgroundReflectance);\n const inkMaterial = materials.length;\n materials.push(resolveChartMaterial(layer.inkReflectance, name + \".inkReflectance\"));\n inputs.push(typeof layer.inkReflectance === \"number\" ? undefined : layer.inkReflectance);\n // The cell index over the mask box; the grain must stay large against the coordinates' rounding (see the header).\n const { cellsX, cellsY } = CHART_MASK_INDEX_GRAIN, cellWidth = unitsWidth / cellsX, cellHeight = unitsHeight / cellsY;\n const extentX = Math.max(unitsWidth, ...shapes.map((s) => Math.max(Math.abs(s.box[0]), Math.abs(s.box[2]))));\n const extentY = Math.max(unitsHeight, ...shapes.map((s) => Math.max(Math.abs(s.box[1]), Math.abs(s.box[3]))));\n if (!(cellWidth > minimumCell(extentX) && cellHeight > minimumCell(extentY))) throw new InvalidConfigurationError(name + \": the shapes extend too far beyond the mask box for its cell index.\");\n const cells: Uint32Array[] = [];\n for (let j = 0; j < cellsY; j++) {\n for (let i = 0; i < cellsX; i++) {\n const x0 = (i - 1) * cellWidth, x1 = (i + 2) * cellWidth, y0 = (j - 1) * cellHeight, y1 = (j + 2) * cellHeight, listed: number[] = [];\n shapes.forEach((s, k) => { if (s.box[0] <= x1 && s.box[2] >= x0 && s.box[1] <= y1 && s.box[3] >= y0) listed.push(k); });\n cells.push(Uint32Array.from(listed));\n }\n }\n const scaleX = unitsWidth / (u1 - u0), scaleY = unitsHeight / (v1 - v0);\n return Object.freeze({ rectangle: Object.freeze({ u0, v0, u1, v1 }), unitsWidth, unitsHeight, scaleX, scaleY, shapes: Object.freeze(shapes), cellsX, cellsY, cellWidth, cellHeight,\n cells: Object.freeze(cells), backgroundMaterial, inkMaterial,\n containsUnits(x: number, y: number): boolean {\n let i = Math.floor(x / cellWidth), j = Math.floor(y / cellHeight);\n if (!(i > 0)) i = 0; else if (i >= cellsX) i = cellsX - 1;\n if (!(j > 0)) j = 0; else if (j >= cellsY) j = cellsY - 1;\n const list = cells[j * cellsX + i]!;\n for (let k = 0; k < list.length; k++) if (shapeContains(shapes[list[k]!]!, x, y)) return true;\n return false;\n } });\n}\n\n/**\n * Validates a declared material scene and resolves its chart (in a frame of `aspect` = height / width) and its\n * layers. `materialAt` is the float64 reference the GPU stage is checked against, and `callerScene` is the same\n * scene for `simulateCapture`'s `scene` option.\n */\nexport function resolveChartMaterialLayers(input: { scene: ChartMaterialLayerScene; aspect: number }): ResolvedChartMaterialLayers {\n requireInputKeys(input, \"resolveChartMaterialLayers\", [\"scene\", \"aspect\"]);\n const { scene, aspect } = input;\n requireInputObject(scene, \"scene\");\n const record = scene as unknown as Record<string, unknown>;\n for (const key of Object.keys(record)) if (![\"kind\", \"sceneId\", \"chart\", \"layers\"].includes(key)) throw new InvalidConfigurationError(\"Unknown scene field: \" + key + \".\");\n if (record.kind !== \"material-layers\") throw new InvalidConfigurationError(\"scene.kind must be material-layers.\");\n if (typeof record.sceneId !== \"string\" || !SCENE_ID.test(record.sceneId)) throw new InvalidConfigurationError(\"A material-layers scene needs a public sceneId.\");\n if (typeof aspect !== \"number\" || !Number.isFinite(aspect) || aspect <= 0) throw new InvalidConfigurationError(\"Chart aspect must be positive.\");\n const chart = resolveChartScene({ scene: record.chart as ChartScene, aspect });\n const list = record.layers;\n if (!Array.isArray(list) || list.length < 1 || list.length > CHART_MATERIAL_LAYER_LIMITS.maximumLayers) throw new InvalidConfigurationError(\"layers must list 1 to 16 shape-mask layers.\");\n const materials: ResolvedChartScene[\"materials\"][number][] = [...chart.materials], inputs: unknown[] = [...chartMaterialInputs(chart)];\n const layers = list.map((layer: unknown, index: number) => resolveLayer(layer, \"layers[\" + index + \"]\", aspect, materials, inputs));\n const materialAt = (u: number, v: number): number => {\n for (let l = layers.length - 1; l >= 0; l--) {\n const layer = layers[l]!, r = layer.rectangle;\n if (u < r.u0 || u > r.u1 || v < r.v0 || v > r.v1) continue;\n return layer.containsUnits((u - r.u0) * layer.scaleX, (r.v1 - v) * layer.scaleY) ? layer.inkMaterial : layer.backgroundMaterial;\n }\n return chart.materialAt(u, v);\n };\n const callerMaterials = materials.map((m, k) => (m.kind === \"neutral\" ? m.reflectance : inputs[k] as ChartReflectance));\n const callerScene: CallerMaterialScene = Object.freeze({ kind: \"material-function\" as const, sceneId: record.sceneId, materials: Object.freeze(callerMaterials),\n materialAt: (p: Readonly<SceneMaterialPoint>) => materialAt(p.chartU ?? p.u, p.chartV ?? p.v) });\n return Object.freeze({ kind: \"material-layers\" as const, sceneId: record.sceneId, chart, layers: Object.freeze(layers), materials: Object.freeze(materials),\n materialInputs: Object.freeze(inputs), materialAt, callerScene });\n}\n"]}
@@ -23,7 +23,7 @@ import { resolveChartMaterialLayers } from "./chart-material-layers.js";
23
23
  import { buildPlanarSceneRadianceProvider, calculateIlluminantIrradianceScale, resolveCaptureIlluminant, tabulatedSpectrum } from "./scene-radiance.js";
24
24
  export const CHART_RADIANCE_BATCH_SCHEMA_VERSION = "0.1.0";
25
25
  /** `maximumQueries` is the default batch limit; a request may raise it with its own `maximumQueries`, up to `ceilingQueries`. */
26
- export const CHART_RADIANCE_BATCH_LIMITS = Object.freeze({ maximumQueries: 24_000_000, ceilingQueries: FULL_RESOLUTION_CEILING_PIXELS, maximumWavelengths: 256,
26
+ export const CHART_RADIANCE_BATCH_LIMITS = /* @__PURE__ */ Object.freeze({ maximumQueries: 24_000_000, ceilingQueries: FULL_RESOLUTION_CEILING_PIXELS, maximumWavelengths: 256,
27
27
  maximumChannels: 4 });
28
28
  export function calculateChartRadianceBatchPlan(input) {
29
29
  const r = requireAllowlistedRecord(input, ["schemaVersion", "scene", "illuminant", "illuminanceLux", "aspect", "points", "wavelengthsNanometers",