@photivra/engine 1.0.0 → 1.1.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/AGENTS.md +3 -3
- package/CHANGELOG.md +12 -0
- package/CITATION.cff +1 -1
- package/CONTRIBUTING.md +3 -3
- package/NODE_SUPPORT.md +9 -9
- package/README.md +9 -7
- package/SECURITY.md +1 -1
- package/dist/core/version.d.ts +6 -11
- package/dist/core/version.d.ts.map +1 -1
- package/dist/core/version.js +6 -11
- package/dist/core/version.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/output/print-detail.d.ts +106 -0
- package/dist/output/print-detail.d.ts.map +1 -0
- package/dist/output/print-detail.js +215 -0
- package/dist/output/print-detail.js.map +1 -0
- package/dist/output/print-plan.d.ts +138 -0
- package/dist/output/print-plan.d.ts.map +1 -0
- package/dist/output/print-plan.js +305 -0
- package/dist/output/print-plan.js.map +1 -0
- package/docs/API_REFERENCE.md +38 -1
- package/docs/API_STYLE.md +11 -7
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/AUTOMATION_COORDINATION.md +1 -1
- package/docs/CAPTURE_COLOR.md +1 -1
- package/docs/CAPTURE_CORRECTED_SDR.md +1 -1
- package/docs/CAPTURE_EXPORT_METADATA.md +1 -1
- package/docs/CAPTURE_SDR.md +1 -1
- package/docs/DEVELOPERS.md +12 -6
- package/docs/DIGITAL_OPTICS_FOUNDATION.md +1 -1
- package/docs/ENVIRONMENT_RAW_CAPTURE.md +1 -1
- package/docs/EXPORT_ACCEPTANCE.md +1 -1
- package/docs/GENERIC_TIER_PRESETS.md +2 -2
- package/docs/GEOMETRIC_PREPARATION_REUSE.md +1 -1
- package/docs/IMAGE_FORMATION.md +1 -1
- package/docs/LINEAR_CAPTURE_ENCODING.md +1 -1
- package/docs/MOTION_AND_SIGNAL.md +1 -1
- package/docs/NUMERICAL_CORRECTNESS.md +1 -1
- package/docs/PERFORMANCE_BASELINE.md +1 -1
- package/docs/PHOTOGRAPHIC_EXPORT.md +1 -1
- package/docs/PHYSICS_FOUNDATION.md +1 -1
- package/docs/POC_API.md +1 -1
- package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +12 -0
- package/docs/POC_PROJECTION_REUSE.md +1 -1
- package/docs/PRINT_DETAIL_ASSESSMENT.md +81 -0
- package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +29 -0
- package/docs/PRINT_DETAIL_VALIDATION.md +36 -0
- package/docs/PRINT_PLANNING.md +73 -0
- package/docs/PROCESSED_OUTPUT.md +1 -1
- package/docs/PRODUCTION_COMPOSITION.md +1 -1
- package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +3 -3
- package/docs/PROVENANCE.md +1 -1
- package/docs/PSF_FOUNDATION.md +1 -1
- package/docs/RAW_FRAME_ENVELOPE.md +1 -1
- package/docs/RAW_FRAME_RECONSTRUCTION.md +2 -2
- package/docs/RELEASE_1_0.md +1 -0
- package/docs/RELEASE_1_0_1.md +61 -0
- package/docs/RELEASE_1_1_0.md +25 -0
- package/docs/RELEASE_AUDIT.md +1 -0
- package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +1 -1
- package/docs/SCENE_SENSOR_QUADRATURE.md +1 -1
- package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +1 -1
- package/docs/SCIENTIFIC_ASSURANCE.md +1 -1
- package/docs/SCIENTIFIC_CONFORMANCE.md +1 -1
- package/docs/SDR_RENDERING.md +2 -2
- package/docs/SENSOR_ENVIRONMENT_QUERY.md +1 -1
- package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +1 -1
- package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +1 -1
- package/docs/SENSOR_PSF_QUADRATURE.md +1 -1
- package/docs/SENSOR_RAW_FRAME.md +2 -2
- package/docs/SENSOR_RAW_PRODUCER.md +1 -1
- package/docs/SIGNAL_CONFORMANCE.md +1 -1
- package/docs/SIMULATED_CAPTURE.md +1 -1
- package/docs/STABILIZATION.md +1 -1
- package/docs/TEMPORAL_PHOTO_RAW.md +1 -1
- package/docs/TIER_ACCEPTANCE.md +1 -1
- package/docs/TIER_PRESET_ACCEPTANCE.md +2 -2
- package/docs/USAGE.md +7 -1
- package/docs/V1_COMPOSITION_MAP.md +2 -2
- package/docs/V1_HELPER_REUSE_REVIEW.md +1 -1
- package/docs/V1_PERFORMANCE_DISPOSITION.md +1 -1
- package/docs/api/camera-equivalent-focal-length.md +1 -1
- package/docs/api/camera-field-of-view.md +1 -1
- package/docs/api/camera-projected-object-size.md +1 -1
- package/docs/api/capture-capture-export-metadata.md +1 -1
- package/docs/api/capture-environment-raw-producer.md +1 -1
- package/docs/api/capture-focus-control.md +1 -1
- package/docs/api/capture-linear-encoding.md +1 -1
- package/docs/api/capture-photographic-export.md +1 -1
- package/docs/api/capture-raw-frame-reconstruction.md +1 -1
- package/docs/api/capture-release-sequence.md +1 -1
- package/docs/api/capture-sensor-raw-frame.md +1 -1
- package/docs/api/capture-sensor-raw-producer.md +1 -1
- package/docs/api/capture-simulated-capture.md +1 -1
- package/docs/api/color-capture-color.md +1 -1
- package/docs/api/color-white-balance.md +1 -1
- package/docs/api/composition-image-formation-plan.md +1 -1
- package/docs/api/composition-plan-consumer.md +1 -1
- package/docs/api/core-calculation-result.md +1 -1
- package/docs/api/core-configuration-error.md +1 -1
- package/docs/api/core-image-formation.md +1 -1
- package/docs/api/core-scientific-assurance.md +1 -1
- package/docs/api/core-spectral-composition.md +1 -1
- package/docs/api/core-spectral.md +1 -1
- package/docs/api/core-validation.md +1 -1
- package/docs/api/core-version.md +6 -6
- package/docs/api/equipment-exposure-capabilities.md +1 -1
- package/docs/api/equipment-generic-tier-assets.md +1 -1
- package/docs/api/equipment-generic-tier-presets.md +1 -1
- package/docs/api/equipment-iso-capabilities.md +1 -1
- package/docs/api/equipment-metering-capabilities.md +1 -1
- package/docs/api/equipment-release-capabilities.md +1 -1
- package/docs/api/exports.json +117 -2
- package/docs/api/exposure-exposure-duration-control.md +1 -1
- package/docs/api/exposure-exposure-mode-resolver.md +1 -1
- package/docs/api/exposure-exposure.md +1 -1
- package/docs/api/exposure-flash.md +1 -1
- package/docs/api/exposure-metering-scene-radiance.md +1 -1
- package/docs/api/exposure-metering-target.md +1 -1
- package/docs/api/exposure-metering-temporal.md +1 -1
- package/docs/api/exposure-metering.md +1 -1
- package/docs/api/exposure-program-line.md +1 -1
- package/docs/api/motion-camera-rotation.md +1 -1
- package/docs/api/motion-capture-rotation-inverse-mapping.md +1 -1
- package/docs/api/motion-capture-rotation-temporal-quadrature.md +1 -1
- package/docs/api/motion-capture-rotation-trajectory.md +1 -1
- package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +1 -1
- package/docs/api/motion-extended-object-projection.md +1 -1
- package/docs/api/motion-projected-motion.md +1 -1
- package/docs/api/optics-aperture.md +1 -1
- package/docs/api/optics-circle-of-confusion.md +1 -1
- package/docs/api/optics-complex-pupil-psf.md +1 -1
- package/docs/api/optics-depth-of-field.md +1 -1
- package/docs/api/optics-diffraction.md +1 -1
- package/docs/api/optics-focus-breathing.md +1 -1
- package/docs/api/optics-focus-state.md +1 -1
- package/docs/api/optics-front-of-lens-filter.md +1 -1
- package/docs/api/optics-illumination-vignetting.md +1 -1
- package/docs/api/optics-lateral-chromatic-aberration.md +1 -1
- package/docs/api/optics-lens-psf-profile.md +1 -1
- package/docs/api/optics-polygon-diffraction.md +1 -1
- package/docs/api/optics-profile-contract.md +1 -1
- package/docs/api/optics-psf-foundation.md +1 -1
- package/docs/api/optics-radial-distortion.md +1 -1
- package/docs/api/optics-scene-to-sensor-irradiance.md +1 -1
- package/docs/api/optics-scene-to-sensor-quadrature.md +1 -1
- package/docs/api/optics-sensor-environment-query.md +1 -1
- package/docs/api/optics-sensor-psf-quadrature.md +1 -1
- package/docs/api/optics-stray-light.md +1 -1
- package/docs/api/optics-thin-lens.md +1 -1
- package/docs/api/output-capture-corrected-sdr.md +1 -1
- package/docs/api/output-capture-geometry.md +1 -1
- package/docs/api/output-capture-sdr.md +1 -1
- package/docs/api/output-crop.md +1 -1
- package/docs/api/output-geometric-transforms.md +1 -1
- package/docs/api/output-lens-corrections.md +1 -1
- package/docs/api/output-print-detail.md +147 -0
- package/docs/api/output-print-plan.md +165 -0
- package/docs/api/output-sdr-rendering.md +1 -1
- package/docs/api/output-subject-framing-crop.md +1 -1
- package/docs/api/schema-camera.md +1 -1
- package/docs/api/schema-illumination-spectral.md +1 -1
- package/docs/api/schema-illumination-temporal.md +1 -1
- package/docs/api/schema-illumination.md +1 -1
- package/docs/api/schema-scene-radiance-temporal.md +1 -1
- package/docs/api/schema-scene-radiance.md +1 -1
- package/docs/api/schema-scene.md +1 -1
- package/docs/api/schema-validation.md +1 -1
- package/docs/api/sensor-accumulated-charge.md +1 -1
- package/docs/api/sensor-architecture.md +1 -1
- package/docs/api/sensor-camera-saturation-capacity.md +1 -1
- package/docs/api/sensor-capture-color-sampling-binding.md +1 -1
- package/docs/api/sensor-capture-mode-timing.md +1 -1
- package/docs/api/sensor-capture-mode.md +1 -1
- package/docs/api/sensor-color-sampling.md +1 -1
- package/docs/api/sensor-constant-rate-temporal-integration.md +1 -1
- package/docs/api/sensor-dark-current.md +1 -1
- package/docs/api/sensor-environment-photo-signal.md +1 -1
- package/docs/api/sensor-eqe-electron-rate.md +1 -1
- package/docs/api/sensor-eqe-local-exposure.md +1 -1
- package/docs/api/sensor-eqe-temporal-exposure.md +1 -1
- package/docs/api/sensor-exposure-window.md +1 -1
- package/docs/api/sensor-iso-signal-chain.md +1 -1
- package/docs/api/sensor-local-exposure-binding.md +1 -1
- package/docs/api/sensor-optical-stack.md +1 -1
- package/docs/api/sensor-photon-energy.md +1 -1
- package/docs/api/sensor-physical-charge-capacity.md +1 -1
- package/docs/api/sensor-pixel-pitch.md +1 -1
- package/docs/api/sensor-radiometry-readiness.md +1 -1
- package/docs/api/sensor-raw-readout.md +1 -1
- package/docs/api/sensor-raw-reconstruction.md +1 -1
- package/docs/api/sensor-readout-exposure-linkage.md +1 -1
- package/docs/api/sensor-readout-timing.md +1 -1
- package/docs/api/sensor-response-application-compatibility.md +1 -1
- package/docs/api/sensor-response-operating-range.md +1 -1
- package/docs/api/sensor-responsivity-photocurrent.md +1 -1
- package/docs/api/sensor-sampling-aperture.md +1 -1
- package/docs/api/sensor-scene-eqe-temporal-exposure.md +1 -1
- package/docs/api/sensor-sensor-geometry.md +1 -1
- package/docs/api/sensor-signal-noise.md +1 -1
- package/docs/api/sensor-spatial-sample-reduction.md +1 -1
- package/docs/api/sensor-spatial-sampling-quadrature.md +1 -1
- package/docs/api/sensor-spatio-spectral-reduction.md +1 -1
- package/docs/api/sensor-spectral-coverage.md +1 -1
- package/docs/api/sensor-spectral-quadrature.md +1 -1
- package/docs/api/sensor-spectral-response.md +1 -1
- package/docs/api/sensor-temporal-photo-signal.md +1 -1
- package/docs/api/simulation-poc-simulation.md +1 -1
- package/docs/api/stabilization-camera-shake.md +1 -1
- package/docs/api/stabilization-system.md +1 -1
- package/docs/examples/quick-start.mjs +1 -1
- package/docs/validation/print-detail-capabilities.json +100 -0
- package/docs/validation/print-detail-sdr-evidence.json +81 -0
- package/package.json +1 -1
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/** Native-only print geometry. No image generation or perceived-quality certification.
|
|
3
|
+
* @see docs/PRINT_PLANNING.md for equations, rounding and support limits.
|
|
4
|
+
*/
|
|
5
|
+
import { calculatedResult, approximationResult } from "../core/calculation-result.js";
|
|
6
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
7
|
+
import { requireAllowlistedRecord, requirePublicOpaqueId } from "../core/record-validation.js";
|
|
8
|
+
import { requirePositiveFinite, requirePositiveInteger } from "../core/validation.js";
|
|
9
|
+
import { ENGINE_API_VERSION } from "../core/version.js";
|
|
10
|
+
import { resolveCaptureGeometry } from "./capture-geometry.js";
|
|
11
|
+
const UNIT_MM = { mm: 1, cm: 10, inches: 25.4, m: 1000 };
|
|
12
|
+
const RAD_PER_ARCMIN = Math.PI / 10800;
|
|
13
|
+
function record(value, keys) {
|
|
14
|
+
return requireAllowlistedRecord(value, keys, "Invalid or unknown Print planning fields.");
|
|
15
|
+
}
|
|
16
|
+
function number(value, name) {
|
|
17
|
+
if (typeof value !== "number")
|
|
18
|
+
throw new InvalidConfigurationError(`${name} must be numeric.`);
|
|
19
|
+
requirePositiveFinite(name, value);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function unit(value) {
|
|
23
|
+
if (typeof value !== "string" || !Object.hasOwn(UNIT_MM, value))
|
|
24
|
+
throw new InvalidConfigurationError("Invalid Print length unit.");
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function length(value) {
|
|
28
|
+
const r = record(value, ["value", "unit"]);
|
|
29
|
+
return { value: number(r.value, "length.value"), unit: unit(r.unit) };
|
|
30
|
+
}
|
|
31
|
+
function raster(value) {
|
|
32
|
+
const r = record(value, ["pixelWidth", "pixelHeight"]);
|
|
33
|
+
const pixelWidth = number(r.pixelWidth, "pixelWidth"), pixelHeight = number(r.pixelHeight, "pixelHeight");
|
|
34
|
+
requirePositiveInteger("pixelWidth", pixelWidth);
|
|
35
|
+
requirePositiveInteger("pixelHeight", pixelHeight);
|
|
36
|
+
return { pixelWidth, pixelHeight };
|
|
37
|
+
}
|
|
38
|
+
function geometry(value) {
|
|
39
|
+
const g = record(value, ["imagingArea", "nativeRaster", "orientation", "activeCaptureRect", "outputCropRect", "outputRaster"]);
|
|
40
|
+
record(g.imagingArea, ["widthMm", "heightMm"]);
|
|
41
|
+
raster(g.nativeRaster);
|
|
42
|
+
for (const key of ["activeCaptureRect", "outputCropRect"]) {
|
|
43
|
+
if (g[key] !== undefined)
|
|
44
|
+
record(g[key], ["x", "y", "width", "height"]);
|
|
45
|
+
}
|
|
46
|
+
if (g.outputRaster !== undefined)
|
|
47
|
+
raster(g.outputRaster);
|
|
48
|
+
// Existing geometry owns units, orientations, bounds and optical-axis semantics.
|
|
49
|
+
const parsed = g;
|
|
50
|
+
resolveCaptureGeometry(parsed);
|
|
51
|
+
return structuredCloneGeometry(parsed);
|
|
52
|
+
}
|
|
53
|
+
function structuredCloneGeometry(g) {
|
|
54
|
+
return { imagingArea: { ...g.imagingArea }, nativeRaster: { ...g.nativeRaster }, orientation: g.orientation,
|
|
55
|
+
...(g.activeCaptureRect === undefined ? {} : { activeCaptureRect: { ...g.activeCaptureRect } }),
|
|
56
|
+
...(g.outputCropRect === undefined ? {} : { outputCropRect: { ...g.outputCropRect } }),
|
|
57
|
+
...(g.outputRaster === undefined ? {} : { outputRaster: { ...g.outputRaster } }) };
|
|
58
|
+
}
|
|
59
|
+
function sampling(value) {
|
|
60
|
+
const tag = record(value, ["kind", "maximumArcminutesPerPixel", "strokeWidthArcminutes", "samplesPerStroke", "periodArcminutes", "samplesPerPeriod", "pixelsPerInch"]);
|
|
61
|
+
let result;
|
|
62
|
+
switch (tag.kind) {
|
|
63
|
+
case "manual-ppi": {
|
|
64
|
+
const r = record(value, ["kind", "pixelsPerInch"]);
|
|
65
|
+
return { kind: "manual-ppi", pixelsPerInch: number(r.pixelsPerInch, "pixelsPerInch") };
|
|
66
|
+
}
|
|
67
|
+
case "angular-pixel-pitch": {
|
|
68
|
+
const r = record(value, ["kind", "maximumArcminutesPerPixel"]);
|
|
69
|
+
result = { kind: "angular-pixel-pitch", maximumArcminutesPerPixel: number(r.maximumArcminutesPerPixel, "maximumArcminutesPerPixel") };
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "angular-stroke": {
|
|
73
|
+
const r = record(value, ["kind", "strokeWidthArcminutes", "samplesPerStroke"]);
|
|
74
|
+
const samplesPerStroke = number(r.samplesPerStroke, "samplesPerStroke");
|
|
75
|
+
requirePositiveInteger("samplesPerStroke", samplesPerStroke);
|
|
76
|
+
result = { kind: "angular-stroke", strokeWidthArcminutes: number(r.strokeWidthArcminutes, "strokeWidthArcminutes"), samplesPerStroke };
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case "angular-line-pair": {
|
|
80
|
+
const r = record(value, ["kind", "periodArcminutes", "samplesPerPeriod"]);
|
|
81
|
+
const samplesPerPeriod = number(r.samplesPerPeriod, "samplesPerPeriod");
|
|
82
|
+
requirePositiveInteger("samplesPerPeriod", samplesPerPeriod);
|
|
83
|
+
if (samplesPerPeriod < 2)
|
|
84
|
+
throw new InvalidConfigurationError("A line-pair period requires at least two samples.");
|
|
85
|
+
result = { kind: "angular-line-pair", periodArcminutes: number(r.periodArcminutes, "periodArcminutes"), samplesPerPeriod };
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
default: throw new InvalidConfigurationError("Invalid Print sampling convention.");
|
|
89
|
+
}
|
|
90
|
+
const angle = angularLimit(result);
|
|
91
|
+
if (angle <= 0 || angle >= 10800)
|
|
92
|
+
throw new InvalidConfigurationError("Effective angular pixel pitch must lie in (0, 10800) arcminutes.");
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
function angularLimit(s) {
|
|
96
|
+
switch (s.kind) {
|
|
97
|
+
case "angular-pixel-pitch": return s.maximumArcminutesPerPixel;
|
|
98
|
+
case "angular-stroke": return s.strokeWidthArcminutes / s.samplesPerStroke;
|
|
99
|
+
case "angular-line-pair": return s.periodArcminutes / s.samplesPerPeriod;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Validate and copy an untrusted Print request; never infer native authority. */
|
|
103
|
+
export function parsePrintPlanInput(value) {
|
|
104
|
+
const r = record(value, ["source", "printedImage", "viewingDistance", "sampling", "fit", "provider"]);
|
|
105
|
+
const source = record(r.source, ["kind", "captureId", "geometry", "reason"]);
|
|
106
|
+
let parsedSource;
|
|
107
|
+
if (source.kind === "native-retained") {
|
|
108
|
+
record(r.source, ["kind", "captureId", "geometry"]);
|
|
109
|
+
parsedSource = { kind: "native-retained", captureId: requirePublicOpaqueId(source.captureId, "Invalid public capture ID."), geometry: geometry(source.geometry) };
|
|
110
|
+
}
|
|
111
|
+
else if (source.kind === "unavailable") {
|
|
112
|
+
record(r.source, ["kind", "reason"]);
|
|
113
|
+
if (source.reason !== "missing-native-raster" && source.reason !== "unverified-native-identity")
|
|
114
|
+
throw new InvalidConfigurationError("Invalid native-unavailable reason.");
|
|
115
|
+
parsedSource = { kind: "unavailable", reason: source.reason };
|
|
116
|
+
}
|
|
117
|
+
else
|
|
118
|
+
throw new InvalidConfigurationError("Invalid native source kind.");
|
|
119
|
+
const image = record(r.printedImage, ["width", "height", "unit"]);
|
|
120
|
+
const fit = record(r.fit, ["kind", "maximumRelativeAspectError"]);
|
|
121
|
+
if (fit.kind !== "confirmed-native-aspect" || typeof fit.maximumRelativeAspectError !== "number" || !Number.isFinite(fit.maximumRelativeAspectError) || fit.maximumRelativeAspectError < 0 || fit.maximumRelativeAspectError > 0.01)
|
|
122
|
+
throw new InvalidConfigurationError("Declare a native-aspect fit tolerance in [0, 0.01].");
|
|
123
|
+
const parsed = { source: parsedSource, printedImage: { width: number(image.width, "printedImage.width"), height: number(image.height, "printedImage.height"), unit: unit(image.unit) }, viewingDistance: length(r.viewingDistance), sampling: sampling(r.sampling), fit: { kind: "confirmed-native-aspect", maximumRelativeAspectError: fit.maximumRelativeAspectError } };
|
|
124
|
+
if (r.provider !== undefined) {
|
|
125
|
+
const p = record(r.provider, ["minimumRaster", "exactRaster", "minimumPpi", "exactPpi"]);
|
|
126
|
+
parsed.provider = {
|
|
127
|
+
...(p.minimumRaster === undefined ? {} : { minimumRaster: raster(p.minimumRaster) }),
|
|
128
|
+
...(p.exactRaster === undefined ? {} : { exactRaster: raster(p.exactRaster) }),
|
|
129
|
+
...(p.minimumPpi === undefined ? {} : { minimumPpi: number(p.minimumPpi, "minimumPpi") }),
|
|
130
|
+
...(p.exactPpi === undefined ? {} : { exactPpi: number(p.exactPpi, "exactPpi") })
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return parsed;
|
|
134
|
+
}
|
|
135
|
+
function gcd(a, b) { while (b !== 0) {
|
|
136
|
+
const next = a % b;
|
|
137
|
+
a = b;
|
|
138
|
+
b = next;
|
|
139
|
+
} return a; }
|
|
140
|
+
function positiveSupported(...values) { return values.every(v => Number.isFinite(v) && v > 0); }
|
|
141
|
+
// Adjacent binary64 values implement outward rounding, not a criterion epsilon.
|
|
142
|
+
function adjacentPositive(value, direction) {
|
|
143
|
+
const view = new DataView(new ArrayBuffer(8));
|
|
144
|
+
view.setFloat64(0, value);
|
|
145
|
+
view.setBigUint64(0, view.getBigUint64(0) + (direction === "up" ? 1n : -1n));
|
|
146
|
+
return view.getFloat64(0);
|
|
147
|
+
}
|
|
148
|
+
function exactRatio(a, b) {
|
|
149
|
+
return BigInt(a.pixelWidth) * BigInt(b.pixelHeight) === BigInt(a.pixelHeight) * BigInt(b.pixelWidth);
|
|
150
|
+
}
|
|
151
|
+
function minimumRaster(native, width, height) {
|
|
152
|
+
const divisor = gcd(native.pixelWidth, native.pixelHeight);
|
|
153
|
+
const x = native.pixelWidth / divisor, y = native.pixelHeight / divisor;
|
|
154
|
+
const count = Math.max(1, Math.ceil(width / x), Math.ceil(height / y));
|
|
155
|
+
const pixelWidth = count * x, pixelHeight = count * y;
|
|
156
|
+
return Number.isSafeInteger(pixelWidth) && Number.isSafeInteger(pixelHeight) ? { pixelWidth, pixelHeight } : null;
|
|
157
|
+
}
|
|
158
|
+
function diagnostics(raster, width, height, distance) {
|
|
159
|
+
const px = width / raster.pixelWidth, py = height / raster.pixelHeight;
|
|
160
|
+
return { raster, pixelsPerInch: { x: 25.4 / px, y: 25.4 / py }, angularPixelPitchArcminutes: { x: 2 * Math.atan((px / distance) / 2) / RAD_PER_ARCMIN, y: 2 * Math.atan((py / distance) / 2) / RAD_PER_ARCMIN } };
|
|
161
|
+
}
|
|
162
|
+
/** Resolve the minimum exact-native-ratio file under declared sampling/lab constraints.
|
|
163
|
+
* Angular guidance is approximate as a usage criterion; geometry is calculated.
|
|
164
|
+
* No source detail, perceived quality, serializer or resource availability is assessed.
|
|
165
|
+
*/
|
|
166
|
+
export function calculatePrintPlan(value) {
|
|
167
|
+
const input = parsePrintPlanInput(value);
|
|
168
|
+
const plan = { engineApiVersion: ENGINE_API_VERSION, input, status: "cannot-assess", nativePixelSufficiency: "cannot-assess", reasons: [], printedImageMm: null, viewingDistanceMm: null, guidance: null, relativeAspectError: null, native: null, minimumSamplingRaster: null, recommended: null, resamplingScale: null, alternatives: null, capturedDetailAssessment: "unassessed", deliveryAssessment: "unassessed" };
|
|
169
|
+
const finish = () => calculatedResult(plan, "native-only-print-plan", "0.1.0", ["Declared native authority; flat image, normal viewing at image center.", "Output preserves the exact retained native aspect ratio; no upscale.", "Angular sampling is conditional guidance, not captured-detail or print-quality certification."]);
|
|
170
|
+
const unsupported = () => { plan.status = "unsupported"; plan.nativePixelSufficiency = "cannot-assess"; plan.reasons.push("unsupported-numeric-range"); return finish(); };
|
|
171
|
+
const width = input.printedImage.width * UNIT_MM[input.printedImage.unit], height = input.printedImage.height * UNIT_MM[input.printedImage.unit], distance = input.viewingDistance.value * UNIT_MM[input.viewingDistance.unit];
|
|
172
|
+
if (!positiveSupported(width, height, distance))
|
|
173
|
+
return unsupported();
|
|
174
|
+
plan.printedImageMm = { width, height };
|
|
175
|
+
plan.viewingDistanceMm = distance;
|
|
176
|
+
const angle = input.sampling.kind === "manual-ppi" ? null : angularLimit(input.sampling);
|
|
177
|
+
const pitchFactor = angle === null ? null : 2 * Math.tan((angle * RAD_PER_ARCMIN) / 2);
|
|
178
|
+
const pitch = input.sampling.kind === "manual-ppi" ? 25.4 / input.sampling.pixelsPerInch : distance * (pitchFactor ?? 0);
|
|
179
|
+
const ppi = input.sampling.kind === "manual-ppi" ? input.sampling.pixelsPerInch : 25.4 / pitch;
|
|
180
|
+
if (!positiveSupported(pitch, ppi, width / pitch, height / pitch))
|
|
181
|
+
return unsupported();
|
|
182
|
+
const guidance = { derivedPixelsPerInch: ppi, maximumPixelPitchMm: pitch, maximumArcminutesPerPixel: angle };
|
|
183
|
+
plan.guidance = angle === null ? calculatedResult(guidance, "manual-print-density", "0.1.0", ["Explicit manual PPI plan; no angular criterion is certified."]) : approximationResult(guidance, "declared-angular-print-sampling", "0.1.0", ["Exact centered pixel angle uses 2 atan(pitch / (2 distance)); no small-angle substitution.", "Declared angular sampling convention is an uncalibrated usage assumption."]);
|
|
184
|
+
if (input.source.kind === "unavailable") {
|
|
185
|
+
plan.reasons.push(input.source.reason);
|
|
186
|
+
return finish();
|
|
187
|
+
}
|
|
188
|
+
const resolved = resolveCaptureGeometry(input.source.geometry).value;
|
|
189
|
+
const native = { pixelWidth: resolved.output.cropRect.width, pixelHeight: resolved.output.cropRect.height };
|
|
190
|
+
const aspectError = Math.abs((width / height) / (native.pixelWidth / native.pixelHeight) - 1);
|
|
191
|
+
if (!Number.isFinite(aspectError))
|
|
192
|
+
return unsupported();
|
|
193
|
+
plan.relativeAspectError = aspectError;
|
|
194
|
+
const nativeDiagnostics = diagnostics(native, width, height, distance);
|
|
195
|
+
if (!positiveSupported(nativeDiagnostics.pixelsPerInch.x, nativeDiagnostics.pixelsPerInch.y, nativeDiagnostics.angularPixelPitchArcminutes.x, nativeDiagnostics.angularPixelPitchArcminutes.y))
|
|
196
|
+
return unsupported();
|
|
197
|
+
plan.native = nativeDiagnostics;
|
|
198
|
+
if (aspectError > input.fit.maximumRelativeAspectError) {
|
|
199
|
+
plan.status = "crop-confirmation-required";
|
|
200
|
+
plan.reasons.push("printed-image-and-confirmed-crop-aspect-mismatch");
|
|
201
|
+
return finish();
|
|
202
|
+
}
|
|
203
|
+
const widthInches = input.printedImage.unit === "inches" ? input.printedImage.width : width / 25.4;
|
|
204
|
+
const heightInches = input.printedImage.unit === "inches" ? input.printedImage.height : height / 25.4;
|
|
205
|
+
const required = input.sampling.kind === "manual-ppi"
|
|
206
|
+
? minimumRaster(native, widthInches * ppi, heightInches * ppi)
|
|
207
|
+
: minimumRaster(native, width / pitch, height / pitch);
|
|
208
|
+
if (required === null)
|
|
209
|
+
return unsupported();
|
|
210
|
+
plan.minimumSamplingRaster = required;
|
|
211
|
+
const sufficient = required.pixelWidth <= native.pixelWidth && required.pixelHeight <= native.pixelHeight;
|
|
212
|
+
plan.nativePixelSufficiency = sufficient ? "sufficient" : "insufficient";
|
|
213
|
+
let maxScale = Math.min(native.pixelWidth * pitch / width, native.pixelHeight * pitch / height);
|
|
214
|
+
let minimumDistance = pitchFactor === null ? null : Math.max(width / native.pixelWidth, height / native.pixelHeight) / pitchFactor;
|
|
215
|
+
let maxWidth = width * maxScale, maxHeight = height * maxScale;
|
|
216
|
+
if (!positiveSupported(maxWidth, maxHeight) || (minimumDistance !== null && !positiveSupported(minimumDistance)))
|
|
217
|
+
return unsupported();
|
|
218
|
+
const fits = (w, h, p) => {
|
|
219
|
+
const candidate = input.sampling.kind === "manual-ppi" ? minimumRaster(native, w / 25.4 * ppi, h / 25.4 * ppi) : minimumRaster(native, w / p, h / p);
|
|
220
|
+
return candidate !== null && candidate.pixelWidth <= native.pixelWidth && candidate.pixelHeight <= native.pixelHeight;
|
|
221
|
+
};
|
|
222
|
+
// Return alternatives that survive their own documented integer policy.
|
|
223
|
+
for (let i = 0; i < 8 && !fits(maxWidth, maxHeight, pitch); i++) {
|
|
224
|
+
maxScale = adjacentPositive(maxScale, "down");
|
|
225
|
+
maxWidth = width * maxScale;
|
|
226
|
+
maxHeight = height * maxScale;
|
|
227
|
+
}
|
|
228
|
+
if (!positiveSupported(maxWidth, maxHeight) || !fits(maxWidth, maxHeight, pitch))
|
|
229
|
+
return unsupported();
|
|
230
|
+
if (minimumDistance !== null && pitchFactor !== null) {
|
|
231
|
+
for (let i = 0; i < 8 && !fits(width, height, minimumDistance * pitchFactor); i++)
|
|
232
|
+
minimumDistance = adjacentPositive(minimumDistance, "up");
|
|
233
|
+
if (!positiveSupported(minimumDistance) || !fits(width, height, minimumDistance * pitchFactor))
|
|
234
|
+
return unsupported();
|
|
235
|
+
}
|
|
236
|
+
plan.alternatives = { maximumImageMmAtCurrentDistance: { width: maxWidth, height: maxHeight }, minimumViewingDistanceMmAtCurrentSize: minimumDistance };
|
|
237
|
+
if (!sufficient) {
|
|
238
|
+
plan.status = "insufficient-native-pixels";
|
|
239
|
+
plan.reasons.push("sampling-requires-native-upscale");
|
|
240
|
+
}
|
|
241
|
+
let file = required;
|
|
242
|
+
const provider = input.provider;
|
|
243
|
+
if (provider) {
|
|
244
|
+
const density = Math.max(provider.minimumPpi ?? 0, provider.exactPpi ?? 0);
|
|
245
|
+
const constrained = minimumRaster(native, Math.max(required.pixelWidth, provider.minimumRaster?.pixelWidth ?? 0, widthInches * density), Math.max(required.pixelHeight, provider.minimumRaster?.pixelHeight ?? 0, heightInches * density));
|
|
246
|
+
if (constrained === null)
|
|
247
|
+
return unsupported();
|
|
248
|
+
file = provider.exactRaster ?? constrained;
|
|
249
|
+
if (provider.exactPpi !== undefined) {
|
|
250
|
+
const exact = { pixelWidth: widthInches * provider.exactPpi, pixelHeight: heightInches * provider.exactPpi };
|
|
251
|
+
if (!Number.isSafeInteger(exact.pixelWidth) || !Number.isSafeInteger(exact.pixelHeight))
|
|
252
|
+
plan.reasons.push("exact-provider-density-has-no-integer-raster");
|
|
253
|
+
else if (provider.exactRaster && (exact.pixelWidth !== file.pixelWidth || exact.pixelHeight !== file.pixelHeight))
|
|
254
|
+
plan.reasons.push("provider-exact-raster-density-conflict");
|
|
255
|
+
else
|
|
256
|
+
file = exact;
|
|
257
|
+
}
|
|
258
|
+
if (!exactRatio(file, native))
|
|
259
|
+
plan.reasons.push("provider-raster-aspect-conflict");
|
|
260
|
+
if (file.pixelWidth < constrained.pixelWidth || file.pixelHeight < constrained.pixelHeight)
|
|
261
|
+
plan.reasons.push("provider-exact-requirement-below-minimum");
|
|
262
|
+
if (file.pixelWidth > native.pixelWidth || file.pixelHeight > native.pixelHeight)
|
|
263
|
+
plan.reasons.push("provider-requires-native-upscale");
|
|
264
|
+
if (plan.reasons.some(r => r.startsWith("provider-") || r.startsWith("exact-provider-"))) {
|
|
265
|
+
plan.status = "provider-conflict";
|
|
266
|
+
return finish();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (!sufficient)
|
|
270
|
+
return finish();
|
|
271
|
+
const achieved = diagnostics(file, width, height, distance);
|
|
272
|
+
if (!positiveSupported(achieved.pixelsPerInch.x, achieved.pixelsPerInch.y, achieved.angularPixelPitchArcminutes.x, achieved.angularPixelPitchArcminutes.y))
|
|
273
|
+
return unsupported();
|
|
274
|
+
plan.status = "ready";
|
|
275
|
+
plan.recommended = achieved;
|
|
276
|
+
plan.resamplingScale = { x: file.pixelWidth / native.pixelWidth, y: file.pixelHeight / native.pixelHeight };
|
|
277
|
+
return finish();
|
|
278
|
+
}
|
|
279
|
+
/** Calculate a conditional size bound. Lab constraints require individual plans;
|
|
280
|
+
* this first size-query contract reports them as unsupported rather than ignoring them.
|
|
281
|
+
*/
|
|
282
|
+
export function calculatePrintSizeLimit(value) {
|
|
283
|
+
const r = record(value, ["plan", "viewingDistancePolicy"]);
|
|
284
|
+
if (r.viewingDistancePolicy !== "fixed" && r.viewingDistancePolicy !== "proportional-to-image-size")
|
|
285
|
+
throw new InvalidConfigurationError("Invalid viewing-distance scaling policy.");
|
|
286
|
+
const referencePlan = calculatePrintPlan(parsePrintPlanInput(r.plan)).value;
|
|
287
|
+
const result = { engineApiVersion: ENGINE_API_VERSION, status: "cannot-assess", maximumImageMm: null, reasons: [...referencePlan.reasons], referencePlan };
|
|
288
|
+
if (referencePlan.input.provider !== undefined && Object.keys(referencePlan.input.provider).length > 0) {
|
|
289
|
+
result.status = "unsupported";
|
|
290
|
+
result.reasons.push("size-query-with-provider-constraints-unsupported");
|
|
291
|
+
}
|
|
292
|
+
else if (referencePlan.status === "unsupported")
|
|
293
|
+
result.status = "unsupported";
|
|
294
|
+
else if (referencePlan.alternatives !== null) {
|
|
295
|
+
if (r.viewingDistancePolicy === "proportional-to-image-size" && referencePlan.input.sampling.kind !== "manual-ppi") {
|
|
296
|
+
result.status = referencePlan.nativePixelSufficiency === "sufficient" ? "unbounded" : "no-positive-size";
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
result.status = "finite";
|
|
300
|
+
result.maximumImageMm = referencePlan.alternatives.maximumImageMmAtCurrentDistance;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return calculatedResult(result, "conditional-native-print-size-limit", "0.1.0", ["Native sampling capacity only; no perceived-quality or physical-printer bound.", "Proportional distance and image scaling preserve angular pixel pitch."]);
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=print-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print-plan.js","sourceRoot":"","sources":["../../src/output/print-plan.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAA0B,MAAM,+BAA+B,CAAC;AAC9G,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAoC,MAAM,uBAAuB,CAAC;AA2DjG,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAW,CAAC;AAClE,MAAM,cAAc,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC;AACvC,SAAS,MAAM,CAAC,KAAc,EAAE,IAAuB;IACrD,OAAO,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,2CAA2C,CAAC,CAAC;AAC5F,CAAC;AACD,SAAS,MAAM,CAAC,KAAc,EAAE,IAAY;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,yBAAyB,CAAC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAC/F,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAAC,OAAO,KAAK,CAAC;AACnD,CAAC;AACD,SAAS,IAAI,CAAC,KAAc;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,IAAI,yBAAyB,CAAC,4BAA4B,CAAC,CAAC;IACnI,OAAO,KAA4B,CAAC;AACtC,CAAC;AACD,SAAS,MAAM,CAAC,KAAc;IAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AACxE,CAAC;AACD,SAAS,MAAM,CAAC,KAAc;IAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1G,sBAAsB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAAC,sBAAsB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACrG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACrC,CAAC;AACD,SAAS,QAAQ,CAAC,KAAc;IAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAC;IAC/H,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACvE,KAAK,MAAM,GAAG,IAAI,CAAC,mBAAmB,EAAE,gBAAgB,CAAU,EAAE,CAAC;QACnE,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACzD,iFAAiF;IACjF,MAAM,MAAM,GAAG,CAA2C,CAAC;IAC3D,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AACD,SAAS,uBAAuB,CAAC,CAA8B;IAC7D,OAAO,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW;QACzG,GAAG,CAAC,CAAC,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC/F,GAAG,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;QACtF,GAAG,CAAC,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC;AACvF,CAAC;AACD,SAAS,QAAQ,CAAC,KAAc;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC;IACvK,IAAI,MAA8B,CAAC;IACnC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;YACnD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,eAAe,CAAC,EAAE,CAAC;QACzF,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC;YAC/D,MAAM,GAAG,EAAE,IAAI,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,CAAC,CAAC,CAAC,yBAAyB,EAAE,2BAA2B,CAAC,EAAE,CAAC;YAAC,MAAM;QAC/I,CAAC;QACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,kBAAkB,CAAC,CAAC,CAAC;YAC/E,MAAM,gBAAgB,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;YAAC,sBAAsB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;YACtI,MAAM,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,EAAE,uBAAuB,CAAC,EAAE,gBAAgB,EAAE,CAAC;YAAC,MAAM;QAChJ,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CAAC;YAC1E,MAAM,gBAAgB,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;YAAC,sBAAsB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;YACtI,IAAI,gBAAgB,GAAG,CAAC;gBAAE,MAAM,IAAI,yBAAyB,CAAC,mDAAmD,CAAC,CAAC;YACnH,MAAM,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAC;YAAC,MAAM;QACpI,CAAC;QACD,OAAO,CAAC,CAAC,MAAM,IAAI,yBAAyB,CAAC,oCAAoC,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK;QAAE,MAAM,IAAI,yBAAyB,CAAC,kEAAkE,CAAC,CAAC;IAC1I,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,SAAS,YAAY,CAAC,CAA0D;IAC9E,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,qBAAqB,CAAC,CAAC,OAAO,CAAC,CAAC,yBAAyB,CAAC;QAC/D,KAAK,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,qBAAqB,GAAG,CAAC,CAAC,gBAAgB,CAAC;QAC3E,KAAK,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;IAC3E,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IACtG,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7E,IAAI,YAA+B,CAAC;IACpC,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;QACpD,YAAY,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,qBAAqB,CAAC,MAAM,CAAC,SAAS,EAAE,4BAA4B,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACpK,CAAC;SAAM,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACzC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,MAAM,KAAK,uBAAuB,IAAI,MAAM,CAAC,MAAM,KAAK,4BAA4B;YAAE,MAAM,IAAI,yBAAyB,CAAC,oCAAoC,CAAC,CAAC;QAC3K,YAAY,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC;;QAAM,MAAM,IAAI,yBAAyB,CAAC,6BAA6B,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC,CAAC;IAClE,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB,IAAI,OAAO,GAAG,CAAC,0BAA0B,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,0BAA0B,CAAC,IAAI,GAAG,CAAC,0BAA0B,GAAG,CAAC,IAAI,GAAG,CAAC,0BAA0B,GAAG,IAAI;QAAE,MAAM,IAAI,yBAAyB,CAAC,qDAAqD,CAAC,CAAC;IAChU,MAAM,MAAM,GAAmB,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC;IAC3X,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,QAAQ,GAAG;YAChB,GAAG,CAAC,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;YACpF,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9E,GAAG,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,CAAC;YACzF,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;SAClF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS,IAAY,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;IAAC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,GAAG,IAAI,CAAC;AAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjH,SAAS,iBAAiB,CAAC,GAAG,MAAgB,IAAa,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACnH,gFAAgF;AAChF,SAAS,gBAAgB,CAAC,KAAa,EAAE,SAAwB;IAC/D,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACzE,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AACD,SAAS,UAAU,CAAC,CAAmB,EAAE,CAAmB;IAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;AACvG,CAAC;AACD,SAAS,aAAa,CAAC,MAAwB,EAAE,KAAa,EAAE,MAAc;IAC5E,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpH,CAAC;AACD,SAAS,WAAW,CAAC,MAAwB,EAAE,KAAa,EAAE,MAAc,EAAE,QAAgB;IAC5F,MAAM,EAAE,GAAG,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;IACvE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,2BAA2B,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,EAAE,CAAC;AACpN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,IAAI,GAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,sBAAsB,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,wBAAwB,EAAE,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,CAAC;IACpa,MAAM,MAAM,GAAG,GAAiC,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,CAAC,wEAAwE,EAAE,sEAAsE,EAAE,+FAA+F,CAAC,CAAC,CAAC;IAClW,MAAM,WAAW,GAAG,GAAiC,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC,IAAI,CAAC,sBAAsB,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACzM,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,eAAe,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/N,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACtE,IAAI,CAAC,cAAc,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC;IAC3E,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACzF,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IACzH,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;IAC/F,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACxF,MAAM,QAAQ,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,mBAAmB,EAAE,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,CAAC;IAC7G,IAAI,CAAC,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC,8DAA8D,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,iCAAiC,EAAE,OAAO,EAAE,CAAC,4FAA4F,EAAE,2EAA2E,CAAC,CAAC,CAAC;IACxZ,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;IAAC,CAAC;IACrG,MAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;IACrE,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC5G,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9F,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACxD,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC;IACvC,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvE,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,CAAC,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,CAAC,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACrN,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC;IAChC,IAAI,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC;QAAC,IAAI,CAAC,MAAM,GAAG,4BAA4B,CAAC;QAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;IAAC,CAAC;IAC/L,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC;IACnG,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;IACtG,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;QACnD,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,EAAE,YAAY,GAAG,GAAG,CAAC;QAC9D,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;IACzD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,WAAW,EAAE,CAAC;IAC5C,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC;IACtC,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,IAAI,QAAQ,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;IAC1G,IAAI,CAAC,sBAAsB,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC;IACzE,IAAI,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,CAAC,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC;IAChG,IAAI,eAAe,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACnI,IAAI,QAAQ,GAAG,KAAK,GAAG,QAAQ,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC/D,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,eAAe,KAAK,IAAI,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACvI,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAW,EAAE;QACxD,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrJ,OAAO,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;IACxH,CAAC,CAAC;IACF,wEAAwE;IACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChE,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAAC,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;QAAC,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC5G,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACvG,IAAI,eAAe,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,GAAG,WAAW,CAAC,EAAE,CAAC,EAAE;YAAE,eAAe,GAAG,gBAAgB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QAC7I,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,GAAG,WAAW,CAAC;YAAE,OAAO,WAAW,EAAE,CAAC;IACvH,CAAC;IACD,IAAI,CAAC,YAAY,GAAG,EAAE,+BAA+B,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,qCAAqC,EAAE,eAAe,EAAE,CAAC;IACxJ,IAAI,CAAC,UAAU,EAAE,CAAC;QAAC,IAAI,CAAC,MAAM,GAAG,4BAA4B,CAAC;QAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAAC,CAAC;IACvH,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,EAAE,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,aAAa,EAAE,UAAU,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,aAAa,EAAE,WAAW,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;QAC3O,IAAI,WAAW,KAAK,IAAI;YAAE,OAAO,WAAW,EAAE,CAAC;QAC/C,IAAI,GAAG,QAAQ,CAAC,WAAW,IAAI,WAAW,CAAC;QAC3C,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,WAAW,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC7G,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;iBACtJ,IAAI,QAAQ,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;;gBAC1K,IAAI,GAAG,KAAK,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACpF,IAAI,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,WAAW;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QAC1J,IAAI,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QACxI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC;YAAC,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC;YAAC,OAAO,MAAM,EAAE,CAAC;QAAC,CAAC;IACnJ,CAAC;IACD,IAAI,CAAC,UAAU;QAAE,OAAO,MAAM,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,2BAA2B,CAAC,CAAC,EAAE,QAAQ,CAAC,2BAA2B,CAAC,CAAC,CAAC;QAAE,OAAO,WAAW,EAAE,CAAC;IACjL,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;IACnD,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC5G,OAAO,MAAM,EAAE,CAAC;AAClB,CAAC;AAiBD;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAA0B;IAChE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC,qBAAqB,KAAK,OAAO,IAAI,CAAC,CAAC,qBAAqB,KAAK,4BAA4B;QAAE,MAAM,IAAI,yBAAyB,CAAC,0CAA0C,CAAC,CAAC;IACrL,MAAM,aAAa,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5E,MAAM,MAAM,GAAmB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3K,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvG,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC;QAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACzG,CAAC;SAAM,IAAI,aAAa,CAAC,MAAM,KAAK,aAAa;QAAE,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC;SAC5E,IAAI,aAAa,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,CAAC,qBAAqB,KAAK,4BAA4B,IAAI,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACnH,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC,sBAAsB,KAAK,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC;QAC3G,CAAC;aAAM,CAAC;YAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC;YAAC,MAAM,CAAC,cAAc,GAAG,aAAa,CAAC,YAAY,CAAC,+BAA+B,CAAC;QAAC,CAAC;IAC1H,CAAC;IACD,OAAO,gBAAgB,CAAC,MAAM,EAAE,qCAAqC,EAAE,OAAO,EAAE,CAAC,gFAAgF,EAAE,uEAAuE,CAAC,CAAC,CAAC;AAC/O,CAAC"}
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public API reference
|
|
2
2
|
|
|
3
|
-
Generated from the exact root exports for **@photivra/engine 1.
|
|
3
|
+
Generated from the exact root exports for **@photivra/engine 1.1.0 / root contract 1.1.0** by `node scripts/generate-api-reference.mjs`. No module deep import is supported.
|
|
4
4
|
|
|
5
5
|
Use [the developer guide](DEVELOPERS.md) for executable paths and scientific boundaries. Types are contracts, not runtime validation: parse untrusted data, preserve units/reference frames, read assessment blockers, and retain evidence/limitations. Optional properties do not imply a universal default. Model/schema IDs remain independent of the distribution.
|
|
6
6
|
|
|
@@ -1189,6 +1189,43 @@ Use [the developer guide](DEVELOPERS.md) for executable paths and scientific bou
|
|
|
1189
1189
|
| [`ResolvedLensCorrectionPlan`](api/output-lens-corrections.md#resolvedlenscorrectionplan) | Type |
|
|
1190
1190
|
| [`resolveLensCorrectionPlan`](api/output-lens-corrections.md#resolvelenscorrectionplan) | Runtime |
|
|
1191
1191
|
|
|
1192
|
+
## output/print-detail.ts
|
|
1193
|
+
|
|
1194
|
+
[Detailed contracts](api/output-print-detail.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/output/print-detail.ts)
|
|
1195
|
+
|
|
1196
|
+
| Export | Kind |
|
|
1197
|
+
| --- | --- |
|
|
1198
|
+
| [`calculatePrintRegionDetail`](api/output-print-detail.md#calculateprintregiondetail) | Runtime |
|
|
1199
|
+
| [`MAX_PRINT_DETAIL_REGION_SAMPLES`](api/output-print-detail.md#max_print_detail_region_samples) | Runtime |
|
|
1200
|
+
| [`parsePrintRegionDetailInput`](api/output-print-detail.md#parseprintregiondetailinput) | Runtime |
|
|
1201
|
+
| [`PRINT_REGION_DETAIL_MODEL_VERSION`](api/output-print-detail.md#print_region_detail_model_version) | Runtime |
|
|
1202
|
+
| [`PrintDetailRegion`](api/output-print-detail.md#printdetailregion) | Type |
|
|
1203
|
+
| [`PrintDetailSource`](api/output-print-detail.md#printdetailsource) | Type |
|
|
1204
|
+
| [`PrintRegionDetailAssessment`](api/output-print-detail.md#printregiondetailassessment) | Type |
|
|
1205
|
+
| [`PrintRegionDetailInput`](api/output-print-detail.md#printregiondetailinput) | Type |
|
|
1206
|
+
| [`PrintSinusoidalMeasurement`](api/output-print-detail.md#printsinusoidalmeasurement) | Type |
|
|
1207
|
+
| [`PrintSinusoidalTarget`](api/output-print-detail.md#printsinusoidaltarget) | Type |
|
|
1208
|
+
|
|
1209
|
+
## output/print-plan.ts
|
|
1210
|
+
|
|
1211
|
+
[Detailed contracts](api/output-print-plan.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/output/print-plan.ts)
|
|
1212
|
+
|
|
1213
|
+
| Export | Kind |
|
|
1214
|
+
| --- | --- |
|
|
1215
|
+
| [`calculatePrintPlan`](api/output-print-plan.md#calculateprintplan) | Runtime |
|
|
1216
|
+
| [`calculatePrintSizeLimit`](api/output-print-plan.md#calculateprintsizelimit) | Runtime |
|
|
1217
|
+
| [`parsePrintPlanInput`](api/output-print-plan.md#parseprintplaninput) | Runtime |
|
|
1218
|
+
| [`PrintedImageSize`](api/output-print-plan.md#printedimagesize) | Type |
|
|
1219
|
+
| [`PrintLength`](api/output-print-plan.md#printlength) | Type |
|
|
1220
|
+
| [`PrintNativeSource`](api/output-print-plan.md#printnativesource) | Type |
|
|
1221
|
+
| [`PrintPlan`](api/output-print-plan.md#printplan) | Type |
|
|
1222
|
+
| [`PrintPlanInput`](api/output-print-plan.md#printplaninput) | Type |
|
|
1223
|
+
| [`PrintProviderConstraints`](api/output-print-plan.md#printproviderconstraints) | Type |
|
|
1224
|
+
| [`PrintRasterSampling`](api/output-print-plan.md#printrastersampling) | Type |
|
|
1225
|
+
| [`PrintSamplingCriterion`](api/output-print-plan.md#printsamplingcriterion) | Type |
|
|
1226
|
+
| [`PrintSizeLimit`](api/output-print-plan.md#printsizelimit) | Type |
|
|
1227
|
+
| [`PrintSizeLimitInput`](api/output-print-plan.md#printsizelimitinput) | Type |
|
|
1228
|
+
|
|
1192
1229
|
## output/sdr-rendering.ts
|
|
1193
1230
|
|
|
1194
1231
|
[Detailed contracts](api/output-sdr-rendering.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/output/sdr-rendering.ts)
|
package/docs/API_STYLE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public API Style
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
The open engine should feel like one coherent library.
|
|
6
6
|
|
|
@@ -89,14 +89,14 @@ Do **not** automatically sum, average, add in quadrature, or otherwise collapse
|
|
|
89
89
|
|
|
90
90
|
## Versioning
|
|
91
91
|
|
|
92
|
-
Photivra
|
|
92
|
+
From 1.0.1, Photivra aligns its release and root API identities:
|
|
93
93
|
|
|
94
94
|
- npm/package version: distribution/release version;
|
|
95
|
-
- `ENGINE_API_VERSION`:
|
|
95
|
+
- `ENGINE_API_VERSION`: the same full version as the npm package;
|
|
96
96
|
- `POC_SIMULATION_API_VERSION`: composed `simulatePocCamera()` request/response contract;
|
|
97
97
|
- schema-specific versions such as sensor-architecture or radiometry-readiness schemas.
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
The release checker enforces package/root equality. Subsystem, schema and POC versions remain independent. A change to a parser/schema does not necessarily require changing the POC contract, and a POC response change does not necessarily mean the npm package has been released.
|
|
100
100
|
|
|
101
101
|
Before 1.0, public APIs may evolve with documented changes. Breaking or semantically meaningful contract changes must update the relevant version surface, tests, changelog, and migration/compatibility documentation. After 1.0, breaking public-contract changes require an appropriate major-version transition.
|
|
102
102
|
|
|
@@ -160,7 +160,7 @@ serialization keeps its existing validated JSON.stringify representation.
|
|
|
160
160
|
|
|
161
161
|
## Compatibility and deprecation policy
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
The package and root API share a release version. Update independent schema/model/POC versions only when their observable contracts change.
|
|
164
164
|
|
|
165
165
|
### Package version
|
|
166
166
|
|
|
@@ -168,7 +168,7 @@ The npm package version identifies a published distribution. It is not a proxy f
|
|
|
168
168
|
|
|
169
169
|
### `ENGINE_API_VERSION`
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
Set to the npm package version for every release, including patches. New records use this creator identity; parsers preserve historical archive identities.
|
|
172
172
|
|
|
173
173
|
### Subsystem/schema versions
|
|
174
174
|
|
|
@@ -228,4 +228,8 @@ Audit rule:
|
|
|
228
228
|
|
|
229
229
|
## Stable 1.0 distribution transition
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
Historically, package 1.0.0 retained `ENGINE_API_VERSION = "0.116.0"`: this independent root contract identity is already embedded in serialized captures and does not itself signal a published distribution. The package 1.0 policy now governs breaking changes despite that historical root ID. No schema/model/POC/plan version is reset. See [migration and release procedure](RELEASE_1_0.md).
|
|
232
|
+
|
|
233
|
+
## Aligned 1.0.1 release transition
|
|
234
|
+
|
|
235
|
+
Starting with 1.0.1, `ENGINE_API_VERSION` equals the full npm package version. Package and root API follow one SemVer release sequence; schema/model/POC/plan versions remain independent. Archived capture identities and measured artifacts are preserved. Newly created capture/plan bytes and identity hashes can change because their creator API field now records 1.0.1. See [migration and release procedure](RELEASE_1_0_1.md).
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
Photivra separates a reusable scientific core from optional composition and transport layers.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public-engine automation coordination
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
This document coordinates the two recurring automation lanes that work only in the public
|
|
6
6
|
`Photivra/photivra` repository. It is process guidance, not a scientific roadmap. Open issues and
|
package/docs/CAPTURE_COLOR.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Virtual-camera linear color: #15B
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
`resolveCaptureColorModel()` defines an ideal CIE 1931 2-degree colorimetric camera: co-sited red/green/blue channels are an invertible encoding of XYZ in the linear-sRGB primary basis, with D65 reference white. They are relative linear values, not electrons, spectral response measurements or commercial-camera RGB. Choosing this profile is an upstream producer assertion about sample meaning; naming arbitrary sensor data with its ID does not establish validity.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Capture-bound corrections and SDR: #112 integration slice
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
`calculateCaptureCorrectedSdr()` consumes the same immutable `SimulatedCapture` and explicit source/color/WB choice as `calculateCaptureSdr()`, then executes existing #117/#118 corrections before the existing SDR renderer. This bounded reference bridge does not replace the #111 composer, activate production stages, or complete #112/V1.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Capture export metadata foundation (#16B)
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
`createCaptureExportMetadataPair()` is a browser-safe, deterministic **semantic metadata projection**, not an image exporter or proof of RAW/JPEG pixel derivation. Both future writers consume its single shared object; each resource has a distinct caller-owned document UUID and saved-incarnation UUID. `imageDataPairing = "not-verified"` prevents metadata agreement being mistaken for image agreement.
|
|
6
6
|
|
package/docs/CAPTURE_SDR.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Capture-to-SDR adapter
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
Current integration: [processed camera output](PROCESSED_OUTPUT.md) documents
|
|
6
6
|
the shared preview/export path and explicit plan 0.6.0 post-RAW activation.
|
package/docs/DEVELOPERS.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
# Developer guide
|
|
2
2
|
|
|
3
|
-
This is the entry point for **@photivra/engine 1.
|
|
3
|
+
This is the entry point for **@photivra/engine 1.1.0 candidate**, root API contract **1.1.0**. The candidate becomes an installable 1.1.0 distribution only after the owner tags and publishes it. Repository `main` may later describe newer development; use a published release's packaged docs or its exact tag for the stable contract. [Release notes and migration](RELEASE_1_1_0.md) explain the transition to aligned package/root versions.
|
|
4
4
|
|
|
5
5
|
Photivra is an Apache-2.0 ESM TypeScript calculation library with no runtime npm dependencies. It exposes explicit units, deterministic data, provenance and bounded scientific approximations. The package supplies no hosted API, renderer installation, UI, commercial camera calibration or automatic agent service. [Photivra's public site](https://photivra.com) is separate from the engine's license; public engine documentation is available here without an application account.
|
|
6
6
|
|
|
7
7
|
## Install and calculate
|
|
8
8
|
|
|
9
|
-
After publication, install `npm install @photivra/engine@1.
|
|
9
|
+
After publication, install `npm install @photivra/engine@1.1.0`. During candidate review, use the verified tarball described in [release preparation](RELEASE_1_1_0.md).
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
import { calculateFieldOfView, ENGINE_API_VERSION } from "@photivra/engine";
|
|
13
13
|
|
|
14
14
|
const horizontal = calculateFieldOfView({ focalLengthMm: 50, sensorDimensionMm: 36 });
|
|
15
|
-
console.log(ENGINE_API_VERSION); //
|
|
15
|
+
console.log(ENGINE_API_VERSION); // 1.1.0: matches the package version
|
|
16
16
|
console.log(horizontal.value.degrees); // approximately 39.60, ideal infinity-focus geometry
|
|
17
17
|
console.log(horizontal.provenance); // read assumptions/status with the value
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
The root is browser-safe. Supported Node execution/tooling is Node 22.13+ within the maintained 22 line
|
|
20
|
+
The root is browser-safe. Supported Node execution/tooling is Node 22.13+ within the maintained 22 line, the maintained 24 line, and Node 26 Current; prefer patched Node 24. The broad manifest minimum does not qualify untested or EOL lines. A browser backend must supply the documented ES APIs (including `structuredClone`, typed arrays and Web Crypto where used); a browser-safe import graph is not a promise about every browser version or rendering speed. See [runtime policy](../NODE_SUPPORT.md).
|
|
21
21
|
|
|
22
22
|
Primitive calculations normally return `CalculationResult<T>` with `value`, `provenance` and optional `quality`. Parsers return validated values; plans/snapshots return their independently versioned records; assessments return explicit blockers; paired export returns a Promise because hashing is asynchronous. Do not infer calibrated accuracy from successful parsing, a complete stage graph, a generic tier name or deterministic replay.
|
|
23
23
|
|
|
24
24
|
## Find the operation by scientific task
|
|
25
25
|
|
|
26
|
-
Every row applies to package
|
|
26
|
+
Every row applies to package/root API 1.1.0. Direct calculations are synchronous/browser-safe unless the row says otherwise. A listed primitive is not automatically an app feature or supported in every production combination. The [API reference](API_REFERENCE.md) resolves all root exports and exact signatures; the linked guides own equations, inputs, defaults, errors and limits.
|
|
27
27
|
|
|
28
28
|
| Task | Start here / executable evidence | Qualified boundary |
|
|
29
29
|
| --- | --- | --- |
|
|
@@ -57,4 +57,10 @@ Malformed configurations/non-finite values throw the established domain errors.
|
|
|
57
57
|
|
|
58
58
|
See [provenance](PROVENANCE.md), [license](../LICENSE), [NOTICE](../NOTICE), [third-party inventory](../THIRD_PARTY.md), [contributing](../CONTRIBUTING.md) and [security reporting](../SECURITY.md). Engine code/docs do not license the commercial application or its private assets. Report reproducible engine defects through [public issues](https://github.com/Photivra/photivra/issues).
|
|
59
59
|
|
|
60
|
-
Website navigation/documentation hosting belongs to [the app-side discovery ticket #45](https://github.com/Photivra/photivra-apps/issues/45), with navigation #298 and environments #300. Handoff: link the public engine repository, this developer guide, the
|
|
60
|
+
Website navigation/documentation hosting belongs to [the app-side discovery ticket #45](https://github.com/Photivra/photivra-apps/issues/45), with navigation #298 and environments #300. Handoff: link the public engine repository, this developer guide, the verified npm release package and capability examples from the public site. No unpublished `/developers` destination is linked here. Website launch is not an engine release prerequisite; access to the site returned HTTP 403 during this audit, so its content/navigation was not verified.
|
|
61
|
+
|
|
62
|
+
## Print planning
|
|
63
|
+
|
|
64
|
+
Use [native-only Print planning](PRINT_PLANNING.md) for independently specified image size/viewing distance, explicit angular conventions, confirmed native crop and lab constraints. It returns no upscale recommendation and does not certify perceived quality or activate an exporter.
|
|
65
|
+
|
|
66
|
+
The [regional Print detail diagnostic](PRINT_DETAIL_ASSESSMENT.md) measures one declared coherent sinusoidal fundamental in a selected linear-luminance ROI and records its exact source stage. Its [validation protocol](PRINT_DETAIL_VALIDATION.md) and [capability ledger](validation/print-detail-capabilities.json) distinguish mathematical conformance from blocked acquired-image, renderer and perceived-quality qualification.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Stray light and digital lens correction foundations
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
Issues #114, #118 and #117 add standalone browser-safe primitives. They do not enable a production-plan stage, change the POC, or supply a calibrated camera/lens preset. The public root API advances from 0.94.0 to 0.95.0; each new profile/prepared-map schema is 0.1.0. Package, POC, production-plan and PSF versions are unchanged. This branch incorporates merged polygon-diffraction PR #157 and reconciles the root API increment with that predecessor.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Executed environment capture to native RAW
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
`calculateEnvironmentSensorPhotoSignal()` executes one destination site's
|
|
6
6
|
bounded environment exposure. `simulateEnvironmentSensorRawFrame()` applies that
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Simulated Sensor RAW DNG / JPEG acceptance
|
|
2
2
|
|
|
3
|
-
Release context: **package 1.
|
|
3
|
+
Release context: **package 1.1.0 candidate / root API 1.1.0**. Subsystem/model versions and dated introduction or measurement records below are independent historical identities; they are not distribution versions. See [developer navigation](DEVELOPERS.md) and [release contract](RELEASE_1_1_0.md).
|
|
4
4
|
|
|
5
5
|
This record separates implemented export behavior, reproducible independent
|
|
6
6
|
checks and external application acceptance for #16. The files are synthetic
|