@photivra/engine 2.16.0 → 2.18.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.
- package/CHANGELOG.md +104 -1
- package/CITATION.cff +1 -1
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +24 -0
- package/dist/camera/lens-projection.d.ts +5 -0
- package/dist/camera/lens-projection.js +10 -0
- package/dist/camera/lens-projection.js.map +1 -1
- package/dist/camera/sensor-equivalence.d.ts +156 -0
- package/dist/camera/sensor-equivalence.js +208 -0
- package/dist/camera/sensor-equivalence.js.map +1 -0
- package/dist/capture/native-environment-tabulated.d.ts +5 -0
- package/dist/capture/native-environment-tabulated.js +1 -1
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +227 -0
- package/dist/equipment/generic-lens-catalogue.js +243 -0
- package/dist/equipment/generic-lens-catalogue.js.map +1 -0
- package/dist/equipment/ideal-lens.d.ts +25 -0
- package/dist/equipment/ideal-lens.js +21 -0
- package/dist/equipment/ideal-lens.js.map +1 -0
- package/dist/facade/catalogue-lens-signal.d.ts +94 -0
- package/dist/facade/catalogue-lens-signal.js +362 -0
- package/dist/facade/catalogue-lens-signal.js.map +1 -0
- package/dist/facade/defocus-bokeh-zones.d.ts +33 -0
- package/dist/facade/defocus-bokeh-zones.js +53 -0
- package/dist/facade/defocus-bokeh-zones.js.map +1 -0
- package/dist/facade/defocus-image-space-provider.d.ts +9 -0
- package/dist/facade/defocus-image-space-provider.js +101 -9
- package/dist/facade/defocus-image-space-provider.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +29 -0
- package/dist/facade/diffraction-provider.js +117 -11
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.js +4 -0
- package/dist/facade/display-view-gpu-session.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +10 -0
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.d.ts +61 -0
- package/dist/facade/display-view-lens-signal.js +502 -0
- package/dist/facade/display-view-lens-signal.js.map +1 -0
- package/dist/facade/expected-signal-setup.d.ts +15 -0
- package/dist/facade/expected-signal-setup.js +19 -2
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +13 -0
- package/dist/facade/expected-signal.js +155 -1
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/generic-lens-capture.d.ts +7 -0
- package/dist/facade/generic-lens-capture.js +9 -0
- package/dist/facade/generic-lens-capture.js.map +1 -0
- package/dist/facade/large-defocus-lattice.d.ts +39 -0
- package/dist/facade/large-defocus-lattice.js +64 -0
- package/dist/facade/large-defocus-lattice.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +5 -0
- package/dist/facade/scene-radiance.js +5 -2
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +67 -7
- package/dist/facade/simulate-capture.js +400 -64
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.js +23 -17
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/display-view-quality-gpu.d.ts +0 -9
- package/dist/gpu/display-view-quality-gpu.js +6 -0
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.js +2 -0
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/optics/defocus-bokeh-kernel.d.ts +207 -0
- package/dist/optics/defocus-bokeh-kernel.js +380 -0
- package/dist/optics/defocus-bokeh-kernel.js.map +1 -0
- package/dist/optics/defocus-disc-kernel.d.ts +41 -19
- package/dist/optics/defocus-disc-kernel.js +44 -23
- package/dist/optics/defocus-disc-kernel.js.map +1 -1
- package/dist/optics/generic-lens-psf.d.ts +68 -0
- package/dist/optics/generic-lens-psf.js +337 -0
- package/dist/optics/generic-lens-psf.js.map +1 -0
- package/dist/optics/illumination-vignetting.d.ts +6 -0
- package/dist/optics/illumination-vignetting.js +24 -7
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/sensor-environment-query.d.ts +6 -0
- package/dist/optics/sensor-environment-query.js +13 -6
- package/dist/optics/sensor-environment-query.js.map +1 -1
- package/dist/optics/site-kernel-runs.d.ts +77 -0
- package/dist/optics/site-kernel-runs.js +200 -0
- package/dist/optics/site-kernel-runs.js.map +1 -0
- package/dist/output/generic-lens-corrections.d.ts +24 -0
- package/dist/output/generic-lens-corrections.js +51 -0
- package/dist/output/generic-lens-corrections.js.map +1 -0
- package/docs/AGENT_GUIDE.md +4 -0
- package/docs/API_REFERENCE.md +77 -1
- package/docs/QUICK_START.md +305 -17
- package/docs/USAGE.md +98 -5
- package/docs/api/camera-sensor-equivalence.md +209 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +281 -0
- package/docs/api/equipment-ideal-lens.md +26 -0
- package/docs/api/exports.json +202 -2
- package/docs/api/facade-simulate-capture.md +48 -4
- package/docs/api/optics-defocus-bokeh-kernel.md +145 -0
- package/docs/api/optics-defocus-disc-kernel.md +22 -15
- package/docs/api/optics-sensor-environment-query.md +6 -0
- package/docs/api/output-generic-lens-corrections.md +39 -0
- package/llms.txt +3 -0
- package/package.json +1 -1
|
@@ -133,13 +133,12 @@ async function renderDisplayViewResult(context, viewInternals) {
|
|
|
133
133
|
function prepareView(context) {
|
|
134
134
|
const { ahd, antiAliasing, aspect, axisChannelResponse, boxSamples, buildProvider, callerScene, chart, materialLayers, chartReport, chartSize, diffraction, diffractionPsf, fNumber, focalLengthMm, focusDistanceM, height, highlightMode, exposureGain, illuminanceLux, illuminant, illuminantOption, imagingArea, intentOf, metresPerFrameUnit, noiseSeed, outputOptions, pitch, preset, provider, regimeByChannel, resolvedIso, isoReport, standardExposureDeviationStops, standardExposureIlluminanceLux, greyCardDeviationStops, metering, sceneOption, scenePreset, shutterSeconds, subjectDistanceM, toneCurve, whiteBalanceOption, whiteBalanceState, width, margin, mode, nativeHeight, nativeWidth, sourceSha256 } = context;
|
|
135
135
|
const kelvinInput = context.kelvinWhiteBalanceInput;
|
|
136
|
-
const portableKelvinWhiteBalance = kelvinInput ? () => resolvePortableColorTemperatureWhiteBalance(kelvinInput) : undefined;
|
|
137
136
|
// The engine's illuminant formulas (Planckian, CIE A, daylight locus) evaluated with the portable power and e^x − 1, so
|
|
138
137
|
// the view's radiances, irradiance scale and scene-illuminant white balance have the same bits in every JavaScript
|
|
139
138
|
// engine; they differ from the capture's own by at most a few ulps (docs/DISPLAY_VIEW.md, "Same bytes in every engine").
|
|
140
139
|
const viewIlluminant = resolvePortableCaptureIlluminant(illuminantOption), viewIrradianceScale = calculateIlluminantIrradianceScale(viewIlluminant.shape, illuminanceLux);
|
|
141
140
|
const viewProvider = buildProvider(viewIlluminant, viewIrradianceScale);
|
|
142
|
-
const viewWhiteBalanceState = whiteBalanceOption === "scene-illuminant" ? sceneIlluminantWhiteBalance(viewIlluminant) :
|
|
141
|
+
const viewWhiteBalanceState = whiteBalanceOption === "scene-illuminant" ? sceneIlluminantWhiteBalance(viewIlluminant) : kelvinInput ? resolvePortableColorTemperatureWhiteBalance(kelvinInput) : whiteBalanceState;
|
|
143
142
|
// The chart's materials likewise (a step wedge's geometric levels use the portable power); same geometry and order.
|
|
144
143
|
const viewChart = chart ? resolvePortableChartScene({ scene: sceneOption, aspect: chartSize ? chartSize.heightM / chartSize.widthM : aspect }) : undefined;
|
|
145
144
|
if (chart && viewChart.materials.length !== chart.materials.length)
|
|
@@ -149,17 +148,20 @@ function prepareView(context) {
|
|
|
149
148
|
// The tabulated expected signal's input (#394: shared with the capture's tabulated RAW path).
|
|
150
149
|
const sceneMaterials = viewChart ? viewChart.materials : callerScene?.kind === "material-function" ? callerScene.materials : undefined;
|
|
151
150
|
// Defocus (#492): the geometric disc on the site lattice, combined with the diffraction kernels in the tables (expected-signal-setup.ts).
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
// #553: with bokeh options (blades, spherical aberration) the capture built the shaped kernel; it replaces the disc.
|
|
152
|
+
const defocusDisc = context.defocus, defocusKernel = defocusDisc && defocusDisc.diameterSites > 0 ? defocusDisc.siteKernel ?? createDefocusDiscSiteKernel(defocusDisc.diameterSites) : null;
|
|
153
|
+
const shaped = defocusDisc?.siteKernel !== undefined;
|
|
154
|
+
// The combined radius is at most 32 + 512 sites (the diffraction and disc caps), as in the capture. #564: above 64 sites the kernel is
|
|
155
|
+
// convolved by runs after the in-focus signal (expected-signal.ts), the same sums regrouped.
|
|
154
156
|
const diffractionRadius = diffraction ? diffraction.kernelRadiusSamples : 0, combinedRadius = defocusKernel ? diffractionRadius + defocusKernel.radius : diffractionRadius;
|
|
155
157
|
const { offsets, signalInput } = buildExpectedSignalInput({ nativeWidth, nativeHeight, width, wavelengths, perNode, apertureNodes: apertureNodeOffsets(boxSamples), boxSamples,
|
|
156
|
-
antiAliasing, pitch, defocus: defocusKernel, diffraction: diffraction ? { radius: diffraction.kernelRadiusSamples, psf: diffractionPsf.configuration.psf, profileWavelengths: diffraction.profile.axes.wavelengthNm } : undefined,
|
|
158
|
+
antiAliasing, pitch, defocus: defocusKernel, ...(context.lensPsf ? { lensKernels: context.lensPsf.axisKernels(wavelengths) } : {}), diffraction: diffraction ? { radius: diffraction.kernelRadiusSamples, psf: diffractionPsf.configuration.psf, profileWavelengths: diffraction.profile.axes.wavelengthNm } : undefined,
|
|
157
159
|
materials: sceneMaterials && provider.chartMaterialAt ? { materialAt: provider.chartMaterialAt,
|
|
158
160
|
list: [...sceneMaterials.map((m, index) => (m.kind === "neutral" ? { neutral: m.reflectance } : { radiance: (nm) => viewProvider.materialRadiance(index, nm) })),
|
|
159
161
|
...(chartSize ? [{ neutral: chartSize.surroundReflectance }] : [])],
|
|
160
162
|
whiteRadiance: (nm) => viewIrradianceScale * viewIlluminant.shape.evaluate(nm) / Math.PI } : undefined,
|
|
161
163
|
radianceAt: viewProvider.radianceAt, imagingArea, focalLengthMm, focusDistanceM, subjectDistanceM, metresPerFrameUnit, caller: "simulateDisplayView" });
|
|
162
|
-
const kernels = signalInput.kernels;
|
|
164
|
+
const kernels = signalInput.kernels, largeDefocus = signalInput.largeKernel;
|
|
163
165
|
// Readout moments per channel: normalized value k·e with variance k²·(e + σ_read²) plus the ADC quantization (1/12 code², times d² before a digital gain d).
|
|
164
166
|
// #556: a development exposure push G multiplies the normalized value before the per-site clip at white: k → G·k and the constant variance → G²·(…).
|
|
165
167
|
// Without a push G = 1, and x·1 = x exactly in IEEE 754 arithmetic, so the moments are bit-identical to those without the push.
|
|
@@ -181,7 +183,7 @@ function prepareView(context) {
|
|
|
181
183
|
const toSrgb = resolveCaptureColorModel().xyzToCameraRgb, m = colour.cameraToXyz;
|
|
182
184
|
const matrix = [0, 1, 2].map((r) => [0, 1, 2].map((c) => toSrgb[r][0] * m[0][c] + toSrgb[r][1] * m[1][c] + toSrgb[r][2] * m[2][c]));
|
|
183
185
|
// Reach of a footprint's pixels into the scene, in sites: the demosaic (1), the largest query offset and the kernel radius.
|
|
184
|
-
const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0);
|
|
186
|
+
const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0) + (largeDefocus ? largeDefocus.radius : 0);
|
|
185
187
|
// The inputs of the AHD correction states (fixed here, so the correction key is too; #447).
|
|
186
188
|
const gains = colour.appliedGains, clipLevel = Math.min(...colour.appliedGains), viewToneCurve = toneCurve;
|
|
187
189
|
const ahdCorrection = ahd ? { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c] : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,
|
|
@@ -190,29 +192,30 @@ function prepareView(context) {
|
|
|
190
192
|
// #491: a fixed-size chart's placement for the GPU material lookup (the provider's chart-local units cu = u·m/h and the surround beyond the chart).
|
|
191
193
|
const placement = chartSize ? { chartUnitsPerFrameUnit: metresPerFrameUnit / (chartSize.widthM / 2), aspect: chartSize.heightM / chartSize.widthM } : null;
|
|
192
194
|
/** The renderer's setup of one view (with `ahdCollect`, a collect pass), and its expected signal. */
|
|
193
|
-
const setupOf = (v,
|
|
195
|
+
const setupOf = (v, { checkAbort, yieldControl }, ahdCollect) => {
|
|
196
|
+
const viewRegion = v.region ?? { x: 0, y: 0, width: v.width, height: v.height };
|
|
194
197
|
// The native columns the region's windows span, beyond one window's width: a filled band need not be wider (a speed hint).
|
|
195
|
-
|
|
198
|
+
// #563: through the lens (projection, distortion, vignetting, rotation) when the request has them.
|
|
199
|
+
const signal = (context.lens ?? createDisplayViewExpectedSignal)(signalInput, Math.ceil((viewRegion.width + 2) * nativeWidth / v.width));
|
|
196
200
|
return { signal, setup: { frameWidth: width, frameHeight: height, margin, nativeWidth, nativeHeight, viewWidth: v.width, viewHeight: v.height,
|
|
197
201
|
region: viewRegion, samplesPerAxis: v.samplesPerAxis, reachSites, bitDepth: v.bitDepth, seed: noiseSeed, signal, readout, demosaic: demosaicTable,
|
|
198
202
|
...(ahdCandidates && ahdCorrection ? { candidates: ahdCandidates, ahdCorrection } : {}), ...(ahdCollect ? { ahdCollect } : {}),
|
|
199
|
-
gains, clipLevel, matrix, toneCurve: viewToneCurve, yieldControl, checkAbort, gpu: { signalInput, chart: viewChart ?? null, layers: materialLayers ?? null, placement, ...(defocusKernel ? { defocusRadius: defocusKernel.radius } : {}) } } };
|
|
203
|
+
gains, clipLevel, matrix, toneCurve: viewToneCurve, yieldControl, checkAbort, gpu: { signalInput, chart: viewChart ?? null, layers: materialLayers ?? null, placement, ...(defocusKernel && !largeDefocus ? { defocusRadius: defocusKernel.radius } : {}) } } };
|
|
200
204
|
};
|
|
201
205
|
const correction = ahdCorrection ? { seed: noiseSeed, readout, gains, clipLevel, matrix, toneCurve: viewToneCurve, ahdCorrection } : undefined;
|
|
202
206
|
const collect = async (v, run) => {
|
|
203
207
|
const keys = new Set();
|
|
204
|
-
await renderDisplayView(setupOf(v,
|
|
208
|
+
await renderDisplayView(setupOf(v, run, keys).setup);
|
|
205
209
|
return Int32Array.from(keys).sort();
|
|
206
210
|
};
|
|
207
211
|
// #492: out of focus the view reads the defocus disc (its kernel in signalInput.kernels); the GPU Quality site pass gathers it (step 2c).
|
|
208
|
-
const gpuRequest = { ahd, defocus: defocusKernel !== null, diffraction: diffraction !== undefined, antiAliasing: antiAliasing !== undefined, boxSamples, toneCurve: viewToneCurve,
|
|
212
|
+
const gpuRequest = { ahd, lens: !!context.lens, defocus: defocusKernel !== null, ...(largeDefocus ? { largeDefocus: true } : {}), diffraction: diffraction !== undefined, antiAliasing: antiAliasing !== undefined, boxSamples, toneCurve: viewToneCurve,
|
|
209
213
|
scene: chart ? "chart" : materialLayers ? "material-layers" : callerScene.kind };
|
|
210
214
|
const render = async (v, run, viewInternals, gpu) => {
|
|
211
215
|
const { started, viewStarted } = run;
|
|
212
216
|
const assumptions = [...context.assumptions];
|
|
213
217
|
const assume = (id, kind, value, explanation) => { assumptions.push({ id, kind, value, explanation }); };
|
|
214
|
-
const
|
|
215
|
-
const { setup, signal } = setupOf(v, viewRegion, run);
|
|
218
|
+
const { setup, signal } = setupOf(v, run), viewRegion = setup.region;
|
|
216
219
|
// #481: the GPU session renders on the device when it can, else through the CPU reference, and labels which ran.
|
|
217
220
|
const cpu = () => renderDisplayView(setup);
|
|
218
221
|
const { rendered, execution } = gpu ? await gpu.render(setup, run.signal, cpu)
|
|
@@ -254,9 +257,12 @@ function prepareView(context) {
|
|
|
254
257
|
"the flat-neighbourhood state is an approximation at edges (docs/DISPLAY_VIEW.md, validation)." :
|
|
255
258
|
"The bilinear demosaic's linear kernels, exactly.");
|
|
256
259
|
if (defocusKernel) {
|
|
257
|
-
assume("view.defocus", "model", { kernel: diffraction ? "diffraction-convolved-with-disc" : "disc", defocusKernelRadiusSites: defocusKernel.radius,
|
|
258
|
-
diffractionKernelRadiusSites: diffraction ? diffractionRadius : null, kernelRadiusSites: combinedRadius, scientificStatus: "approximation"
|
|
259
|
-
|
|
260
|
+
assume("view.defocus", "model", { kernel: shaped ? (diffraction ? "diffraction-convolved-with-shaped-kernel" : "shaped-kernel") : diffraction ? "diffraction-convolved-with-disc" : "disc", defocusKernelRadiusSites: defocusKernel.radius,
|
|
261
|
+
diffractionKernelRadiusSites: diffraction ? diffractionRadius : null, kernelRadiusSites: combinedRadius, scientificStatus: "approximation", ...(largeDefocus ? { convolution: "runs" } : {}) },
|
|
262
|
+
// #564: the lens.defocus assumption explains the run convolution above 64 sites (convolution: "runs").
|
|
263
|
+
"The expected electrons of each real site read the scene on the site lattice through the defocus " + (shaped ? "kernel shaped by the lens (#553; see the lens.defocus assumption; " : "disc (") +
|
|
264
|
+
defocusKernel.diameterSites + " sites across, a " + defocusKernel.width + " × " +
|
|
265
|
+
defocusKernel.width + " window), as the capture's convolution does; the estimators then run unchanged on the blurred signal. " + (diffraction ?
|
|
260
266
|
"With lens.diffraction each spectral node's kernel is its diffraction kernel convolved with the disc (" + (2 * combinedRadius + 1) + " × " + (2 * combinedRadius + 1) + " taps): " +
|
|
261
267
|
"an approximation, because the PSF of a defocused wave is not the in-focus Airy pattern convolved with a geometric disc." :
|
|
262
268
|
"The disc is the same at every spectral node (geometric optics)."));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulate-display-view.js","sourceRoot":"","sources":["../../src/facade/simulate-display-view.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The public entry point of the display view (`simulateDisplayView`) and its renderer. `simulate-capture.ts` resolves the\n * request (`runCapture`) and calls the renderer it is given, so a bundle that imports only `simulateCapture` or\n * `simulateIdealReference` does not contain the display view (`display-view.ts`) or the portable evaluations it uses.\n * The design and its error analysis are in docs/DISPLAY_VIEW.md.\n */\n\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolvePortableColorTemperatureWhiteBalance, type ResolvedWhiteBalanceState } from \"../color/white-balance.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { prepareSensorColorDevelopment } from \"../color/sensor-color-development.js\";\nimport { buildExpectedSignalInput } from \"./expected-signal-setup.js\";\nimport type { DisplayViewExpectedSignalInput } from \"./expected-signal.js\";\nimport { resolveSensorReadoutRegime } from \"../sensor/raw-readout.js\";\nimport { resolvePortableChartScene, type ChartScene } from \"./chart-scenes.js\";\nimport { resolvePortableCaptureIlluminant, calculateIlluminantIrradianceScale } from \"./scene-radiance.js\";\nimport { ahdCandidateKernels, computeDisplayViewCorrectionStates, createDisplayViewExpectedSignal, displayViewCorrectionKey, renderDisplayView, type DisplayViewChannelReadout,\n type DisplayViewCorrectionSetup, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet, type DisplayViewExpectedSignal, type DisplayViewRenderResult, type DisplayViewSetup,\n EXACT_AREA_MEAN_MAX_PIXELS } from \"./display-view.js\";\nimport { runCapture, apertureNodeOffsets, bilinearPhaseProfiles, clockMs, fail, sceneIlluminantWhiteBalance, CAMERA_TO_XYZ, CHANNELS, DARK_CURRENT_ELECTRONS_PER_SECOND, FACADE_EVIDENCE,\n SIMULATE_CAPTURE_FACADE_VERSION, DISPLAY_VIEW_WITHOUT_VIEW, allowKeys, parseDisplayViewOption, type DisplayViewResult, type DisplayViewRunContext, type ParsedDisplayView,\n type SimulateCaptureAssumption, type SimulateCaptureOptions, type SimulateDisplayViewOptions } from \"./simulate-capture.js\";\nimport { createHostYield } from \"./host-yield.js\";\nimport { createDefocusDiscSiteKernel } from \"../optics/defocus-disc-kernel.js\";\nimport { cpuDisplayViewExecution, parsePrepareDisplayViewOptions, type DisplayViewExecution, type DisplayViewGpuRequest, type PrepareDisplayViewOptions } from \"./display-view-gpu.js\";\nimport type { DisplayViewGpuSession } from \"./display-view-gpu-session.js\";\n\nexport { serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet } from \"./display-view.js\";\n\n/**\n * The display view of a capture request: the image the real full-resolution capture (`simulateCapture(options)`) would\n * give after it is resized to `view.width` × `view.height` by area averaging in linear light, estimated at a cost that\n * follows the display pixels, not the capture's. Optics (lens diffraction, the anti-aliasing filter, the pixel aperture)\n * act at the real pixel pitch; the colour mosaic, demosaic and development are those of the real pixels; the noise is\n * that of the average of the real pixels, demosaic correlation included; exposure, white balance and tone are the\n * capture's. The result is labelled `kind: \"display-view\"`; it is not a capture.\n * @see docs/DISPLAY_VIEW.md and docs/QUICK_START.md, \"Display view\".\n */\nexport async function simulateDisplayView(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions): Promise<DisplayViewResult> {\n return await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context)) as DisplayViewResult;\n}\n/** Options of one {@link PreparedDisplayView} render. */\nexport interface PreparedDisplayViewRenderOptions {\n /** Aborting cancels this render only; the promise rejects with a domain error. The request's own `signal` applies to preparing only. */\n signal?: AbortSignal;\n}\n/**\n * 2.7: a display-view request resolved once (`prepareDisplayView`). `render(view)` gives the same result as\n * `simulateDisplayView(options, view)` for the prepared options, byte for byte (samples, view, exposure, scene, diagnostics\n * and assumptions; only `diagnostics.timingsMs` differ, and they cover the render only), without repeating the request's\n * setup: use it to render one view in many regions, for example on each worker of a progressive display.\n */\nexport interface PreparedDisplayView {\n /**\n * Renders a view of the prepared request. Renders may run concurrently; they share no state except read-only setup and the\n * realm's AHD correction states, which never change a byte (docs/DISPLAY_VIEW.md, \"AHD at low signal\"). With `gpu: \"auto\"`\n * or `\"require\"` (#481) GPU renders of one prepared view run one at a time on its device, and `diagnostics.fast.execution`\n * says whether the GPU or the CPU reference rendered the view, and why.\n */\n render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult>;\n /**\n * 2.11 (#481): releases the WebGPU device the view acquired (none with `gpu: \"off\"`, or when `gpuDevice` gave an accelerator,\n * whose device its owner keeps). Later renders run the CPU reference labelled `fallbackReason: \"disposed\"` (`\"auto\"`) or fail\n * with that reason (`\"require\"`). Idempotent.\n */\n dispose(): void;\n /**\n * 2.10 (#447): the key of this request's AHD low-signal correction states, or null when the request has no AHD\n * (`output.demosaic` other than \"ahd\"). Every input of the key is fixed when the request is prepared; two prepared views\n * with the same key read the same states.\n */\n correctionKey(): string | null;\n /**\n * 2.10 (#447): the grid keys of every correction state a render of `view` reads (ascending, whether or not this realm holds\n * them), found by a render of the view's region that records the states instead of computing them. No image is returned;\n * it costs about one render whose states are all held. Fails with an InvalidConfigurationError when the request has no AHD.\n */\n collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys>;\n /**\n * 2.10 (#447): computes the correction states of `gridKeys` (from `collectCorrectionStates`, or a share of them) as a render\n * would, stores them in this realm's cache and returns their values, for {@link bindDisplayViewCorrectionStates} in\n * another realm. States this realm holds are read, not computed. Yields and honours `signal` like `render`. Fails with an\n * InvalidConfigurationError when the request has no AHD or a grid key is out of range.\n */\n computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet>;\n}\n/**\n * 2.7 (#387): resolves a {@link simulateDisplayView} request once, without a view, and returns a handle whose `render(view)`\n * renders its views. The setup it does once (request validation, the camera, lens, scene, chart and illuminant, the channel\n * responses through the environment chain, the diffraction kernels, readout moments, demosaic tables and colour matrix) costs\n * about 0.3–1.3 s per call on a 24 MP request; a region costs only its own pixels. Errors in the request are raised here;\n * errors in the view by `render`.\n *\n * 2.11 (#481): `prepareOptions.gpu` chooses the renderer: `\"off\"` (default) is the CPU reference, today's bytes; `\"auto\"` renders\n * on WebGPU when a conforming device is available and the request is supported, else on the CPU, labelled; `\"require\"` fails\n * instead of falling back (`ImageKernelExecutionError`, acquisition failures here, later ones from `render`). `gpuDevice` is a\n * WebGPU entry point or an `ImageKernelAccelerator` whose device the view shares; without it the engine acquires one device\n * for the prepared view (the request's `signal` aborts the acquisition) and `dispose()` releases it. The realm's\n * `setWebGpuEnabled(false)` vetoes both GPU modes (`webgpu-disabled`). See docs/DISPLAY_VIEW.md, \"Rendering on the GPU\".\n * @see docs/QUICK_START.md, \"Display view\".\n */\nexport async function prepareDisplayView(options: SimulateCaptureOptions, prepareOptions?: PrepareDisplayViewOptions): Promise<PreparedDisplayView> {\n const gpuOptions = parsePrepareDisplayViewOptions(prepareOptions);\n let frameWidth = 0, frameHeight = 0;\n const prepared = await runCapture(options, \"display-view\", DISPLAY_VIEW_WITHOUT_VIEW, (context) => {\n frameWidth = context.width; frameHeight = context.height;\n return Promise.resolve(prepareView(context));\n }) as PreparedViewParts;\n // The GPU code is loaded only when a GPU mode asks for it, so bundles on the default stay without it.\n const session: DisplayViewGpuSession | null = gpuOptions.gpu === \"off\" ? null :\n await (await import(\"./display-view-gpu-session.js\")).openDisplayViewGpuSession(gpuOptions, prepared.gpuRequest, (options as { signal?: AbortSignal }).signal);\n /** One call's start times, cancellation (its own signal) and yielding. */\n const runOf = (renderOptions: PreparedDisplayViewRenderOptions | undefined): ViewRun => {\n const started = Date.now(), viewStarted = clockMs();\n const signal = renderOptions === undefined ? undefined : allowKeys(renderOptions, \"render options\", [\"signal\"]).signal as AbortSignal | undefined;\n if (signal !== undefined && (typeof signal !== \"object\" || signal === null || typeof signal.aborted !== \"boolean\")) fail(\"signal must be an AbortSignal.\");\n const checkAbort = (): void => { if (signal?.aborted) fail(\"simulateCapture aborted.\"); };\n checkAbort();\n return { started, viewStarted, checkAbort, yieldControl: createHostYield().yieldControl, signal };\n };\n const correctionOf = (caller: string): DisplayViewCorrectionSetup => prepared.correction ??\n fail(caller + \": the prepared request has no AHD low-signal correction (it applies with output.demosaic \\\"ahd\\\").\");\n const handle: PreparedDisplayView = Object.freeze({\n async render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult> {\n const run = runOf(renderOptions);\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return await prepared.render(parsed, run, undefined, session);\n },\n dispose(): void { session?.dispose(); },\n correctionKey(): string | null { return prepared.correction ? displayViewCorrectionKey(prepared.correction) : null; },\n async collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys> {\n const run = runOf(renderOptions), correction = correctionOf(\"collectCorrectionStates\");\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return { key: displayViewCorrectionKey(correction)!, gridKeys: await prepared.collect(parsed, run) };\n },\n async computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet> {\n const run = runOf(renderOptions), correction = correctionOf(\"computeCorrectionStates\");\n return await computeDisplayViewCorrectionStates({ ...correction, yieldControl: run.yieldControl, checkAbort: run.checkAbort }, gridKeys);\n }\n });\n PREPARED_INTERNALS.set(handle, async (view, renderOptions) => {\n const internals: ViewInternals = {};\n const result = await prepared.render(parseDisplayViewOption(view, frameWidth, frameHeight), runOf(renderOptions), internals, session);\n return { result, internals: internals.value! };\n });\n return handle;\n}\n/** The internal render of each prepared view (the same render as `render`, keeping its renderer's result). */\nconst PREPARED_INTERNALS = new WeakMap<PreparedDisplayView, (view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions) =>\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult }>>();\n/**\n * Internal (not exported from the package): renders a view of a prepared view as `render` does (the same GPU session and labels)\n * and also returns the renderer's noise-free expected linear values and noise standard deviations, whichever renderer ran (#480's\n * GPU producer, `scripts/lib/display-view-gpu-page.mjs`).\n */\nexport async function renderPreparedDisplayViewWithInternals(prepared: PreparedDisplayView, view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions):\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult }> {\n const render = PREPARED_INTERNALS.get(prepared);\n if (!render) fail(\"renderPreparedDisplayViewWithInternals needs a view returned by prepareDisplayView.\");\n return await render(view, renderOptions);\n}\n/**\n * Internal (not exported from the package): the display view plus its noise-free expected linear values and noise standard\n * deviations, for the validation scripts and tests.\n */\nexport async function simulateDisplayViewWithInternals(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions):\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult; signal: DisplayViewExpectedSignal; setup: DisplayViewSetup; signalInput: DisplayViewExpectedSignalInput }> {\n const internals: ViewInternals = {};\n const result = await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context, internals)) as DisplayViewResult;\n return { result, internals: internals.value!, signal: internals.signal!, setup: internals.setup!, signalInput: internals.signalInput! };\n}\n\n/** AHD low-signal correction (display view): draws per flat-neighbourhood state, and the pixel noise (linear light) above which it applies. */\nconst DISPLAY_VIEW_AHD_CORRECTION_DRAWS = 2048, DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD = 0.01;\n\ntype ViewInternals = { value?: DisplayViewRenderResult; signal?: DisplayViewExpectedSignal;\n /** #478: the render's setup and the expected signal's input, for the GPU display view's tests. */\n setup?: DisplayViewSetup; signalInput?: DisplayViewExpectedSignalInput };\n/** What one render of a prepared view needs from its call: its start times, cancellation and yielding. */\ninterface ViewRun { started: number; viewStarted: number; checkAbort: () => void; yieldControl: () => Promise<void>; signal?: AbortSignal | undefined }\ntype RenderPreparedView = (view: ParsedDisplayView, run: ViewRun, viewInternals?: ViewInternals, gpu?: DisplayViewGpuSession | null) => Promise<DisplayViewResult>;\n/**\n * A prepared request: its render, its collect pass (#447: the grid keys of the correction states a view's region reads) and\n * the inputs of its correction states (undefined without AHD).\n */\ninterface PreparedViewParts {\n render: RenderPreparedView;\n collect(view: ParsedDisplayView, run: ViewRun): Promise<Int32Array>;\n correction: DisplayViewCorrectionSetup | undefined;\n /** #481: what a GPU renderer is asked to support. */\n gpuRequest: DisplayViewGpuRequest;\n}\n\n/** Renders the display view of a resolved request (the last step of `runCapture` for \"display-view\"). */\nasync function renderDisplayViewResult(context: DisplayViewRunContext, viewInternals?: ViewInternals): Promise<DisplayViewResult> {\n const viewStarted = clockMs();\n return await prepareView(context).render(context.parsedView!, { started: context.started, viewStarted, checkAbort: context.checkAbort, yieldControl: context.yieldControl }, viewInternals);\n}\n\n/**\n * Internal (#387): the part of a display view that depends only on the request, done once (the portable illuminant, chart and\n * white balance, the channel responses, query offsets, diffraction kernels, readout moments, demosaic tables and colour\n * matrix). The returned function renders one view from it; it keeps no state between renders (each has its own expected-\n * signal caches, lookup count and assumptions), so its results are those of separate calls.\n */\nfunction prepareView(context: DisplayViewRunContext): PreparedViewParts {\n const { ahd, antiAliasing, aspect, axisChannelResponse, boxSamples, buildProvider, callerScene, chart, materialLayers, chartReport, chartSize, diffraction, diffractionPsf, fNumber, focalLengthMm, focusDistanceM, height, highlightMode, exposureGain, illuminanceLux, illuminant, illuminantOption, imagingArea, intentOf, metresPerFrameUnit, noiseSeed, outputOptions, pitch, preset, provider, regimeByChannel, resolvedIso, isoReport, standardExposureDeviationStops, standardExposureIlluminanceLux, greyCardDeviationStops, metering, sceneOption, scenePreset, shutterSeconds, subjectDistanceM, toneCurve, whiteBalanceOption, whiteBalanceState, width, margin, mode, nativeHeight, nativeWidth, sourceSha256 } = context;\n const kelvinInput = context.kelvinWhiteBalanceInput;\n const portableKelvinWhiteBalance = kelvinInput ? (): ResolvedWhiteBalanceState => resolvePortableColorTemperatureWhiteBalance(kelvinInput) : undefined;\n // The engine's illuminant formulas (Planckian, CIE A, daylight locus) evaluated with the portable power and e^x − 1, so\n // the view's radiances, irradiance scale and scene-illuminant white balance have the same bits in every JavaScript\n // engine; they differ from the capture's own by at most a few ulps (docs/DISPLAY_VIEW.md, \"Same bytes in every engine\").\n const viewIlluminant = resolvePortableCaptureIlluminant(illuminantOption), viewIrradianceScale = calculateIlluminantIrradianceScale(viewIlluminant.shape, illuminanceLux);\n const viewProvider = buildProvider(viewIlluminant, viewIrradianceScale);\n const viewWhiteBalanceState = whiteBalanceOption === \"scene-illuminant\" ? sceneIlluminantWhiteBalance(viewIlluminant) : portableKelvinWhiteBalance ? portableKelvinWhiteBalance() : whiteBalanceState;\n // The chart's materials likewise (a step wedge's geometric levels use the portable power); same geometry and order.\n const viewChart = chart ? resolvePortableChartScene({ scene: sceneOption as ChartScene, aspect: chartSize ? chartSize.heightM / chartSize.widthM : aspect }) : undefined;\n if (chart && viewChart!.materials.length !== chart.materials.length) fail(\"simulateDisplayView: the chart's materials could not be resolved portably.\");\n const { electronsPerRadiance, wavelengths, relativePerElectron } = axisChannelResponse(\"simulateDisplayView\");\n const perNode = CHANNELS.map((c) => Float64Array.from(wavelengths, (nm) => electronsPerRadiance[c].get(nm) ?? 0)) as [Float64Array, Float64Array, Float64Array];\n // The tabulated expected signal's input (#394: shared with the capture's tabulated RAW path).\n const sceneMaterials = viewChart ? viewChart.materials : callerScene?.kind === \"material-function\" ? callerScene.materials : undefined;\n // Defocus (#492): the geometric disc on the site lattice, combined with the diffraction kernels in the tables (expected-signal-setup.ts).\n const defocusDisc = context.defocus, defocusKernel = defocusDisc && defocusDisc.diameterSites > 0 ? createDefocusDiscSiteKernel(defocusDisc.diameterSites) : null;\n // The combined radius is at most 32 + 64 = 96 sites (the diffraction and disc caps), as in the capture.\n const diffractionRadius = diffraction ? diffraction.kernelRadiusSamples : 0, combinedRadius = defocusKernel ? diffractionRadius + defocusKernel.radius : diffractionRadius;\n const { offsets, signalInput } = buildExpectedSignalInput({ nativeWidth, nativeHeight, width, wavelengths, perNode, apertureNodes: apertureNodeOffsets(boxSamples), boxSamples,\n antiAliasing, pitch, defocus: defocusKernel, diffraction: diffraction ? { radius: diffraction.kernelRadiusSamples, psf: diffractionPsf!.configuration.psf, profileWavelengths: diffraction.profile.axes.wavelengthNm } : undefined,\n materials: sceneMaterials && provider.chartMaterialAt ? { materialAt: provider.chartMaterialAt,\n list: [...sceneMaterials.map((m, index) => (m.kind === \"neutral\" ? { neutral: m.reflectance } : { radiance: (nm: number): number => viewProvider.materialRadiance!(index, nm) })),\n ...(chartSize ? [{ neutral: chartSize.surroundReflectance }] : [])],\n whiteRadiance: (nm: number): number => viewIrradianceScale * viewIlluminant.shape.evaluate(nm) / Math.PI } : undefined,\n radianceAt: viewProvider.radianceAt, imagingArea, focalLengthMm, focusDistanceM, subjectDistanceM, metresPerFrameUnit, caller: \"simulateDisplayView\" });\n const kernels = signalInput.kernels;\n // Readout moments per channel: normalized value k·e with variance k²·(e + σ_read²) plus the ADC quantization (1/12 code², times d² before a digital gain d).\n // #556: a development exposure push G multiplies the normalized value before the per-site clip at white: k → G·k and the constant variance → G²·(…).\n // Without a push G = 1, and x·1 = x exactly in IEEE 754 arithmetic, so the moments are bit-identical to those without the push.\n const readout = CHANNELS.map((channel): DisplayViewChannelReadout => {\n const { readoutProfile, regimeId } = regimeByChannel[channel];\n const resolved = resolveSensorReadoutRegime({ profile: readoutProfile as Parameters<typeof resolveSensorReadoutRegime>[0][\"profile\"], regimeId });\n const k = relativePerElectron[channel], digitalGain = resolved.regime.adc.digitalGain ?? 1, gain = resolved.regime.systemConversionGainElectronsPerCode.value;\n const codeSpan = digitalGain / (gain * k), read = resolved.combinedReadNoiseRmsElectrons;\n const quantizationCodes = digitalGain * digitalGain / 12 + (digitalGain === 1 ? 0 : 1 / 12);\n return { perElectron: exposureGain * k, darkElectrons: DARK_CURRENT_ELECTRONS_PER_SECOND * shutterSeconds,\n constantVariance: exposureGain * exposureGain * (k * k * read * read + quantizationCodes / (codeSpan * codeSpan)) };\n }) as [DisplayViewChannelReadout, DisplayViewChannelReadout, DisplayViewChannelReadout];\n const phases = bilinearPhaseProfiles(), demosaicTable: { dx: number; dy: number; weight: number }[][][] = [];\n for (const phase of phases) demosaicTable[phase.phaseY * 2 + phase.phaseX] = CHANNELS.map((c) => phase.profile.kernels.find((k) => k.outputChannelId === c)!.contributions\n .map((t) => ({ dx: t.offsetX, dy: t.offsetY, weight: t.weight })));\n const viewIntent = intentOf(viewWhiteBalanceState), viewGains = viewIntent ? [viewIntent.channelGains.red, viewIntent.channelGains.green, viewIntent.channelGains.blue] : null;\n const colour = prepareSensorColorDevelopment(CAMERA_TO_XYZ as unknown as Parameters<typeof prepareSensorColorDevelopment>[0], viewGains, highlightMode);\n const toSrgb = resolveCaptureColorModel().xyzToCameraRgb, m = colour.cameraToXyz;\n const matrix = [0, 1, 2].map((r) => [0, 1, 2].map((c) => toSrgb[r]![0]! * m[0]![c]! + toSrgb[r]![1]! * m[1]![c]! + toSrgb[r]![2]! * m[2]![c]!));\n // Reach of a footprint's pixels into the scene, in sites: the demosaic (1), the largest query offset and the kernel radius.\n const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0);\n // The inputs of the AHD correction states (fixed here, so the correction key is too; #447).\n const gains = colour.appliedGains as [number, number, number], clipLevel = Math.min(...colour.appliedGains), viewToneCurve = toneCurve as \"identity\" | \"positive-reinhard-per-channel\";\n const ahdCorrection = ahd ? { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c]! : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,\n thresholdVariance: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD * DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : undefined;\n const ahdCandidates = ahd ? [0, 1, 2, 3].map((p) => ahdCandidateKernels(p % 2, Math.floor(p / 2))) : undefined;\n // #491: a fixed-size chart's placement for the GPU material lookup (the provider's chart-local units cu = u·m/h and the surround beyond the chart).\n const placement = chartSize ? { chartUnitsPerFrameUnit: metresPerFrameUnit / (chartSize.widthM / 2), aspect: chartSize.heightM / chartSize.widthM } : null;\n /** The renderer's setup of one view (with `ahdCollect`, a collect pass), and its expected signal. */\n const setupOf = (v: ParsedDisplayView, viewRegion: { x: number; y: number; width: number; height: number }, { checkAbort, yieldControl }: ViewRun,\n ahdCollect?: Set<number>): { setup: DisplayViewSetup; signal: DisplayViewExpectedSignal } => {\n // The native columns the region's windows span, beyond one window's width: a filled band need not be wider (a speed hint).\n const signal = createDisplayViewExpectedSignal(signalInput, Math.ceil((viewRegion.width + 2) * nativeWidth / v.width));\n return { signal, setup: { frameWidth: width, frameHeight: height, margin, nativeWidth, nativeHeight, viewWidth: v.width, viewHeight: v.height,\n region: viewRegion, samplesPerAxis: v.samplesPerAxis, reachSites, bitDepth: v.bitDepth, seed: noiseSeed, signal, readout, demosaic: demosaicTable,\n ...(ahdCandidates && ahdCorrection ? { candidates: ahdCandidates, ahdCorrection } : {}), ...(ahdCollect ? { ahdCollect } : {}),\n gains, clipLevel, matrix, toneCurve: viewToneCurve, yieldControl, checkAbort, gpu: { signalInput, chart: viewChart ?? null, layers: materialLayers ?? null, placement, ...(defocusKernel ? { defocusRadius: defocusKernel.radius } : {}) } } };\n };\n const correction: DisplayViewCorrectionSetup | undefined = ahdCorrection ? { seed: noiseSeed, readout, gains, clipLevel, matrix, toneCurve: viewToneCurve, ahdCorrection } : undefined;\n const collect = async (v: ParsedDisplayView, run: ViewRun): Promise<Int32Array> => {\n const keys = new Set<number>();\n await renderDisplayView(setupOf(v, v.region ?? { x: 0, y: 0, width: v.width, height: v.height }, run, keys).setup);\n return Int32Array.from(keys).sort();\n };\n // #492: out of focus the view reads the defocus disc (its kernel in signalInput.kernels); the GPU Quality site pass gathers it (step 2c).\n const gpuRequest: DisplayViewGpuRequest = { ahd, defocus: defocusKernel !== null, diffraction: diffraction !== undefined, antiAliasing: antiAliasing !== undefined, boxSamples, toneCurve: viewToneCurve,\n scene: chart ? \"chart\" : materialLayers ? \"material-layers\" : callerScene!.kind };\n const render: RenderPreparedView = async (v, run, viewInternals, gpu) => {\n const { started, viewStarted } = run;\n const assumptions: SimulateCaptureAssumption[] = [...context.assumptions];\n const assume = (id: string, kind: SimulateCaptureAssumption[\"kind\"], value: unknown, explanation: string): void => { assumptions.push({ id, kind, value, explanation }); };\n const viewRegion = v.region ?? { x: 0, y: 0, width: v.width, height: v.height };\n const { setup, signal } = setupOf(v, viewRegion, run);\n // #481: the GPU session renders on the device when it can, else through the CPU reference, and labels which ran.\n const cpu = (): Promise<DisplayViewRenderResult> => renderDisplayView(setup);\n const { rendered, execution }: { rendered: DisplayViewRenderResult; execution: DisplayViewExecution } = gpu ? await gpu.render(setup, run.signal, cpu)\n : { rendered: await cpu(), execution: cpuDisplayViewExecution(\"off\", null, null, null) };\n if (viewInternals) { viewInternals.value = rendered; viewInternals.signal = signal; viewInternals.setup = setup; viewInternals.signalInput = signalInput; }\n const viewMs = clockMs() - viewStarted, scaleX = width / v.width, scaleY = height / v.height;\n assume(\"view.definition\", \"model\", { resampling: \"area-average-linear-light\", width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY },\n \"The image the full-resolution capture of this request would give after resizing to \" + v.width + \" × \" + v.height + \": each display pixel is the area-weighted mean, in linear light (sRGB samples decoded with the sRGB EOTF), \" +\n \"of the real output pixels its rectangle covers (\" + scaleX + \" × \" + scaleY + \" real pixels), then sRGB-encoded and rounded. The real capture's own samples are rounded to the view's bit depth before averaging.\");\n const uniformSamplesPerAxis = Math.max(1, Math.round(v.samplesPerAxis / 4));\n const siteSentence = \"the expected electrons of the real sites its demosaic reads are exact at the real pitch (the scene sampled at those sites through the pixel aperture, \" +\n \"anti-aliasing filter and diffraction kernels, with the capture's own query arithmetic, so the colour mosaic and its aliasing are the real sensor's), and the per-site clip at white, the highlight clip, the tone curve \" +\n \"and the clip to [0, 1] act on the pixel's own noise distribution, approximated as normal.\";\n // 2.8 (#393): where a footprint holds at most 25 real pixels (and at most K²), every real pixel of it is evaluated once with its exact weight.\n if (rendered.estimation === \"exact-area-mean\") {\n assume(\"view.estimation\", \"model\", { method: \"exact-area-mean-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, realPixelsPerDisplayPixel: scaleX * scaleY,\n evaluatedRealPixels: rendered.sampleCount },\n \"Each display pixel's expected value is the exact area mean of the real pixels its rectangle covers: every real pixel it touches is evaluated once and weighted by its overlap with the rectangle \" +\n \"(w_j / A, summing to 1), so there is no sampling error. This applies because each rectangle holds \" + scaleX * scaleY + \" real pixels (\" + scaleX + \" × \" + scaleY + \"), at most \" + EXACT_AREA_MEAN_MAX_PIXELS + \" and at most K² = \" + v.samplesPerAxis * v.samplesPerAxis + \"; coarser views use a stratified estimate, which costs less there. \" +\n \"For each real pixel \" + siteSentence);\n } else {\n assume(\"view.estimation\", \"model\", { method: \"stratified-monte-carlo-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, uniformSamplesPerAxis,\n detailPixels: rendered.detailPixelCount, uniformPixels: rendered.uniformPixelCount },\n \"Each display pixel's expected value is the mean over K × K strata of its rectangle, one seeded uniformly jittered real pixel in each, so it is unbiased; the error is zero where the rectangle is uniform \" +\n \"and falls as K^-3/2 at an edge. K = \" + v.samplesPerAxis + \" where a fixed pilot grid over the rectangle (widened by the demosaic, filter and kernel reach) or a neighbouring pixel's grid finds more than one scene value, \" +\n \"K = \" + uniformSamplesPerAxis + \" elsewhere. For each sampled pixel \" + siteSentence);\n }\n assume(\"view.noise\", \"model\", { method: \"variance-of-the-area-mean\", distribution: \"normal\" },\n \"Noise of the mean of the real pixels: the covariance of the weighted sum of independent site noises (shot, dark, read and ADC), with the demosaic correlation (B_c = Σ β², in closed form from the rectangle) and the \" +\n \"expected slopes of the clips and the tone curve (Stein's lemma); the variance the linearization misses and the real pixels' output rounding are added per pixel. One correlated normal draw per display pixel, seeded \" +\n \"by sensor.noiseSeed: the same statistics as the resized capture, not the same realization.\");\n assume(\"view.demosaic\", \"model\", ahd ? { capture: \"ahd\", view: \"ahd-candidates-with-low-signal-correction\", correctedPixels: rendered.ahdCorrectedPixelCount,\n correctionDrawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS, correctionThresholdLinearStd: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : { capture: \"bilinear\", view: \"bilinear\" },\n ahd ? \"AHD is non-linear only in its choice between two linear candidates (green along the rows or the columns, red and blue from colour differences). The view propagates both candidates' exact linear statistics \" +\n \"and averages them. Where a sampled pixel's noise exceeds \" + DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD + \" (linear light), the choice reacts to the noise and shifts the colour, so the pixel adds the mean \" +\n \"difference between the engine's AHD steps and the two candidates on \" + DISPLAY_VIEW_AHD_CORRECTION_DRAWS + \" drawn noisy flat neighbourhoods (Poisson electrons plus read and ADC noise) with its channel means, \" +\n \"computed once per state of a logarithmic grid (8 steps per octave of the channel means) and interpolated trilinearly, a control variate with no per-pixel sampling noise; \" +\n \"the flat-neighbourhood state is an approximation at edges (docs/DISPLAY_VIEW.md, validation).\" :\n \"The bilinear demosaic's linear kernels, exactly.\");\n if (defocusKernel) {\n assume(\"view.defocus\", \"model\", { kernel: diffraction ? \"diffraction-convolved-with-disc\" : \"disc\", defocusKernelRadiusSites: defocusKernel.radius,\n diffractionKernelRadiusSites: diffraction ? diffractionRadius : null, kernelRadiusSites: combinedRadius, scientificStatus: \"approximation\" },\n \"The expected electrons of each real site read the scene on the site lattice through the defocus disc (\" + defocusKernel.diameterSites + \" sites across, a \" + defocusKernel.width + \" × \" +\n defocusKernel.width + \" window), as the capture's object-space convolution does; the estimators then run unchanged on the blurred signal. \" + (diffraction ?\n \"With lens.diffraction each spectral node's kernel is its diffraction kernel convolved with the disc (\" + (2 * combinedRadius + 1) + \" × \" + (2 * combinedRadius + 1) + \" taps): \" +\n \"an approximation, because the PSF of a defocused wave is not the in-focus Airy pattern convolved with a geometric disc.\" :\n \"The disc is the same at every spectral node (geometric optics).\"));\n }\n if (execution.backend === \"webgpu-f32\") {\n assume(\"view.execution\", \"model\", { backend: execution.backend, arithmetic: execution.arithmetic, errorBound: execution.errorBound, adapter: execution.adapter },\n \"Estimated on the GPU: this view was rendered by the WebGPU float32 display-view renderer, a labelled approximation of the float64 CPU reference within the a-priori \" +\n \"error bound reported in diagnostics.fast.execution.errorBound; it is not bit-identical to the reference. The device passed the engine's run-time conformance check first.\");\n }\n assume(\"view.source\", \"model\", { rendering: \"srgb\", format: v.format, ignoredCaptureOutput: [\"format\", \"colorEncoding\", \"bitDepth\", \"gamutMapping\", \"jpegQuantizationStep\", \"dng\", \"metadata\", \"maximumPixels\"].filter((k) => outputOptions[k] !== undefined) },\n \"The view shows the capture's sRGB rendering (its tone curve, white balance and highlight mode); the capture's file-format options do not apply to it.\");\n return Object.freeze({ kind: \"display-view\" as const, label: \"Display view: the full-resolution capture resized to \" + v.width + \" × \" + v.height + \" (estimated); not a capture.\",\n facadeVersion: SIMULATE_CAPTURE_FACADE_VERSION, engineApiVersion: ENGINE_API_VERSION,\n image: { width: viewRegion.width, height: viewRegion.height, format: v.format, samples: rendered.samples },\n view: { width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY, samplesPerAxis: v.samplesPerAxis, ...(v.region ? { region: { ...v.region } } : {}) },\n exposure: { mode, settings: { fNumber, shutterSeconds, iso: resolvedIso }, ev100: Math.log2(fNumber ** 2 / shutterSeconds), ...isoReport, standardExposureDeviationStops, standardExposureIlluminanceLux, greyCardDeviationStops, metering },\n scene: { sceneId: chart ? \"chart:\" + chart.preset : callerScene!.sceneId, preset: scenePreset, parameters: chart ? chart.parameters : {},\n illuminant: { id: illuminant.id, description: illuminant.description, illuminanceLux }, distanceM: subjectDistanceM,\n framedWidthM: 2 * metresPerFrameUnit, framedHeightM: 2 * metresPerFrameUnit * aspect, ...(chartReport ? { chart: chartReport } : {}), sourceSha256 },\n diagnostics: { sampleCount: rendered.sampleCount, siteEvaluations: rendered.siteCount, sceneLookups: signal.lookups, detailPixelCount: rendered.detailPixelCount,\n uniformPixelCount: rendered.uniformPixelCount, ahdCorrectedPixelCount: rendered.ahdCorrectedPixelCount, timingsMs: { view: viewMs, total: Date.now() - started },\n fast: Object.freeze({ ...context.fastReport, assurance: execution.backend === \"webgpu-f32\" ? \"approximation-with-a-priori-bound\" as const : context.fastReport.assurance, execution }),\n highlight: Object.freeze({ saturatedPixelCount: rendered.saturatedPixelCount, statistic: \"expected-value\" as const }) },\n provenance: { scientificStatus: \"approximation\" as const, cameraPresetId: preset.presetId, cameraPresetVersion: preset.presetVersion, evidence: [...FACADE_EVIDENCE, ...preset.evidence],\n composedContracts: [\"calculateEnvironmentSensorPhotoSignal\", \"resolveSensorReadoutRegime\", \"calculateSiteEffectiveSaturationCode\", ...(diffraction ? [\"createDiffractionLimitedPsfProfile\", \"resolveLensPsfConvolutionKernels\"] : []),\n ...(antiAliasing ? [\"resolveAntiAliasingSpatialKernel\"] : []), \"prepareSensorColorDevelopment\", \"display view estimator\"],\n limitations: [\"Estimated display view of the full-resolution capture: its expected value is a stratified Monte Carlo estimate and its noise is drawn from the variance of the area mean, so it has the resized capture's statistics, not its exact pixels; not a capture and not a measurement.\"] },\n assumptions: Object.freeze(assumptions.map((a) => Object.freeze(a))) });\n };\n return { render, collect, correction, gpuRequest };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"simulate-display-view.js","sourceRoot":"","sources":["../../src/facade/simulate-display-view.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,2CAA2C,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAmB,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,gCAAgC,EAAE,kCAAkC,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,mBAAmB,EAAE,kCAAkC,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,iBAAiB,EAE5I,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,2BAA2B,EAAE,aAAa,EAAE,QAAQ,EAAE,iCAAiC,EAAE,eAAe,EACtL,+BAA+B,EAAE,yBAAyB,EAAE,SAAS,EAAE,sBAAsB,EACC,MAAM,uBAAuB,CAAC;AAC9H,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAyF,MAAM,uBAAuB,CAAC;AAGvL,OAAO,EAAE,oCAAoC,EAAE,+BAA+B,EAA2E,MAAM,mBAAmB,CAAC;AAEnL;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAA+B,EAAE,IAAgC;IACzG,OAAO,MAAM,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAsB,CAAC;AAC7H,CAAC;AA8CD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA+B,EAAE,cAA0C;IAClH,MAAM,UAAU,GAAG,8BAA8B,CAAC,cAAc,CAAC,CAAC;IAClE,IAAI,UAAU,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE;QAChG,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;QAAC,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;QACzD,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAsB,CAAC;IACxB,sGAAsG;IACtG,MAAM,OAAO,GAAiC,UAAU,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7E,MAAM,CAAC,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC,CAAC,yBAAyB,CAAC,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAG,OAAoC,CAAC,MAAM,CAAC,CAAC;IACjK,0EAA0E;IAC1E,MAAM,KAAK,GAAG,CAAC,aAA2D,EAAW,EAAE;QACrF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,GAAG,OAAO,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,EAAE,gBAAgB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAiC,CAAC;QAClJ,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC;YAAE,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC3J,MAAM,UAAU,GAAG,GAAS,EAAE,GAAG,IAAI,MAAM,EAAE,OAAO;YAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IACpG,CAAC,CAAC;IACF,MAAM,YAAY,GAAG,CAAC,MAAc,EAA8B,EAAE,CAAC,QAAQ,CAAC,UAAU;QACtF,IAAI,CAAC,MAAM,GAAG,oGAAoG,CAAC,CAAC;IACtH,MAAM,MAAM,GAAwB,MAAM,CAAC,MAAM,CAAC;QAChD,KAAK,CAAC,MAAM,CAAC,IAAgC,EAAE,aAAgD;YAC7F,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACrE,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,KAAW,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACvC,aAAa,KAAoB,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,wBAAwB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACrH,KAAK,CAAC,uBAAuB,CAAC,IAAgC,EAAE,aAAgD;YAC9G,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;YACvF,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YACrE,OAAO,EAAE,GAAG,EAAE,wBAAwB,CAAC,UAAU,CAAE,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QACvG,CAAC;QACD,KAAK,CAAC,uBAAuB,CAAC,QAAoB,EAAE,aAAgD;YAClG,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;YACvF,OAAO,MAAM,kCAAkC,CAAC,EAAE,GAAG,UAAU,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC3I,CAAC;KACF,CAAC,CAAC;IACH,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE;QAC3D,MAAM,SAAS,GAAkB,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACtI,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,KAAM,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,8GAA8G;AAC9G,MAAM,kBAAkB,GAAG,IAAI,OAAO,EACyC,CAAC;AAChF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAAC,QAA6B,EAAE,IAAgC,EAAE,aAAgD;IAE5K,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,qFAAqF,CAAC,CAAC;IACzG,OAAO,MAAM,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AACD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CAAC,OAA+B,EAAE,IAAgC;IAEtH,MAAM,SAAS,GAAkB,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAsB,CAAC;IAC9I,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,KAAM,EAAE,MAAM,EAAE,SAAS,CAAC,MAAO,EAAE,KAAK,EAAE,SAAS,CAAC,KAAM,EAAE,WAAW,EAAE,SAAS,CAAC,WAAY,EAAE,CAAC;AAC1I,CAAC;AAED,+IAA+I;AAC/I,MAAM,iCAAiC,GAAG,IAAI,EAAE,qCAAqC,GAAG,IAAI,CAAC;AAoB7F,yGAAyG;AACzG,KAAK,UAAU,uBAAuB,CAAC,OAA8B,EAAE,aAA6B;IAClG,MAAM,WAAW,GAAG,OAAO,EAAE,CAAC;IAC9B,OAAO,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAW,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAC9L,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,OAA8B;IACjD,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,SAAS,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IACvsB,MAAM,WAAW,GAAG,OAAO,CAAC,uBAAuB,CAAC;IACpD,wHAAwH;IACxH,mHAAmH;IACnH,yHAAyH;IACzH,MAAM,cAAc,GAAG,gCAAgC,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,GAAG,kCAAkC,CAAC,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC1K,MAAM,YAAY,GAAG,aAAa,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;IACxE,MAAM,qBAAqB,GAAG,kBAAkB,KAAK,kBAAkB,CAAC,CAAC,CAAC,2BAA2B,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,2CAA2C,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACnN,oHAAoH;IACpH,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,yBAAyB,CAAC,EAAE,KAAK,EAAE,WAAyB,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzK,IAAI,KAAK,IAAI,SAAU,CAAC,SAAS,CAAC,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC,MAAM;QAAE,IAAI,CAAC,4EAA4E,CAAC,CAAC;IACxJ,MAAM,EAAE,oBAAoB,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,mBAAmB,CAAC,qBAAqB,CAAC,CAAC;IAC9G,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAA+C,CAAC;IAChK,8FAA8F;IAC9F,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,KAAK,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACvI,0IAA0I;IAC1I,qHAAqH;IACrH,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,WAAW,IAAI,WAAW,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,IAAI,2BAA2B,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5L,MAAM,MAAM,GAAG,WAAW,EAAE,UAAU,KAAK,SAAS,CAAC;IACrD,uIAAuI;IACvI,6FAA6F;IAC7F,MAAM,iBAAiB,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAC3K,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,wBAAwB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,mBAAmB,CAAC,UAAU,CAAC,EAAE,UAAU;QAC5K,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,mBAAmB,EAAE,GAAG,EAAE,cAAe,CAAC,aAAa,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS;QACzT,SAAS,EAAE,cAAc,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,eAAe;YAC5F,IAAI,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAU,EAAU,EAAE,CAAC,YAAY,CAAC,gBAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC/K,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrE,aAAa,EAAE,CAAC,EAAU,EAAU,EAAE,CAAC,mBAAmB,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;QACxH,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAC1J,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC;IAC5E,6JAA6J;IAC7J,qJAAqJ;IACrJ,gIAAgI;IAChI,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAA6B,EAAE;QAClE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,0BAA0B,CAAC,EAAE,OAAO,EAAE,cAA6E,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClJ,MAAM,CAAC,GAAG,mBAAmB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,oCAAoC,CAAC,KAAK,CAAC;QAC9J,MAAM,QAAQ,GAAG,WAAW,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,6BAA6B,CAAC;QACzF,MAAM,iBAAiB,GAAG,WAAW,GAAG,WAAW,GAAG,EAAE,GAAG,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5F,OAAO,EAAE,WAAW,EAAE,YAAY,GAAG,CAAC,EAAE,aAAa,EAAE,iCAAiC,GAAG,cAAc;YACvG,gBAAgB,EAAE,YAAY,GAAG,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,iBAAiB,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC;IACxH,CAAC,CAAsF,CAAC;IACxF,MAAM,MAAM,GAAG,qBAAqB,EAAE,EAAE,aAAa,GAAqD,EAAE,CAAC;IAC7G,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,aAAa,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,CAAE,CAAC,aAAa;aACvK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/K,MAAM,MAAM,GAAG,6BAA6B,CAAC,aAA+E,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IACxJ,MAAM,MAAM,GAAG,wBAAwB,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;IACjF,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;IAChJ,4HAA4H;IAC5H,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrM,4FAA4F;IAC5F,MAAM,KAAK,GAAG,MAAM,CAAC,YAAwC,EAAE,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,aAAa,GAAG,SAAyD,CAAC;IACvL,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,iCAAiC;QACnL,iBAAiB,EAAE,qCAAqC,GAAG,qCAAqC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACjH,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/G,oJAAoJ;IACpJ,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,kBAAkB,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3J,qGAAqG;IACrG,MAAM,OAAO,GAAG,CAAC,CAAoB,EAAE,EAAE,UAAU,EAAE,YAAY,EAAW,EAAE,UAAwB,EAAkE,EAAE;QACxK,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAChF,2HAA2H;QAC3H,mGAAmG;QACnG,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,+BAA+B,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACzI,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM;gBAC3I,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa;gBACjJ,GAAG,CAAC,aAAa,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9H,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,IAAI,IAAI,EAAE,MAAM,EAAE,cAAc,IAAI,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACpQ,CAAC,CAAC;IACF,MAAM,UAAU,GAA2C,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvL,MAAM,OAAO,GAAG,KAAK,EAAE,CAAoB,EAAE,GAAY,EAAuB,EAAE;QAChF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;QACrD,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC,CAAC;IACF,0IAA0I;IAC1I,MAAM,UAAU,GAA0B,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,WAAW,KAAK,SAAS,EAAE,YAAY,EAAE,YAAY,KAAK,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa;QAC7Q,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAY,CAAC,IAAI,EAAE,CAAC;IACpF,MAAM,MAAM,GAAuB,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE;QACtE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QACrC,MAAM,WAAW,GAAgC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,IAAuC,EAAE,KAAc,EAAE,WAAmB,EAAQ,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3K,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;QACrE,iHAAiH;QACjH,MAAM,GAAG,GAAG,GAAqC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC7E,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAA2E,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;YACpJ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,EAAE,SAAS,EAAE,uBAAuB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAC3F,IAAI,aAAa,EAAE,CAAC;YAAC,aAAa,CAAC,KAAK,GAAG,QAAQ,CAAC;YAAC,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;YAAC,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC;YAAC,aAAa,CAAC,WAAW,GAAG,WAAW,CAAC;QAAC,CAAC;QAC3J,MAAM,MAAM,GAAG,OAAO,EAAE,GAAG,WAAW,EAAE,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QAC7F,MAAM,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,2BAA2B,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EACtK,qFAAqF,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,MAAM,GAAG,6GAA6G;YAClO,kDAAkD,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,oIAAoI,CAAC,CAAC;QACvN,MAAM,qBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5E,MAAM,YAAY,GAAG,wJAAwJ;YAC3K,0NAA0N;YAC1N,2FAA2F,CAAC;QAC9F,+IAA+I;QAC/I,IAAI,QAAQ,CAAC,UAAU,KAAK,iBAAiB,EAAE,CAAC;YAC9C,MAAM,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kCAAkC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,yBAAyB,EAAE,MAAM,GAAG,MAAM;gBAC3J,mBAAmB,EAAE,QAAQ,CAAC,WAAW,EAAE,EAC3C,mMAAmM;gBACnM,oGAAoG,GAAG,MAAM,GAAG,MAAM,GAAG,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,aAAa,GAAG,0BAA0B,GAAG,oBAAoB,GAAG,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,GAAG,qEAAqE;gBACrV,sBAAsB,GAAG,YAAY,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,yCAAyC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,qBAAqB;gBAC7I,YAAY,EAAE,QAAQ,CAAC,gBAAgB,EAAE,aAAa,EAAE,QAAQ,CAAC,iBAAiB,EAAE,EACpF,4MAA4M;gBAC5M,sCAAsC,GAAG,CAAC,CAAC,cAAc,GAAG,kKAAkK;gBAC9N,MAAM,GAAG,qBAAqB,GAAG,qCAAqC,GAAG,YAAY,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,YAAY,EAAE,QAAQ,EAAE,EAC3F,wNAAwN;YACxN,wNAAwN;YACxN,4FAA4F,CAAC,CAAC;QAChG,MAAM,CAAC,eAAe,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,2CAA2C,EAAE,eAAe,EAAE,QAAQ,CAAC,sBAAsB;YAC1J,uBAAuB,EAAE,iCAAiC,EAAE,4BAA4B,EAAE,qCAAqC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,EAC7K,GAAG,CAAC,CAAC,CAAC,+MAA+M;YACnN,2DAA2D,GAAG,qCAAqC,GAAG,oGAAoG;YAC1M,sEAAsE,GAAG,iCAAiC,GAAG,uGAAuG;YACpN,4KAA4K;YAC5K,+FAA+F,CAAC,CAAC;YACjG,kDAAkD,CAAC,CAAC;QACxD,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,CAAC,cAAc,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,MAAM,EAAE,wBAAwB,EAAE,aAAa,CAAC,MAAM;gBACxO,4BAA4B,EAAE,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;YAC9L,uGAAuG;YACvG,kGAAkG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,oEAAoE,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAC/L,aAAa,CAAC,aAAa,GAAG,mBAAmB,GAAG,aAAa,CAAC,KAAK,GAAG,KAAK;gBAC/E,aAAa,CAAC,KAAK,GAAG,wGAAwG,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC7I,uGAAuG,GAAG,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC,GAAG,UAAU;oBAClL,yHAAyH,CAAC,CAAC;gBAC3H,iEAAiE,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,SAAS,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;YACvC,MAAM,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,EAC9J,sKAAsK;gBACtK,2KAA2K,CAAC,CAAC;QACjL,CAAC;QACD,MAAM,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,sBAAsB,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,EAAE,EAC7P,uJAAuJ,CAAC,CAAC;QAC3J,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,cAAuB,EAAE,KAAK,EAAE,uDAAuD,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,MAAM,GAAG,8BAA8B;YAChL,aAAa,EAAE,+BAA+B,EAAE,gBAAgB,EAAE,kBAAkB;YACpF,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE;YAC1G,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;YACtL,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,cAAc,CAAC,EAAE,GAAG,SAAS,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,QAAQ,EAAE;YAC5O,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;gBACtI,UAAU,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,gBAAgB;gBACnH,YAAY,EAAE,CAAC,GAAG,kBAAkB,EAAE,aAAa,EAAE,CAAC,GAAG,kBAAkB,GAAG,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE;YACtJ,WAAW,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,eAAe,EAAE,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;gBAC9J,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE;gBAChK,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,mCAA4C,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC;gBACtL,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,EAAE,SAAS,EAAE,gBAAyB,EAAE,CAAC,EAAE;YACzH,UAAU,EAAE,EAAE,gBAAgB,EAAE,eAAwB,EAAE,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,CAAC,GAAG,eAAe,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;gBACtL,iBAAiB,EAAE,CAAC,uCAAuC,EAAE,4BAA4B,EAAE,sCAAsC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,oCAAoC,EAAE,kCAAkC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnO,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,+BAA+B,EAAE,wBAAwB,CAAC;gBAC3H,WAAW,EAAE,CAAC,kRAAkR,CAAC,EAAE;YACrS,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AACrD,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The public entry point of the display view (`simulateDisplayView`) and its renderer. `simulate-capture.ts` resolves the\n * request (`runCapture`) and calls the renderer it is given, so a bundle that imports only `simulateCapture` or\n * `simulateIdealReference` does not contain the display view (`display-view.ts`) or the portable evaluations it uses.\n * The design and its error analysis are in docs/DISPLAY_VIEW.md.\n */\n\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolvePortableColorTemperatureWhiteBalance } from \"../color/white-balance.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { prepareSensorColorDevelopment } from \"../color/sensor-color-development.js\";\nimport { buildExpectedSignalInput } from \"./expected-signal-setup.js\";\nimport type { DisplayViewExpectedSignalInput } from \"./expected-signal.js\";\nimport { resolveSensorReadoutRegime } from \"../sensor/raw-readout.js\";\nimport { resolvePortableChartScene, type ChartScene } from \"./chart-scenes.js\";\nimport { resolvePortableCaptureIlluminant, calculateIlluminantIrradianceScale } from \"./scene-radiance.js\";\nimport { ahdCandidateKernels, computeDisplayViewCorrectionStates, createDisplayViewExpectedSignal, displayViewCorrectionKey, renderDisplayView, type DisplayViewChannelReadout,\n type DisplayViewCorrectionSetup, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet, type DisplayViewExpectedSignal, type DisplayViewRenderResult, type DisplayViewSetup,\n EXACT_AREA_MEAN_MAX_PIXELS } from \"./display-view.js\";\nimport { runCapture, apertureNodeOffsets, bilinearPhaseProfiles, clockMs, fail, sceneIlluminantWhiteBalance, CAMERA_TO_XYZ, CHANNELS, DARK_CURRENT_ELECTRONS_PER_SECOND, FACADE_EVIDENCE,\n SIMULATE_CAPTURE_FACADE_VERSION, DISPLAY_VIEW_WITHOUT_VIEW, allowKeys, parseDisplayViewOption, type DisplayViewResult, type DisplayViewRunContext, type ParsedDisplayView,\n type SimulateCaptureAssumption, type SimulateCaptureOptions, type SimulateDisplayViewOptions } from \"./simulate-capture.js\";\nimport { createHostYield } from \"./host-yield.js\";\nimport { createDefocusDiscSiteKernel } from \"../optics/defocus-disc-kernel.js\";\nimport { cpuDisplayViewExecution, parsePrepareDisplayViewOptions, type DisplayViewExecution, type DisplayViewGpuRequest, type PrepareDisplayViewOptions } from \"./display-view-gpu.js\";\nimport type { DisplayViewGpuSession } from \"./display-view-gpu-session.js\";\n\nexport { serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet } from \"./display-view.js\";\n\n/**\n * The display view of a capture request: the image the real full-resolution capture (`simulateCapture(options)`) would\n * give after it is resized to `view.width` × `view.height` by area averaging in linear light, estimated at a cost that\n * follows the display pixels, not the capture's. Optics (lens diffraction, the anti-aliasing filter, the pixel aperture)\n * act at the real pixel pitch; the colour mosaic, demosaic and development are those of the real pixels; the noise is\n * that of the average of the real pixels, demosaic correlation included; exposure, white balance and tone are the\n * capture's. The result is labelled `kind: \"display-view\"`; it is not a capture.\n * @see docs/DISPLAY_VIEW.md and docs/QUICK_START.md, \"Display view\".\n */\nexport async function simulateDisplayView(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions): Promise<DisplayViewResult> {\n return await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context)) as DisplayViewResult;\n}\n/** Options of one {@link PreparedDisplayView} render. */\nexport interface PreparedDisplayViewRenderOptions {\n /** Aborting cancels this render only; the promise rejects with a domain error. The request's own `signal` applies to preparing only. */\n signal?: AbortSignal;\n}\n/**\n * 2.7: a display-view request resolved once (`prepareDisplayView`). `render(view)` gives the same result as\n * `simulateDisplayView(options, view)` for the prepared options, byte for byte (samples, view, exposure, scene, diagnostics\n * and assumptions; only `diagnostics.timingsMs` differ, and they cover the render only), without repeating the request's\n * setup: use it to render one view in many regions, for example on each worker of a progressive display.\n */\nexport interface PreparedDisplayView {\n /**\n * Renders a view of the prepared request. Renders may run concurrently; they share no state except read-only setup and the\n * realm's AHD correction states, which never change a byte (docs/DISPLAY_VIEW.md, \"AHD at low signal\"). With `gpu: \"auto\"`\n * or `\"require\"` (#481) GPU renders of one prepared view run one at a time on its device, and `diagnostics.fast.execution`\n * says whether the GPU or the CPU reference rendered the view, and why.\n */\n render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult>;\n /**\n * 2.11 (#481): releases the WebGPU device the view acquired (none with `gpu: \"off\"`, or when `gpuDevice` gave an accelerator,\n * whose device its owner keeps). Later renders run the CPU reference labelled `fallbackReason: \"disposed\"` (`\"auto\"`) or fail\n * with that reason (`\"require\"`). Idempotent.\n */\n dispose(): void;\n /**\n * 2.10 (#447): the key of this request's AHD low-signal correction states, or null when the request has no AHD\n * (`output.demosaic` other than \"ahd\"). Every input of the key is fixed when the request is prepared; two prepared views\n * with the same key read the same states.\n */\n correctionKey(): string | null;\n /**\n * 2.10 (#447): the grid keys of every correction state a render of `view` reads (ascending, whether or not this realm holds\n * them), found by a render of the view's region that records the states instead of computing them. No image is returned;\n * it costs about one render whose states are all held. Fails with an InvalidConfigurationError when the request has no AHD.\n */\n collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys>;\n /**\n * 2.10 (#447): computes the correction states of `gridKeys` (from `collectCorrectionStates`, or a share of them) as a render\n * would, stores them in this realm's cache and returns their values, for {@link bindDisplayViewCorrectionStates} in\n * another realm. States this realm holds are read, not computed. Yields and honours `signal` like `render`. Fails with an\n * InvalidConfigurationError when the request has no AHD or a grid key is out of range.\n */\n computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet>;\n}\n/**\n * 2.7 (#387): resolves a {@link simulateDisplayView} request once, without a view, and returns a handle whose `render(view)`\n * renders its views. The setup it does once (request validation, the camera, lens, scene, chart and illuminant, the channel\n * responses through the environment chain, the diffraction kernels, readout moments, demosaic tables and colour matrix) costs\n * about 0.3–1.3 s per call on a 24 MP request; a region costs only its own pixels. Errors in the request are raised here;\n * errors in the view by `render`.\n *\n * 2.11 (#481): `prepareOptions.gpu` chooses the renderer: `\"off\"` (default) is the CPU reference, today's bytes; `\"auto\"` renders\n * on WebGPU when a conforming device is available and the request is supported, else on the CPU, labelled; `\"require\"` fails\n * instead of falling back (`ImageKernelExecutionError`, acquisition failures here, later ones from `render`). `gpuDevice` is a\n * WebGPU entry point or an `ImageKernelAccelerator` whose device the view shares; without it the engine acquires one device\n * for the prepared view (the request's `signal` aborts the acquisition) and `dispose()` releases it. The realm's\n * `setWebGpuEnabled(false)` vetoes both GPU modes (`webgpu-disabled`). See docs/DISPLAY_VIEW.md, \"Rendering on the GPU\".\n * @see docs/QUICK_START.md, \"Display view\".\n */\nexport async function prepareDisplayView(options: SimulateCaptureOptions, prepareOptions?: PrepareDisplayViewOptions): Promise<PreparedDisplayView> {\n const gpuOptions = parsePrepareDisplayViewOptions(prepareOptions);\n let frameWidth = 0, frameHeight = 0;\n const prepared = await runCapture(options, \"display-view\", DISPLAY_VIEW_WITHOUT_VIEW, (context) => {\n frameWidth = context.width; frameHeight = context.height;\n return Promise.resolve(prepareView(context));\n }) as PreparedViewParts;\n // The GPU code is loaded only when a GPU mode asks for it, so bundles on the default stay without it.\n const session: DisplayViewGpuSession | null = gpuOptions.gpu === \"off\" ? null :\n await (await import(\"./display-view-gpu-session.js\")).openDisplayViewGpuSession(gpuOptions, prepared.gpuRequest, (options as { signal?: AbortSignal }).signal);\n /** One call's start times, cancellation (its own signal) and yielding. */\n const runOf = (renderOptions: PreparedDisplayViewRenderOptions | undefined): ViewRun => {\n const started = Date.now(), viewStarted = clockMs();\n const signal = renderOptions === undefined ? undefined : allowKeys(renderOptions, \"render options\", [\"signal\"]).signal as AbortSignal | undefined;\n if (signal !== undefined && (typeof signal !== \"object\" || signal === null || typeof signal.aborted !== \"boolean\")) fail(\"signal must be an AbortSignal.\");\n const checkAbort = (): void => { if (signal?.aborted) fail(\"simulateCapture aborted.\"); };\n checkAbort();\n return { started, viewStarted, checkAbort, yieldControl: createHostYield().yieldControl, signal };\n };\n const correctionOf = (caller: string): DisplayViewCorrectionSetup => prepared.correction ??\n fail(caller + \": the prepared request has no AHD low-signal correction (it applies with output.demosaic \\\"ahd\\\").\");\n const handle: PreparedDisplayView = Object.freeze({\n async render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult> {\n const run = runOf(renderOptions);\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return await prepared.render(parsed, run, undefined, session);\n },\n dispose(): void { session?.dispose(); },\n correctionKey(): string | null { return prepared.correction ? displayViewCorrectionKey(prepared.correction) : null; },\n async collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys> {\n const run = runOf(renderOptions), correction = correctionOf(\"collectCorrectionStates\");\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return { key: displayViewCorrectionKey(correction)!, gridKeys: await prepared.collect(parsed, run) };\n },\n async computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet> {\n const run = runOf(renderOptions), correction = correctionOf(\"computeCorrectionStates\");\n return await computeDisplayViewCorrectionStates({ ...correction, yieldControl: run.yieldControl, checkAbort: run.checkAbort }, gridKeys);\n }\n });\n PREPARED_INTERNALS.set(handle, async (view, renderOptions) => {\n const internals: ViewInternals = {};\n const result = await prepared.render(parseDisplayViewOption(view, frameWidth, frameHeight), runOf(renderOptions), internals, session);\n return { result, internals: internals.value! };\n });\n return handle;\n}\n/** The internal render of each prepared view (the same render as `render`, keeping its renderer's result). */\nconst PREPARED_INTERNALS = new WeakMap<PreparedDisplayView, (view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions) =>\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult }>>();\n/**\n * Internal (not exported from the package): renders a view of a prepared view as `render` does (the same GPU session and labels)\n * and also returns the renderer's noise-free expected linear values and noise standard deviations, whichever renderer ran (#480's\n * GPU producer, `scripts/lib/display-view-gpu-page.mjs`).\n */\nexport async function renderPreparedDisplayViewWithInternals(prepared: PreparedDisplayView, view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions):\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult }> {\n const render = PREPARED_INTERNALS.get(prepared);\n if (!render) fail(\"renderPreparedDisplayViewWithInternals needs a view returned by prepareDisplayView.\");\n return await render(view, renderOptions);\n}\n/**\n * Internal (not exported from the package): the display view plus its noise-free expected linear values and noise standard\n * deviations, for the validation scripts and tests.\n */\nexport async function simulateDisplayViewWithInternals(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions):\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult; signal: DisplayViewExpectedSignal; setup: DisplayViewSetup; signalInput: DisplayViewExpectedSignalInput }> {\n const internals: ViewInternals = {};\n const result = await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context, internals)) as DisplayViewResult;\n return { result, internals: internals.value!, signal: internals.signal!, setup: internals.setup!, signalInput: internals.signalInput! };\n}\n\n/** AHD low-signal correction (display view): draws per flat-neighbourhood state, and the pixel noise (linear light) above which it applies. */\nconst DISPLAY_VIEW_AHD_CORRECTION_DRAWS = 2048, DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD = 0.01;\n\ntype ViewInternals = { value?: DisplayViewRenderResult; signal?: DisplayViewExpectedSignal;\n /** #478: the render's setup and the expected signal's input, for the GPU display view's tests. */\n setup?: DisplayViewSetup; signalInput?: DisplayViewExpectedSignalInput };\n/** What one render of a prepared view needs from its call: its start times, cancellation and yielding. */\ninterface ViewRun { started: number; viewStarted: number; checkAbort: () => void; yieldControl: () => Promise<void>; signal?: AbortSignal | undefined }\ntype RenderPreparedView = (view: ParsedDisplayView, run: ViewRun, viewInternals?: ViewInternals, gpu?: DisplayViewGpuSession | null) => Promise<DisplayViewResult>;\n/**\n * A prepared request: its render, its collect pass (#447: the grid keys of the correction states a view's region reads) and\n * the inputs of its correction states (undefined without AHD).\n */\ninterface PreparedViewParts {\n render: RenderPreparedView;\n collect(view: ParsedDisplayView, run: ViewRun): Promise<Int32Array>;\n correction: DisplayViewCorrectionSetup | undefined;\n /** #481: what a GPU renderer is asked to support. */\n gpuRequest: DisplayViewGpuRequest;\n}\n\n/** Renders the display view of a resolved request (the last step of `runCapture` for \"display-view\"). */\nasync function renderDisplayViewResult(context: DisplayViewRunContext, viewInternals?: ViewInternals): Promise<DisplayViewResult> {\n const viewStarted = clockMs();\n return await prepareView(context).render(context.parsedView!, { started: context.started, viewStarted, checkAbort: context.checkAbort, yieldControl: context.yieldControl }, viewInternals);\n}\n\n/**\n * Internal (#387): the part of a display view that depends only on the request, done once (the portable illuminant, chart and\n * white balance, the channel responses, query offsets, diffraction kernels, readout moments, demosaic tables and colour\n * matrix). The returned function renders one view from it; it keeps no state between renders (each has its own expected-\n * signal caches, lookup count and assumptions), so its results are those of separate calls.\n */\nfunction prepareView(context: DisplayViewRunContext): PreparedViewParts {\n const { ahd, antiAliasing, aspect, axisChannelResponse, boxSamples, buildProvider, callerScene, chart, materialLayers, chartReport, chartSize, diffraction, diffractionPsf, fNumber, focalLengthMm, focusDistanceM, height, highlightMode, exposureGain, illuminanceLux, illuminant, illuminantOption, imagingArea, intentOf, metresPerFrameUnit, noiseSeed, outputOptions, pitch, preset, provider, regimeByChannel, resolvedIso, isoReport, standardExposureDeviationStops, standardExposureIlluminanceLux, greyCardDeviationStops, metering, sceneOption, scenePreset, shutterSeconds, subjectDistanceM, toneCurve, whiteBalanceOption, whiteBalanceState, width, margin, mode, nativeHeight, nativeWidth, sourceSha256 } = context;\n const kelvinInput = context.kelvinWhiteBalanceInput;\n // The engine's illuminant formulas (Planckian, CIE A, daylight locus) evaluated with the portable power and e^x − 1, so\n // the view's radiances, irradiance scale and scene-illuminant white balance have the same bits in every JavaScript\n // engine; they differ from the capture's own by at most a few ulps (docs/DISPLAY_VIEW.md, \"Same bytes in every engine\").\n const viewIlluminant = resolvePortableCaptureIlluminant(illuminantOption), viewIrradianceScale = calculateIlluminantIrradianceScale(viewIlluminant.shape, illuminanceLux);\n const viewProvider = buildProvider(viewIlluminant, viewIrradianceScale);\n const viewWhiteBalanceState = whiteBalanceOption === \"scene-illuminant\" ? sceneIlluminantWhiteBalance(viewIlluminant) : kelvinInput ? resolvePortableColorTemperatureWhiteBalance(kelvinInput) : whiteBalanceState;\n // The chart's materials likewise (a step wedge's geometric levels use the portable power); same geometry and order.\n const viewChart = chart ? resolvePortableChartScene({ scene: sceneOption as ChartScene, aspect: chartSize ? chartSize.heightM / chartSize.widthM : aspect }) : undefined;\n if (chart && viewChart!.materials.length !== chart.materials.length) fail(\"simulateDisplayView: the chart's materials could not be resolved portably.\");\n const { electronsPerRadiance, wavelengths, relativePerElectron } = axisChannelResponse(\"simulateDisplayView\");\n const perNode = CHANNELS.map((c) => Float64Array.from(wavelengths, (nm) => electronsPerRadiance[c].get(nm) ?? 0)) as [Float64Array, Float64Array, Float64Array];\n // The tabulated expected signal's input (#394: shared with the capture's tabulated RAW path).\n const sceneMaterials = viewChart ? viewChart.materials : callerScene?.kind === \"material-function\" ? callerScene.materials : undefined;\n // Defocus (#492): the geometric disc on the site lattice, combined with the diffraction kernels in the tables (expected-signal-setup.ts).\n // #553: with bokeh options (blades, spherical aberration) the capture built the shaped kernel; it replaces the disc.\n const defocusDisc = context.defocus, defocusKernel = defocusDisc && defocusDisc.diameterSites > 0 ? defocusDisc.siteKernel ?? createDefocusDiscSiteKernel(defocusDisc.diameterSites) : null;\n const shaped = defocusDisc?.siteKernel !== undefined;\n // The combined radius is at most 32 + 512 sites (the diffraction and disc caps), as in the capture. #564: above 64 sites the kernel is\n // convolved by runs after the in-focus signal (expected-signal.ts), the same sums regrouped.\n const diffractionRadius = diffraction ? diffraction.kernelRadiusSamples : 0, combinedRadius = defocusKernel ? diffractionRadius + defocusKernel.radius : diffractionRadius;\n const { offsets, signalInput } = buildExpectedSignalInput({ nativeWidth, nativeHeight, width, wavelengths, perNode, apertureNodes: apertureNodeOffsets(boxSamples), boxSamples,\n antiAliasing, pitch, defocus: defocusKernel, ...(context.lensPsf ? { lensKernels: context.lensPsf.axisKernels(wavelengths) } : {}), diffraction: diffraction ? { radius: diffraction.kernelRadiusSamples, psf: diffractionPsf!.configuration.psf, profileWavelengths: diffraction.profile.axes.wavelengthNm } : undefined,\n materials: sceneMaterials && provider.chartMaterialAt ? { materialAt: provider.chartMaterialAt,\n list: [...sceneMaterials.map((m, index) => (m.kind === \"neutral\" ? { neutral: m.reflectance } : { radiance: (nm: number): number => viewProvider.materialRadiance!(index, nm) })),\n ...(chartSize ? [{ neutral: chartSize.surroundReflectance }] : [])],\n whiteRadiance: (nm: number): number => viewIrradianceScale * viewIlluminant.shape.evaluate(nm) / Math.PI } : undefined,\n radianceAt: viewProvider.radianceAt, imagingArea, focalLengthMm, focusDistanceM, subjectDistanceM, metresPerFrameUnit, caller: \"simulateDisplayView\" });\n const kernels = signalInput.kernels, largeDefocus = signalInput.largeKernel;\n // Readout moments per channel: normalized value k·e with variance k²·(e + σ_read²) plus the ADC quantization (1/12 code², times d² before a digital gain d).\n // #556: a development exposure push G multiplies the normalized value before the per-site clip at white: k → G·k and the constant variance → G²·(…).\n // Without a push G = 1, and x·1 = x exactly in IEEE 754 arithmetic, so the moments are bit-identical to those without the push.\n const readout = CHANNELS.map((channel): DisplayViewChannelReadout => {\n const { readoutProfile, regimeId } = regimeByChannel[channel];\n const resolved = resolveSensorReadoutRegime({ profile: readoutProfile as Parameters<typeof resolveSensorReadoutRegime>[0][\"profile\"], regimeId });\n const k = relativePerElectron[channel], digitalGain = resolved.regime.adc.digitalGain ?? 1, gain = resolved.regime.systemConversionGainElectronsPerCode.value;\n const codeSpan = digitalGain / (gain * k), read = resolved.combinedReadNoiseRmsElectrons;\n const quantizationCodes = digitalGain * digitalGain / 12 + (digitalGain === 1 ? 0 : 1 / 12);\n return { perElectron: exposureGain * k, darkElectrons: DARK_CURRENT_ELECTRONS_PER_SECOND * shutterSeconds,\n constantVariance: exposureGain * exposureGain * (k * k * read * read + quantizationCodes / (codeSpan * codeSpan)) };\n }) as [DisplayViewChannelReadout, DisplayViewChannelReadout, DisplayViewChannelReadout];\n const phases = bilinearPhaseProfiles(), demosaicTable: { dx: number; dy: number; weight: number }[][][] = [];\n for (const phase of phases) demosaicTable[phase.phaseY * 2 + phase.phaseX] = CHANNELS.map((c) => phase.profile.kernels.find((k) => k.outputChannelId === c)!.contributions\n .map((t) => ({ dx: t.offsetX, dy: t.offsetY, weight: t.weight })));\n const viewIntent = intentOf(viewWhiteBalanceState), viewGains = viewIntent ? [viewIntent.channelGains.red, viewIntent.channelGains.green, viewIntent.channelGains.blue] : null;\n const colour = prepareSensorColorDevelopment(CAMERA_TO_XYZ as unknown as Parameters<typeof prepareSensorColorDevelopment>[0], viewGains, highlightMode);\n const toSrgb = resolveCaptureColorModel().xyzToCameraRgb, m = colour.cameraToXyz;\n const matrix = [0, 1, 2].map((r) => [0, 1, 2].map((c) => toSrgb[r]![0]! * m[0]![c]! + toSrgb[r]![1]! * m[1]![c]! + toSrgb[r]![2]! * m[2]![c]!));\n // Reach of a footprint's pixels into the scene, in sites: the demosaic (1), the largest query offset and the kernel radius.\n const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0) + (largeDefocus ? largeDefocus.radius : 0);\n // The inputs of the AHD correction states (fixed here, so the correction key is too; #447).\n const gains = colour.appliedGains as [number, number, number], clipLevel = Math.min(...colour.appliedGains), viewToneCurve = toneCurve as \"identity\" | \"positive-reinhard-per-channel\";\n const ahdCorrection = ahd ? { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c]! : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,\n thresholdVariance: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD * DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : undefined;\n const ahdCandidates = ahd ? [0, 1, 2, 3].map((p) => ahdCandidateKernels(p % 2, Math.floor(p / 2))) : undefined;\n // #491: a fixed-size chart's placement for the GPU material lookup (the provider's chart-local units cu = u·m/h and the surround beyond the chart).\n const placement = chartSize ? { chartUnitsPerFrameUnit: metresPerFrameUnit / (chartSize.widthM / 2), aspect: chartSize.heightM / chartSize.widthM } : null;\n /** The renderer's setup of one view (with `ahdCollect`, a collect pass), and its expected signal. */\n const setupOf = (v: ParsedDisplayView, { checkAbort, yieldControl }: ViewRun, ahdCollect?: Set<number>): { setup: DisplayViewSetup; signal: DisplayViewExpectedSignal } => {\n const viewRegion = v.region ?? { x: 0, y: 0, width: v.width, height: v.height };\n // The native columns the region's windows span, beyond one window's width: a filled band need not be wider (a speed hint).\n // #563: through the lens (projection, distortion, vignetting, rotation) when the request has them.\n const signal = (context.lens ?? createDisplayViewExpectedSignal)(signalInput, Math.ceil((viewRegion.width + 2) * nativeWidth / v.width));\n return { signal, setup: { frameWidth: width, frameHeight: height, margin, nativeWidth, nativeHeight, viewWidth: v.width, viewHeight: v.height,\n region: viewRegion, samplesPerAxis: v.samplesPerAxis, reachSites, bitDepth: v.bitDepth, seed: noiseSeed, signal, readout, demosaic: demosaicTable,\n ...(ahdCandidates && ahdCorrection ? { candidates: ahdCandidates, ahdCorrection } : {}), ...(ahdCollect ? { ahdCollect } : {}),\n gains, clipLevel, matrix, toneCurve: viewToneCurve, yieldControl, checkAbort, gpu: { signalInput, chart: viewChart ?? null, layers: materialLayers ?? null, placement, ...(defocusKernel && !largeDefocus ? { defocusRadius: defocusKernel.radius } : {}) } } };\n };\n const correction: DisplayViewCorrectionSetup | undefined = ahdCorrection ? { seed: noiseSeed, readout, gains, clipLevel, matrix, toneCurve: viewToneCurve, ahdCorrection } : undefined;\n const collect = async (v: ParsedDisplayView, run: ViewRun): Promise<Int32Array> => {\n const keys = new Set<number>();\n await renderDisplayView(setupOf(v, run, keys).setup);\n return Int32Array.from(keys).sort();\n };\n // #492: out of focus the view reads the defocus disc (its kernel in signalInput.kernels); the GPU Quality site pass gathers it (step 2c).\n const gpuRequest: DisplayViewGpuRequest = { ahd, lens: !!context.lens, defocus: defocusKernel !== null, ...(largeDefocus ? { largeDefocus: true } : {}), diffraction: diffraction !== undefined, antiAliasing: antiAliasing !== undefined, boxSamples, toneCurve: viewToneCurve,\n scene: chart ? \"chart\" : materialLayers ? \"material-layers\" : callerScene!.kind };\n const render: RenderPreparedView = async (v, run, viewInternals, gpu) => {\n const { started, viewStarted } = run;\n const assumptions: SimulateCaptureAssumption[] = [...context.assumptions];\n const assume = (id: string, kind: SimulateCaptureAssumption[\"kind\"], value: unknown, explanation: string): void => { assumptions.push({ id, kind, value, explanation }); };\n const { setup, signal } = setupOf(v, run), viewRegion = setup.region;\n // #481: the GPU session renders on the device when it can, else through the CPU reference, and labels which ran.\n const cpu = (): Promise<DisplayViewRenderResult> => renderDisplayView(setup);\n const { rendered, execution }: { rendered: DisplayViewRenderResult; execution: DisplayViewExecution } = gpu ? await gpu.render(setup, run.signal, cpu)\n : { rendered: await cpu(), execution: cpuDisplayViewExecution(\"off\", null, null, null) };\n if (viewInternals) { viewInternals.value = rendered; viewInternals.signal = signal; viewInternals.setup = setup; viewInternals.signalInput = signalInput; }\n const viewMs = clockMs() - viewStarted, scaleX = width / v.width, scaleY = height / v.height;\n assume(\"view.definition\", \"model\", { resampling: \"area-average-linear-light\", width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY },\n \"The image the full-resolution capture of this request would give after resizing to \" + v.width + \" × \" + v.height + \": each display pixel is the area-weighted mean, in linear light (sRGB samples decoded with the sRGB EOTF), \" +\n \"of the real output pixels its rectangle covers (\" + scaleX + \" × \" + scaleY + \" real pixels), then sRGB-encoded and rounded. The real capture's own samples are rounded to the view's bit depth before averaging.\");\n const uniformSamplesPerAxis = Math.max(1, Math.round(v.samplesPerAxis / 4));\n const siteSentence = \"the expected electrons of the real sites its demosaic reads are exact at the real pitch (the scene sampled at those sites through the pixel aperture, \" +\n \"anti-aliasing filter and diffraction kernels, with the capture's own query arithmetic, so the colour mosaic and its aliasing are the real sensor's), and the per-site clip at white, the highlight clip, the tone curve \" +\n \"and the clip to [0, 1] act on the pixel's own noise distribution, approximated as normal.\";\n // 2.8 (#393): where a footprint holds at most 25 real pixels (and at most K²), every real pixel of it is evaluated once with its exact weight.\n if (rendered.estimation === \"exact-area-mean\") {\n assume(\"view.estimation\", \"model\", { method: \"exact-area-mean-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, realPixelsPerDisplayPixel: scaleX * scaleY,\n evaluatedRealPixels: rendered.sampleCount },\n \"Each display pixel's expected value is the exact area mean of the real pixels its rectangle covers: every real pixel it touches is evaluated once and weighted by its overlap with the rectangle \" +\n \"(w_j / A, summing to 1), so there is no sampling error. This applies because each rectangle holds \" + scaleX * scaleY + \" real pixels (\" + scaleX + \" × \" + scaleY + \"), at most \" + EXACT_AREA_MEAN_MAX_PIXELS + \" and at most K² = \" + v.samplesPerAxis * v.samplesPerAxis + \"; coarser views use a stratified estimate, which costs less there. \" +\n \"For each real pixel \" + siteSentence);\n } else {\n assume(\"view.estimation\", \"model\", { method: \"stratified-monte-carlo-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, uniformSamplesPerAxis,\n detailPixels: rendered.detailPixelCount, uniformPixels: rendered.uniformPixelCount },\n \"Each display pixel's expected value is the mean over K × K strata of its rectangle, one seeded uniformly jittered real pixel in each, so it is unbiased; the error is zero where the rectangle is uniform \" +\n \"and falls as K^-3/2 at an edge. K = \" + v.samplesPerAxis + \" where a fixed pilot grid over the rectangle (widened by the demosaic, filter and kernel reach) or a neighbouring pixel's grid finds more than one scene value, \" +\n \"K = \" + uniformSamplesPerAxis + \" elsewhere. For each sampled pixel \" + siteSentence);\n }\n assume(\"view.noise\", \"model\", { method: \"variance-of-the-area-mean\", distribution: \"normal\" },\n \"Noise of the mean of the real pixels: the covariance of the weighted sum of independent site noises (shot, dark, read and ADC), with the demosaic correlation (B_c = Σ β², in closed form from the rectangle) and the \" +\n \"expected slopes of the clips and the tone curve (Stein's lemma); the variance the linearization misses and the real pixels' output rounding are added per pixel. One correlated normal draw per display pixel, seeded \" +\n \"by sensor.noiseSeed: the same statistics as the resized capture, not the same realization.\");\n assume(\"view.demosaic\", \"model\", ahd ? { capture: \"ahd\", view: \"ahd-candidates-with-low-signal-correction\", correctedPixels: rendered.ahdCorrectedPixelCount,\n correctionDrawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS, correctionThresholdLinearStd: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : { capture: \"bilinear\", view: \"bilinear\" },\n ahd ? \"AHD is non-linear only in its choice between two linear candidates (green along the rows or the columns, red and blue from colour differences). The view propagates both candidates' exact linear statistics \" +\n \"and averages them. Where a sampled pixel's noise exceeds \" + DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD + \" (linear light), the choice reacts to the noise and shifts the colour, so the pixel adds the mean \" +\n \"difference between the engine's AHD steps and the two candidates on \" + DISPLAY_VIEW_AHD_CORRECTION_DRAWS + \" drawn noisy flat neighbourhoods (Poisson electrons plus read and ADC noise) with its channel means, \" +\n \"computed once per state of a logarithmic grid (8 steps per octave of the channel means) and interpolated trilinearly, a control variate with no per-pixel sampling noise; \" +\n \"the flat-neighbourhood state is an approximation at edges (docs/DISPLAY_VIEW.md, validation).\" :\n \"The bilinear demosaic's linear kernels, exactly.\");\n if (defocusKernel) {\n assume(\"view.defocus\", \"model\", { kernel: shaped ? (diffraction ? \"diffraction-convolved-with-shaped-kernel\" : \"shaped-kernel\") : diffraction ? \"diffraction-convolved-with-disc\" : \"disc\", defocusKernelRadiusSites: defocusKernel.radius,\n diffractionKernelRadiusSites: diffraction ? diffractionRadius : null, kernelRadiusSites: combinedRadius, scientificStatus: \"approximation\", ...(largeDefocus ? { convolution: \"runs\" } : {}) },\n // #564: the lens.defocus assumption explains the run convolution above 64 sites (convolution: \"runs\").\n \"The expected electrons of each real site read the scene on the site lattice through the defocus \" + (shaped ? \"kernel shaped by the lens (#553; see the lens.defocus assumption; \" : \"disc (\") +\n defocusKernel.diameterSites + \" sites across, a \" + defocusKernel.width + \" × \" +\n defocusKernel.width + \" window), as the capture's convolution does; the estimators then run unchanged on the blurred signal. \" + (diffraction ?\n \"With lens.diffraction each spectral node's kernel is its diffraction kernel convolved with the disc (\" + (2 * combinedRadius + 1) + \" × \" + (2 * combinedRadius + 1) + \" taps): \" +\n \"an approximation, because the PSF of a defocused wave is not the in-focus Airy pattern convolved with a geometric disc.\" :\n \"The disc is the same at every spectral node (geometric optics).\"));\n }\n if (execution.backend === \"webgpu-f32\") {\n assume(\"view.execution\", \"model\", { backend: execution.backend, arithmetic: execution.arithmetic, errorBound: execution.errorBound, adapter: execution.adapter },\n \"Estimated on the GPU: this view was rendered by the WebGPU float32 display-view renderer, a labelled approximation of the float64 CPU reference within the a-priori \" +\n \"error bound reported in diagnostics.fast.execution.errorBound; it is not bit-identical to the reference. The device passed the engine's run-time conformance check first.\");\n }\n assume(\"view.source\", \"model\", { rendering: \"srgb\", format: v.format, ignoredCaptureOutput: [\"format\", \"colorEncoding\", \"bitDepth\", \"gamutMapping\", \"jpegQuantizationStep\", \"dng\", \"metadata\", \"maximumPixels\"].filter((k) => outputOptions[k] !== undefined) },\n \"The view shows the capture's sRGB rendering (its tone curve, white balance and highlight mode); the capture's file-format options do not apply to it.\");\n return Object.freeze({ kind: \"display-view\" as const, label: \"Display view: the full-resolution capture resized to \" + v.width + \" × \" + v.height + \" (estimated); not a capture.\",\n facadeVersion: SIMULATE_CAPTURE_FACADE_VERSION, engineApiVersion: ENGINE_API_VERSION,\n image: { width: viewRegion.width, height: viewRegion.height, format: v.format, samples: rendered.samples },\n view: { width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY, samplesPerAxis: v.samplesPerAxis, ...(v.region ? { region: { ...v.region } } : {}) },\n exposure: { mode, settings: { fNumber, shutterSeconds, iso: resolvedIso }, ev100: Math.log2(fNumber ** 2 / shutterSeconds), ...isoReport, standardExposureDeviationStops, standardExposureIlluminanceLux, greyCardDeviationStops, metering },\n scene: { sceneId: chart ? \"chart:\" + chart.preset : callerScene!.sceneId, preset: scenePreset, parameters: chart ? chart.parameters : {},\n illuminant: { id: illuminant.id, description: illuminant.description, illuminanceLux }, distanceM: subjectDistanceM,\n framedWidthM: 2 * metresPerFrameUnit, framedHeightM: 2 * metresPerFrameUnit * aspect, ...(chartReport ? { chart: chartReport } : {}), sourceSha256 },\n diagnostics: { sampleCount: rendered.sampleCount, siteEvaluations: rendered.siteCount, sceneLookups: signal.lookups, detailPixelCount: rendered.detailPixelCount,\n uniformPixelCount: rendered.uniformPixelCount, ahdCorrectedPixelCount: rendered.ahdCorrectedPixelCount, timingsMs: { view: viewMs, total: Date.now() - started },\n fast: Object.freeze({ ...context.fastReport, assurance: execution.backend === \"webgpu-f32\" ? \"approximation-with-a-priori-bound\" as const : context.fastReport.assurance, execution }),\n highlight: Object.freeze({ saturatedPixelCount: rendered.saturatedPixelCount, statistic: \"expected-value\" as const }) },\n provenance: { scientificStatus: \"approximation\" as const, cameraPresetId: preset.presetId, cameraPresetVersion: preset.presetVersion, evidence: [...FACADE_EVIDENCE, ...preset.evidence],\n composedContracts: [\"calculateEnvironmentSensorPhotoSignal\", \"resolveSensorReadoutRegime\", \"calculateSiteEffectiveSaturationCode\", ...(diffraction ? [\"createDiffractionLimitedPsfProfile\", \"resolveLensPsfConvolutionKernels\"] : []),\n ...(antiAliasing ? [\"resolveAntiAliasingSpatialKernel\"] : []), \"prepareSensorColorDevelopment\", \"display view estimator\"],\n limitations: [\"Estimated display view of the full-resolution capture: its expected value is a stratified Monte Carlo estimate and its noise is drawn from the variance of the area mean, so it has the resized capture's statistics, not its exact pixels; not a capture and not a measurement.\"] },\n assumptions: Object.freeze(assumptions.map((a) => Object.freeze(a))) });\n };\n return { render, collect, correction, gpuRequest };\n}\n"]}
|
|
@@ -168,15 +168,6 @@ export declare function displayViewQualityGpuSupports(request: DisplayViewGpuReq
|
|
|
168
168
|
export declare const DISPLAY_VIEW_QUALITY_CONFORMANCE_CASE: DisplayViewGpuConformanceCase;
|
|
169
169
|
/** #492's self-check of the defocus disc's blocked site sum (see `runQualityConformance`). */
|
|
170
170
|
export declare const DISPLAY_VIEW_QUALITY_DEFOCUS_CONFORMANCE_CASE: DisplayViewGpuConformanceCase;
|
|
171
|
-
/**
|
|
172
|
-
* The display view's GPU renderer on one runtime (#481's `DisplayViewGpuRenderer`): the Speed kernel for requests it covers
|
|
173
|
-
* (no diffraction, no AHD, no defocus disc, at most 16 offsets) and the Quality kernels for the rest (#492: a defocused Speed
|
|
174
|
-
* request too, with its bilinear demosaic). One pipeline cache per device, one set of
|
|
175
|
-
* material modules (#491: chart presets, composite charts, the 2.3 elements and material-layers scenes; `dispose` releases their
|
|
176
|
-
* uploaded scene records), one correction-state store per correction key. `render` renders the part's region (`setup.gpu`
|
|
177
|
-
* carries the expected signal's input and the chart; a setup without it, a coarse view or a frame the kernels do not cover
|
|
178
|
-
* throws `unsupported-on-backend`), and throws `aborted` and `device-lost` as the accelerator's operations do.
|
|
179
|
-
*/
|
|
180
171
|
export declare function createDisplayViewGpuRenderer(runtime: WebGpuRuntime, options?: {
|
|
181
172
|
maximumBandBytes?: number;
|
|
182
173
|
yieldControl?: YieldControl;
|
|
@@ -156,6 +156,8 @@ function exactLatticeConstant(c, span) {
|
|
|
156
156
|
* 2·reach + 2 sites on each axis (so a reflected border site lies in the band's window).
|
|
157
157
|
*/
|
|
158
158
|
export function displayViewQualityGpuUnsupportedReason(setup, signalInput) {
|
|
159
|
+
if (signalInput.largeKernel)
|
|
160
|
+
return LARGE_DEFOCUS_REASON;
|
|
159
161
|
if (signalInput.scene.kind !== "materials")
|
|
160
162
|
return "radiance scenes (caller functions) are not on the GPU";
|
|
161
163
|
if (!signalInput.kernels && !signalInput.queryPoint)
|
|
@@ -979,6 +981,8 @@ function bilinearKernels() {
|
|
|
979
981
|
* carries the expected signal's input and the chart; a setup without it, a coarse view or a frame the kernels do not cover
|
|
980
982
|
* throws `unsupported-on-backend`), and throws `aborted` and `device-lost` as the accelerator's operations do.
|
|
981
983
|
*/
|
|
984
|
+
/** #564: the GPU refusal of a defocus kernel above the direct radius (the CPU convolves it by runs). */
|
|
985
|
+
const LARGE_DEFOCUS_REASON = "a defocus kernel radius above 64 sites (convolved by runs on the CPU, #564) is not on the GPU";
|
|
982
986
|
export function createDisplayViewGpuRenderer(runtime, options = {}) {
|
|
983
987
|
const pipelines = new Map(), stores = new Map();
|
|
984
988
|
const bandBytes = options.maximumBandBytes ?? Math.min(64 * 1024 * 1024, runtime.maximumStorageBindingBytes);
|
|
@@ -997,6 +1001,8 @@ export function createDisplayViewGpuRenderer(runtime, options = {}) {
|
|
|
997
1001
|
return {
|
|
998
1002
|
id: "photivra-display-view",
|
|
999
1003
|
supports(request) {
|
|
1004
|
+
if (request.largeDefocus)
|
|
1005
|
+
return LARGE_DEFOCUS_REASON;
|
|
1000
1006
|
// #492: out of focus the expected signal carries the defocus disc as site kernels, which only the Quality site pass gathers;
|
|
1001
1007
|
// a Speed request then runs the Quality passes with its own bilinear demosaic (one candidate) and finishing.
|
|
1002
1008
|
if (request.defocus)
|