{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://video-effects.jingfu.design/effect.schema.json",
  "title": "Video Effects effect package manifest (effect.json)",
  "description": "The manifest at the root of an effect package (.zip), format 1. The package holds a shader (effect.glsl), a component (component.jsx, component.tsx, component.js, component.ts) or both, and any images and files they read.",
  "type": "object",
  "required": [
    "format",
    "name"
  ],
  "properties": {
    "$schema": {
      "type": "string"
    },
    "format": {
      "const": 1,
      "description": "This format's version."
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "description": {
      "type": "string",
      "maxLength": 500
    },
    "author": {
      "type": "string",
      "maxLength": 200
    },
    "version": {
      "type": "string",
      "maxLength": 40
    },
    "shader": {
      "type": "string",
      "description": "The shader's file; effect.glsl when there is one."
    },
    "component": {
      "type": "string",
      "description": "The component's file; the first of component.jsx, component.tsx, component.js, component.ts there is."
    },
    "parameters": {
      "type": "array",
      "maxItems": 24,
      "items": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "id",
              "type",
              "min",
              "max"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z][A-Za-z0-9_]{0,31}$",
                "description": "Its name in the shader (a uniform) and the component (a prop): a GLSL name, not a GLSL word, an input, a component prop or one starting gl_ or ve and a capital."
              },
              "label": {
                "type": "string",
                "maxLength": 60,
                "description": "What the card calls it; the id by default."
              },
              "description": {
                "type": "string",
                "maxLength": 300,
                "description": "The control's tooltip."
              },
              "type": {
                "const": "number"
              },
              "min": {
                "type": "number"
              },
              "max": {
                "type": "number"
              },
              "default": {
                "type": "number"
              },
              "step": {
                "type": "number",
                "exclusiveMinimum": 0
              },
              "unit": {
                "type": "string",
                "maxLength": 12
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z][A-Za-z0-9_]{0,31}$",
                "description": "Its name in the shader (a uniform) and the component (a prop): a GLSL name, not a GLSL word, an input, a component prop or one starting gl_ or ve and a capital."
              },
              "label": {
                "type": "string",
                "maxLength": 60,
                "description": "What the card calls it; the id by default."
              },
              "description": {
                "type": "string",
                "maxLength": 300,
                "description": "The control's tooltip."
              },
              "type": {
                "const": "boolean"
              },
              "default": {
                "type": "boolean"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type",
              "choices"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z][A-Za-z0-9_]{0,31}$",
                "description": "Its name in the shader (a uniform) and the component (a prop): a GLSL name, not a GLSL word, an input, a component prop or one starting gl_ or ve and a capital."
              },
              "label": {
                "type": "string",
                "maxLength": 60,
                "description": "What the card calls it; the id by default."
              },
              "description": {
                "type": "string",
                "maxLength": 300,
                "description": "The control's tooltip."
              },
              "type": {
                "const": "choice"
              },
              "choices": {
                "type": "array",
                "minItems": 2,
                "maxItems": 12,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 40
                }
              },
              "default": {
                "oneOf": [
                  {
                    "type": "integer",
                    "minimum": 0
                  },
                  {
                    "type": "string"
                  }
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z][A-Za-z0-9_]{0,31}$",
                "description": "Its name in the shader (a uniform) and the component (a prop): a GLSL name, not a GLSL word, an input, a component prop or one starting gl_ or ve and a capital."
              },
              "label": {
                "type": "string",
                "maxLength": 60,
                "description": "What the card calls it; the id by default."
              },
              "description": {
                "type": "string",
                "maxLength": 300,
                "description": "The control's tooltip."
              },
              "type": {
                "enum": [
                  "colour",
                  "color"
                ]
              },
              "default": {
                "type": "string",
                "pattern": "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "id",
              "type"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z][A-Za-z0-9_]{0,31}$",
                "description": "Its name in the shader (a uniform) and the component (a prop): a GLSL name, not a GLSL word, an input, a component prop or one starting gl_ or ve and a capital."
              },
              "label": {
                "type": "string",
                "maxLength": 60,
                "description": "What the card calls it; the id by default."
              },
              "description": {
                "type": "string",
                "maxLength": 300,
                "description": "The control's tooltip."
              },
              "type": {
                "const": "text"
              },
              "default": {
                "type": "string"
              },
              "maxLength": {
                "type": "integer",
                "minimum": 1,
                "maximum": 500
              },
              "multiline": {
                "type": "boolean"
              }
            }
          }
        ]
      }
    },
    "images": {
      "type": "array",
      "maxItems": 3,
      "items": {
        "type": "object",
        "required": [
          "name",
          "file"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_]{0,31}$",
            "description": "The sampler2D's name in the shader."
          },
          "file": {
            "type": "string",
            "pattern": "\\.(png|jpe?g|webp)$"
          },
          "filter": {
            "enum": [
              "linear",
              "nearest"
            ]
          },
          "wrap": {
            "enum": [
              "clamp",
              "repeat",
              "mirror"
            ]
          }
        }
      }
    }
  }
}
