{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Local wallpaper package manifest v1",
  "description": "The manifest.json at the root of a local image or video wallpaper package. The importer must also check file existence, package boundaries, links, size, media decoding and rights coverage.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "id",
    "version",
    "title",
    "author",
    "license",
    "preview",
    "fallback",
    "renderer",
    "entry"
  ],
  "properties": {
    "schemaVersion": {
      "type": "integer",
      "const": 1
    },
    "id": {
      "description": "Stable lowercase package ID, separate from the display title.",
      "type": "string",
      "maxLength": 128,
      "pattern": "^[a-z0-9]+(?:[.-][a-z0-9]+)*(?![\\s\\S])"
    },
    "version": {
      "description": "Numeric major.minor.patch release version.",
      "type": "string",
      "maxLength": 32,
      "pattern": "^(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*)(?![\\s\\S])"
    },
    "title": {
      "$ref": "#/$defs/label"
    },
    "author": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name"],
      "properties": {
        "name": { "$ref": "#/$defs/label" }
      }
    },
    "license": {
      "description": "Package-relative JSON file that records attribution and usage, adaptation and distribution rights for every included asset.",
      "$ref": "#/$defs/relativePath",
      "pattern": "\\.json(?![\\s\\S])"
    },
    "preview": {
      "description": "Static PNG or JPEG shown in the library without starting the renderer.",
      "$ref": "#/$defs/imagePath"
    },
    "fallback": {
      "description": "Static PNG or JPEG displayed when the main resource cannot be used.",
      "$ref": "#/$defs/imagePath"
    },
    "renderer": {
      "enum": ["image", "video"]
    },
    "entry": {
      "description": "Main package-relative media file, with an extension allowed for the selected renderer.",
      "$ref": "#/$defs/relativePath"
    },
    "recommendedResolution": {
      "description": "Suggested display size in pixels. The importer checks decoded asset size separately.",
      "type": "object",
      "additionalProperties": false,
      "required": ["width", "height"],
      "properties": {
        "width": { "$ref": "#/$defs/dimension" },
        "height": { "$ref": "#/$defs/dimension" }
      }
    },
    "parameters": {
      "description": "Optional defaults for supported per-display controls. Omitted controls are not shown.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "fit": { "enum": ["fill", "fit"] },
        "playbackRate": { "type": "number", "minimum": 0.5, "maximum": 2 }
      }
    },
    "capabilities": {
      "description": "Optional signal declarations. Image and video packages receive no signal data in v1. System and agent data require separate user consent if a future renderer supports them.",
      "type": "array",
      "maxItems": 4,
      "uniqueItems": true,
      "items": { "enum": ["pointer", "clock", "system", "agent"] }
    }
  },
  "if": {
    "required": ["renderer"],
    "properties": { "renderer": { "const": "image" } }
  },
  "then": {
    "properties": {
      "entry": { "$ref": "#/$defs/imagePath" },
      "parameters": { "not": { "required": ["playbackRate"] } }
    }
  },
  "else": {
    "properties": {
      "entry": { "pattern": "\\.(?:mp4|mov|m4v)(?![\\s\\S])" }
    }
  },
  "$defs": {
    "label": {
      "type": "string",
      "maxLength": 120,
      "pattern": "\\S",
      "not": { "pattern": "[\\u0000-\\u001f\\u007f]" }
    },
    "relativePath": {
      "description": "Use slash-separated ASCII names. Segments start with a letter or digit. Dots separate name components.",
      "type": "string",
      "maxLength": 240,
      "pattern": "^(?:[A-Za-z0-9][A-Za-z0-9_-]*(?:\\.[A-Za-z0-9_-]+)*/)*[A-Za-z0-9][A-Za-z0-9_-]*(?:\\.[A-Za-z0-9_-]+)*(?![\\s\\S])"
    },
    "imagePath": {
      "$ref": "#/$defs/relativePath",
      "pattern": "\\.(?:png|jpe?g)(?![\\s\\S])"
    },
    "dimension": {
      "type": "integer",
      "minimum": 1,
      "maximum": 8192
    }
  }
}
