{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://threejs-blocks.com/schemas/baked-motion.schema.json",
	"title": "Baked Motion manifest",
	"description": "Normative wire schema for an indexed, range-addressable Baked Motion package.",
	"$comment": "Decoded JSON text is capped at 524288 UTF-8 bytes. Cross-field invariants (axis products, per-codec decode envelope, stream frame counts, synchronized resources, segment coverage, range overlap, footer exclusion, alpha/depth consistency, and the global 100000-entry index cap) are enforced by parseBakedMotionManifest().",
	"type": "object",
	"additionalProperties": false,
	"required": [
		"type",
		"version",
		"frameRate",
		"frameCount",
		"mode",
		"order",
		"axes",
		"camera",
		"bounds",
		"tracks",
		"renditions",
		"generator"
	],
	"properties": {
		"type": {
			"const": "utsubo-utsbv"
		},
		"version": {
			"const": 3
		},
		"frameRate": {
			"$ref": "#/$defs/frameRate"
		},
		"frameCount": {
			"$ref": "#/$defs/positiveSafeInteger"
		},
		"mode": {
			"enum": [
				"timeline",
				"tilt",
				"rotation"
			]
		},
		"order": {
			"enum": [
				"rowMajor",
				"serpentine"
			]
		},
		"axes": {
			"type": "array",
			"minItems": 1,
			"maxItems": 2,
			"items": {
				"$ref": "#/$defs/axis"
			}
		},
		"camera": {
			"$ref": "#/$defs/camera"
		},
		"bounds": {
			"$ref": "#/$defs/bounds"
		},
		"tracks": {
			"$ref": "#/$defs/tracks"
		},
		"renditions": {
			"type": "array",
			"minItems": 1,
			"items": {
				"$ref": "#/$defs/rendition"
			}
		},
		"coarse": {
			"type": "object",
			"description": "Optional all-view thumbnail atlas: one still image per role holding every stored view, decoded once as a texture so a corner still in flight always has evidence at its own pose. Two-axis grids only.",
			"additionalProperties": false,
			"required": [
				"tile",
				"grid",
				"resources"
			],
			"properties": {
				"tile": {
					"type": "integer",
					"minimum": 1
				},
				"grid": {
					"type": "array",
					"minItems": 2,
					"maxItems": 2,
					"items": {
						"type": "integer",
						"minimum": 1
					}
				},
				"resources": {
					"type": "object",
					"additionalProperties": false,
					"required": [
						"albedo"
					],
					"properties": {
						"albedo": {
							"$ref": "#/$defs/coarseResource"
						},
						"depth": {
							"$ref": "#/$defs/coarseResource"
						}
					}
				}
			}
		},
		"generator": {
			"$ref": "#/$defs/generator"
		},
		"pointer": {
			"$ref": "#/$defs/pointer"
		}
	},
	"allOf": [
		{
			"if": {
				"type": "object",
				"properties": {
					"mode": {
						"const": "timeline"
					}
				},
				"required": [
					"mode"
				]
			},
			"then": {
				"type": "object",
				"properties": {
					"axes": {
						"type": "array",
						"minItems": 1,
						"maxItems": 1,
						"prefixItems": [
							{
								"$ref": "#/$defs/timeAxis"
							}
						],
						"items": false
					}
				},
				"not": {
					"type": "object",
					"required": [
						"pointer"
					]
				}
			}
		},
		{
			"if": {
				"type": "object",
				"properties": {
					"mode": {
						"const": "tilt"
					}
				},
				"required": [
					"mode"
				]
			},
			"then": {
				"type": "object",
				"required": [
					"pointer"
				],
				"properties": {
					"axes": {
						"type": "array",
						"minItems": 2,
						"maxItems": 2,
						"prefixItems": [
							{
								"$ref": "#/$defs/tiltXAxis"
							},
							{
								"$ref": "#/$defs/tiltYAxis"
							}
						],
						"items": false
					}
				}
			}
		},
		{
			"if": {
				"type": "object",
				"properties": {
					"mode": {
						"const": "rotation"
					}
				},
				"required": [
					"mode"
				]
			},
			"then": {
				"type": "object",
				"properties": {
					"axes": {
						"oneOf": [
							{
								"type": "array",
								"minItems": 1,
								"maxItems": 1,
								"prefixItems": [
									{
										"$ref": "#/$defs/azimuthAxis"
									}
								],
								"items": false
							},
							{
								"type": "array",
								"minItems": 2,
								"maxItems": 2,
								"prefixItems": [
									{
										"$ref": "#/$defs/azimuthAxis"
									},
									{
										"$ref": "#/$defs/elevationAxis"
									}
								],
								"items": false
							}
						]
					}
				},
				"not": {
					"type": "object",
					"required": [
						"pointer"
					]
				}
			}
		},
		{
			"if": {
				"type": "object",
				"properties": {
					"tracks": {
						"type": "object",
						"required": [
							"depth"
						]
					}
				},
				"required": [
					"tracks"
				]
			},
			"then": {
				"type": "object",
				"properties": {
					"renditions": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"resources": {
									"type": "object",
									"required": [
										"depth"
									]
								}
							}
						}
					}
				}
			},
			"else": {
				"type": "object",
				"properties": {
					"renditions": {
						"type": "array",
						"items": {
							"type": "object",
							"properties": {
								"resources": {
									"not": {
										"type": "object",
										"required": [
											"depth"
										]
									}
								}
							}
						}
					}
				}
			}
		}
	],
	"$defs": {
		"safeInteger": {
			"type": "integer",
			"minimum": 0,
			"maximum": 9007199254740991
		},
		"positiveSafeInteger": {
			"type": "integer",
			"minimum": 1,
			"maximum": 9007199254740991
		},
		"activeFrameBodyByteLength": {
			"type": "integer",
			"minimum": 1,
			"maximum": 4294967295,
			"description": "Encoded-body length representable by the .af four-byte unsigned trailer offset."
		},
		"positiveNumber": {
			"type": "number",
			"exclusiveMinimum": 0
		},
		"oddCount": {
			"allOf": [
				{
					"$ref": "#/$defs/positiveSafeInteger"
				},
				{
					"type": "integer",
					"minimum": 3
				},
				{
					"not": {
						"type": "integer",
						"multipleOf": 2
					}
				}
			]
		},
		"sha256": {
			"type": "string",
			"pattern": "^[0-9a-f]{64}$"
		},
		"safeId": {
			"type": "string",
			"minLength": 1,
			"maxLength": 64,
			"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
		},
		"safeRelativeUrl": {
			"type": "string",
			"minLength": 1,
			"maxLength": 2048,
			"pattern": "^(?!/)(?![A-Za-z][A-Za-z0-9+.-]*:)(?!.*[\\\\?#])(?!.*(?:^|/)(?:\\.{1,2})(?:/|$))[^\\u0000-\\u001F\\u007F]+$"
		},
		"semver": {
			"type": "string",
			"pattern": "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$"
		},
		"base64": {
			"type": "string",
			"minLength": 1,
			"pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
		},
		"frameRate": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"numerator",
				"denominator"
			],
			"properties": {
				"numerator": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"denominator": {
					"$ref": "#/$defs/positiveSafeInteger"
				}
			}
		},
		"axis": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"param",
				"unit",
				"min",
				"max",
				"count",
				"wrap"
			],
			"properties": {
				"param": {
					"type": "string",
					"minLength": 1
				},
				"unit": {
					"type": "string",
					"minLength": 1
				},
				"min": {
					"type": "number"
				},
				"max": {
					"type": "number"
				},
				"count": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"wrap": {
					"type": "boolean"
				}
			}
		},
		"timeAxis": {
			"allOf": [
				{
					"$ref": "#/$defs/axis"
				},
				{
					"type": "object",
					"properties": {
						"param": {
							"const": "time"
						},
						"wrap": {
							"const": false
						}
					}
				}
			]
		},
		"tiltXAxis": {
			"allOf": [
				{
					"$ref": "#/$defs/axis"
				},
				{
					"type": "object",
					"properties": {
						"param": {
							"const": "tiltX"
						},
						"count": {
							"$ref": "#/$defs/oddCount"
						},
						"wrap": {
							"const": false
						}
					}
				}
			]
		},
		"tiltYAxis": {
			"allOf": [
				{
					"$ref": "#/$defs/axis"
				},
				{
					"type": "object",
					"properties": {
						"param": {
							"const": "tiltY"
						},
						"count": {
							"$ref": "#/$defs/oddCount"
						},
						"wrap": {
							"const": false
						}
					}
				}
			]
		},
		"azimuthAxis": {
			"allOf": [
				{
					"$ref": "#/$defs/axis"
				},
				{
					"type": "object",
					"properties": {
						"param": {
							"const": "azimuth"
						},
						"wrap": {
							"const": true
						}
					}
				}
			]
		},
		"elevationAxis": {
			"allOf": [
				{
					"$ref": "#/$defs/axis"
				},
				{
					"type": "object",
					"properties": {
						"param": {
							"const": "elevation"
						},
						"count": {
							"$ref": "#/$defs/oddCount"
						},
						"wrap": {
							"const": false
						}
					}
				}
			]
		},
		"camera": {
			"oneOf": [
				{
					"type": "object",
					"additionalProperties": false,
					"required": [
						"type",
						"radius",
						"near",
						"far",
						"orthoScale"
					],
					"properties": {
						"type": {
							"const": "orthographic"
						},
						"radius": {
							"$ref": "#/$defs/positiveNumber"
						},
						"near": {
							"$ref": "#/$defs/positiveNumber"
						},
						"far": {
							"$ref": "#/$defs/positiveNumber"
						},
						"orthoScale": {
							"$ref": "#/$defs/positiveNumber"
						}
					}
				},
				{
					"type": "object",
					"additionalProperties": false,
					"required": [
						"type",
						"radius",
						"near",
						"far",
						"fov"
					],
					"properties": {
						"type": {
							"const": "perspective"
						},
						"radius": {
							"$ref": "#/$defs/positiveNumber"
						},
						"near": {
							"$ref": "#/$defs/positiveNumber"
						},
						"far": {
							"$ref": "#/$defs/positiveNumber"
						},
						"fov": {
							"$ref": "#/$defs/positiveNumber"
						}
					}
				}
			]
		},
		"vector3": {
			"type": "array",
			"minItems": 3,
			"maxItems": 3,
			"prefixItems": [
				{
					"type": "number"
				},
				{
					"type": "number"
				},
				{
					"type": "number"
				}
			]
		},
		"bounds": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"center",
				"size",
				"radius"
			],
			"properties": {
				"center": {
					"$ref": "#/$defs/vector3"
				},
				"size": {
					"type": "array",
					"minItems": 3,
					"maxItems": 3,
					"prefixItems": [
						{
							"$ref": "#/$defs/positiveNumber"
						},
						{
							"$ref": "#/$defs/positiveNumber"
						},
						{
							"$ref": "#/$defs/positiveNumber"
						}
					]
				},
				"radius": {
					"$ref": "#/$defs/positiveNumber"
				}
			}
		},
		"albedoSemantics": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"colorSpace"
			],
			"properties": {
				"colorSpace": {
					"const": "srgb"
				}
			}
		},
		"depthSemantics": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"colorSpace",
				"range",
				"encoding",
				"near",
				"far",
				"depthScale",
				"parallaxScale"
			],
			"properties": {
				"colorSpace": {
					"const": "none"
				},
				"range": {
					"const": "full"
				},
				"encoding": {
					"const": "linear01"
				},
				"near": {
					"$ref": "#/$defs/positiveNumber"
				},
				"far": {
					"$ref": "#/$defs/positiveNumber"
				},
				"depthScale": {
					"$ref": "#/$defs/positiveNumber"
				},
				"parallaxScale": {
					"type": "number"
				},
				"frameRanges": {
					"type": "array",
					"minItems": 1,
					"maxItems": 100000,
					"items": {
						"$ref": "#/$defs/depthFrameRange"
					},
					"description": "Per-view actual occupied [minimum, maximum] ranges in camera-space world units. Occupied samples use codes 0-254; code 255 is the empty sentinel."
				}
			}
		},
		"depthFrameRange": {
			"type": "array",
			"minItems": 2,
			"maxItems": 2,
			"prefixItems": [
				{
					"$ref": "#/$defs/positiveNumber"
				},
				{
					"$ref": "#/$defs/positiveNumber"
				}
			],
			"items": false
		},
		"tracks": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"albedo"
			],
			"properties": {
				"albedo": {
					"$ref": "#/$defs/albedoSemantics"
				},
				"depth": {
					"$ref": "#/$defs/depthSemantics"
				}
			}
		},
		"pointer": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"tiltRange",
				"invertY",
				"ease"
			],
			"properties": {
				"tiltRange": {
					"$ref": "#/$defs/positiveNumber"
				},
				"invertY": {
					"type": "boolean"
				},
				"ease": {
					"type": "number",
					"minimum": 0,
					"maximum": 1
				}
			}
		},
		"frameIndexEntry": {
			"type": "array",
			"minItems": 3,
			"maxItems": 3,
			"prefixItems": [
				{
					"$ref": "#/$defs/safeInteger"
				},
				{
					"$ref": "#/$defs/positiveSafeInteger"
				},
				{
					"enum": [
						0,
						1
					]
				}
			]
		},
		"segment": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"firstFrame",
				"frameCount",
				"offset",
				"length",
				"sha256"
			],
			"properties": {
				"firstFrame": {
					"$ref": "#/$defs/safeInteger"
				},
				"frameCount": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"offset": {
					"$ref": "#/$defs/safeInteger"
				},
				"length": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"sha256": {
					"$ref": "#/$defs/sha256"
				}
			}
		},
		"indexedStream": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"codec",
				"gop",
				"frames",
				"segments"
			],
			"properties": {
				"codec": {
					"type": "string",
					"minLength": 1
				},
				"description": {
					"$ref": "#/$defs/base64"
				},
				"gop": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"frames": {
					"type": "array",
					"minItems": 1,
					"maxItems": 100000,
					"items": {
						"$ref": "#/$defs/frameIndexEntry"
					}
				},
				"segments": {
					"type": "array",
					"minItems": 1,
					"maxItems": 100000,
					"items": {
						"$ref": "#/$defs/segment"
					}
				}
			}
		},
		"albedoResource": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"file",
				"byteLength",
				"bodyByteLength",
				"sha256",
				"streams"
			],
			"properties": {
				"file": {
					"$ref": "#/$defs/safeRelativeUrl"
				},
				"byteLength": {
					"$ref": "#/$defs/positiveSafeInteger",
					"description": "Whole .af resource length including its embedded JSON manifest and 4-byte trailer."
				},
				"bodyByteLength": {
					"$ref": "#/$defs/activeFrameBodyByteLength",
					"description": "Encoded-body length and embedded-manifest offset stored by the .af trailer."
				},
				"sha256": {
					"$ref": "#/$defs/sha256"
				},
				"streams": {
					"type": "object",
					"additionalProperties": false,
					"required": [
						"color"
					],
					"properties": {
						"color": {
							"$ref": "#/$defs/indexedStream"
						},
						"alpha": {
							"$ref": "#/$defs/indexedStream"
						}
					}
				}
			}
		},
		"depthResource": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"file",
				"byteLength",
				"bodyByteLength",
				"sha256",
				"streams"
			],
			"properties": {
				"file": {
					"$ref": "#/$defs/safeRelativeUrl"
				},
				"byteLength": {
					"$ref": "#/$defs/positiveSafeInteger",
					"description": "Whole .af resource length including its embedded JSON manifest and 4-byte trailer."
				},
				"bodyByteLength": {
					"$ref": "#/$defs/activeFrameBodyByteLength",
					"description": "Encoded-body length and embedded-manifest offset stored by the .af trailer."
				},
				"sha256": {
					"$ref": "#/$defs/sha256"
				},
				"streams": {
					"type": "object",
					"additionalProperties": false,
					"required": [
						"depth"
					],
					"properties": {
						"depth": {
							"$ref": "#/$defs/indexedStream"
						}
					}
				}
			}
		},
		"rendition": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"id",
				"width",
				"height",
				"resources"
			],
			"properties": {
				"id": {
					"$ref": "#/$defs/safeId"
				},
				"width": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"height": {
					"$ref": "#/$defs/positiveSafeInteger"
				},
				"resources": {
					"type": "object",
					"additionalProperties": false,
					"required": [
						"albedo"
					],
					"properties": {
						"albedo": {
							"$ref": "#/$defs/albedoResource"
						},
						"depth": {
							"$ref": "#/$defs/depthResource"
						}
					}
				}
			}
		},
		"generator": {
			"type": "object",
			"description": "The sole extension point; generator-specific metadata is preserved.",
			"additionalProperties": true,
			"required": [
				"tool",
				"version",
				"projectVersion"
			],
			"properties": {
				"tool": {
					"type": "string",
					"minLength": 1
				},
				"version": {
					"$ref": "#/$defs/semver"
				},
				"projectVersion": {
					"$ref": "#/$defs/positiveSafeInteger"
				}
			}
		},
		"coarseResource": {
			"type": "object",
			"additionalProperties": false,
			"required": [
				"file",
				"byteLength",
				"sha256"
			],
			"properties": {
				"file": {
					"type": "string",
					"minLength": 1
				},
				"byteLength": {
					"type": "integer",
					"minimum": 1
				},
				"sha256": {
					"type": "string",
					"pattern": "^[0-9a-f]{64}$"
				}
			}
		}
	}
}
