{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://studio.schemary.iglooshen.fun/project.schema.json",
  "title": "Schemary project file",
  "description": "Structural file contract. Import also checks graph references, default group/scenario and adapter capabilities.",
  "type": "object",
  "required": [
    "format",
    "metadata",
    "manifest",
    "flow"
  ],
  "properties": {
    "format": {
      "const": "flow-studio-project-export/v1"
    },
    "metadata": {
      "type": "object",
      "required": [
        "title"
      ],
      "properties": {
        "title": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "description": {
          "type": "string",
          "maxLength": 500
        }
      }
    },
    "manifest": {
      "type": "object",
      "required": [
        "format",
        "adapter",
        "defaultGroup",
        "defaultScenario"
      ],
      "properties": {
        "format": {
          "const": "flow-studio-project/v1"
        },
        "adapter": {
          "enum": [
            "generic"
          ]
        },
        "source": {
          "type": "string"
        },
        "defaultGroup": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "defaultScenario": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "display": {
          "$ref": "#/$defs/display"
        }
      }
    },
    "flow": {
      "type": "object",
      "required": [
        "schemaVersion",
        "defaults",
        "screens",
        "actions",
        "conditions",
        "effects",
        "groups",
        "scenarios"
      ],
      "properties": {
        "schemaVersion": {
          "const": 2
        },
        "version": {
          "type": "string"
        },
        "entry": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "defaults": {
          "type": "object"
        },
        "screens": {
          "type": "object",
          "minProperties": 1,
          "propertyNames": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
          },
          "additionalProperties": {
            "$ref": "#/$defs/screen"
          }
        },
        "fixed": {
          "type": "object"
        },
        "actions": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/action"
          }
        },
        "conditions": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        },
        "effects": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        },
        "conditionValues": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/condition"
          }
        },
        "effectValues": {
          "type": "object",
          "additionalProperties": {
            "type": "object"
          }
        },
        "tasks": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "required": [
              "title",
              "outcomes"
            ],
            "properties": {
              "title": {
                "type": "string"
              },
              "effect": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "outcomes": {
                "type": "object",
                "additionalProperties": {
                  "$ref": "#/$defs/action"
                }
              }
            }
          }
        },
        "events": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "required": [
              "title",
              "routes"
            ],
            "properties": {
              "title": {
                "type": "string"
              },
              "routes": {
                "type": "array",
                "items": {
                  "$ref": "#/$defs/action"
                }
              }
            }
          }
        },
        "conditionNodes": {
          "type": "object"
        },
        "shared": {
          "type": "object"
        },
        "sharedContent": {
          "type": "object"
        },
        "groups": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "required": [
              "id",
              "title",
              "screens",
              "main"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "title": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "screens": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                }
              },
              "main": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                }
              }
            }
          }
        },
        "scenarios": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "required": [
              "id",
              "title",
              "entry",
              "state"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "title": {
                "type": "string"
              },
              "entry": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "state": {
                "type": "object"
              },
              "taskResults": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                }
              }
            }
          }
        },
        "uncovered": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "deferred": {
          "type": "array"
        },
        "effectCopies": {
          "type": "object",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
            }
          }
        },
        "effectLists": {
          "type": "object",
          "additionalProperties": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "required": [
                "field",
                "operation"
              ],
              "properties": {
                "field": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                },
                "operation": {
                  "enum": [
                    "append",
                    "update",
                    "remove"
                  ]
                },
                "key": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                },
                "selectedField": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                },
                "item": {
                  "type": "object",
                  "additionalProperties": {
                    "oneOf": [
                      {
                        "type": [
                          "string",
                          "number",
                          "boolean",
                          "null"
                        ]
                      },
                      {
                        "type": "object",
                        "required": [
                          "from"
                        ],
                        "properties": {
                          "from": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                          }
                        },
                        "additionalProperties": false
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "testCases": {
          "type": "array",
          "maxItems": 50,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "title",
              "scenario",
              "steps"
            ],
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "scenario": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "steps": {
                "type": "array",
                "minItems": 1,
                "maxItems": 100,
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type",
                        "blockId"
                      ],
                      "properties": {
                        "type": {
                          "const": "click"
                        },
                        "blockId": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "accepted": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type",
                        "blockId",
                        "value"
                      ],
                      "properties": {
                        "type": {
                          "const": "input"
                        },
                        "blockId": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "value": {
                          "type": [
                            "string",
                            "number",
                            "boolean",
                            "null"
                          ]
                        },
                        "accepted": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type",
                        "taskId",
                        "outcome"
                      ],
                      "properties": {
                        "type": {
                          "const": "taskResult"
                        },
                        "taskId": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "outcome": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "accepted": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type",
                        "eventId"
                      ],
                      "properties": {
                        "type": {
                          "const": "event"
                        },
                        "eventId": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "accepted": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type"
                      ],
                      "properties": {
                        "type": {
                          "const": "back"
                        },
                        "accepted": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type"
                      ],
                      "properties": {
                        "type": {
                          "const": "dismiss"
                        },
                        "accepted": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "type"
                      ],
                      "properties": {
                        "type": {
                          "const": "assert"
                        },
                        "page": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "base": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                        },
                        "layers": {
                          "type": "array",
                          "maxItems": 4,
                          "items": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
                          }
                        },
                        "state": {
                          "type": "object"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "anyOf": [
                        {
                          "required": [
                            "page"
                          ]
                        },
                        {
                          "required": [
                            "base"
                          ]
                        },
                        {
                          "required": [
                            "layers"
                          ]
                        },
                        {
                          "required": [
                            "state"
                          ]
                        },
                        {
                          "required": [
                            "errors"
                          ]
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "$defs": {
    "block": {
      "type": "object",
      "required": [
        "id",
        "type"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "type": {
          "enum": [
            "text",
            "heading",
            "placeholder",
            "note",
            "action",
            "field",
            "select",
            "choice",
            "toggle",
            "stack",
            "row",
            "group",
            "card",
            "list",
            "list-row",
            "navigation",
            "toolbar",
            "tabbar",
            "image",
            "repeat",
            "segmented",
            "accordion",
            "feedback"
          ]
        },
        "text": {
          "type": "string"
        },
        "action": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "when": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "enabled": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "field": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "label": {
          "type": "string",
          "minLength": 1
        },
        "inputType": {
          "enum": [
            "text",
            "number",
            "date",
            "textarea"
          ]
        },
        "layout": {
          "enum": [
            "stack",
            "inline",
            "grid",
            "list"
          ]
        },
        "required": {
          "type": "boolean"
        },
        "readonly": {
          "type": "boolean"
        },
        "hint": {
          "type": "string"
        },
        "placeholder": {
          "type": "string"
        },
        "min": {
          "type": "number"
        },
        "max": {
          "type": "number"
        },
        "maxLength": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10000
        },
        "onChange": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "options": {
          "type": "array",
          "minItems": 1,
          "maxItems": 100,
          "items": {
            "type": "object",
            "required": [
              "value",
              "label"
            ],
            "properties": {
              "value": {
                "type": [
                  "string",
                  "number"
                ]
              },
              "label": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "when": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              }
            }
          }
        },
        "step": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "filterField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "reverseWhen": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "selectedWhen": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "selectedField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "itemsField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "itemKey": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "sortField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "pageField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "expandedField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "progressField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "onSelect": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "children": {
          "type": "array",
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/block"
          }
        },
        "gap": {
          "enum": [
            "none",
            "small",
            "medium",
            "large"
          ]
        },
        "align": {
          "enum": [
            "start",
            "center",
            "end",
            "stretch",
            "between"
          ]
        },
        "slot": {
          "enum": [
            "leading",
            "trailing"
          ]
        },
        "emphasis": {
          "enum": [
            "primary",
            "secondary",
            "danger"
          ]
        },
        "labelDisplay": {
          "enum": [
            "icon",
            "text",
            "both"
          ]
        },
        "icon": {
          "enum": [
            "back",
            "close",
            "more",
            "add",
            "search",
            "filter",
            "grid",
            "list",
            "home",
            "settings",
            "check",
            "chevron-right",
            "share",
            "trash",
            "bookmark",
            "arrow-left",
            "arrow-right",
            "download",
            "refresh"
          ]
        },
        "aspect": {
          "enum": [
            "square",
            "portrait",
            "landscape",
            "wide"
          ]
        },
        "alt": {
          "type": "string"
        },
        "src": {
          "type": "string",
          "pattern": "^https://",
          "maxLength": 2048
        },
        "mode": {
          "enum": [
            "grid",
            "list",
            "carousel"
          ]
        },
        "pageSize": {
          "type": "integer",
          "minimum": 1,
          "maximum": 50
        },
        "emptyText": {
          "type": "string"
        },
        "searchFields": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
          },
          "minItems": 1
        },
        "filterBy": {
          "type": "object",
          "required": [
            "stateField",
            "itemField"
          ],
          "properties": {
            "stateField": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
            },
            "itemField": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
            }
          }
        },
        "sorts": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "value",
              "key",
              "direction"
            ],
            "properties": {
              "value": {
                "type": [
                  "string",
                  "number"
                ]
              },
              "key": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
              },
              "direction": {
                "enum": [
                  "asc",
                  "desc"
                ]
              }
            }
          }
        },
        "variant": {
          "enum": [
            "loading",
            "progress",
            "empty",
            "error",
            "toast"
          ]
        },
        "blocking": {
          "type": "boolean"
        },
        "srcField": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "sharedSnapshots": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        }
      }
    },
    "screen": {
      "type": "object",
      "required": [
        "title",
        "blocks"
      ],
      "properties": {
        "title": {
          "type": "string"
        },
        "blocks": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/block"
          }
        },
        "back": {
          "oneOf": [
            {
              "type": "boolean"
            },
            {
              "type": "string"
            },
            {
              "$ref": "#/$defs/action"
            }
          ]
        },
        "hideBack": {
          "type": "boolean"
        },
        "terminal": {
          "type": "boolean",
          "description": "Explicit end screen; suppresses the no-outlet warning, not other checks."
        },
        "regions": {
          "type": "object",
          "properties": {
            "top": {
              "type": "object",
              "required": [
                "blocks"
              ],
              "properties": {
                "placement": {
                  "enum": [
                    "fixed",
                    "scroll"
                  ]
                },
                "blocks": {
                  "type": "array",
                  "maxItems": 500,
                  "items": {
                    "$ref": "#/$defs/block"
                  }
                }
              },
              "additionalProperties": false
            },
            "bottom": {
              "type": "object",
              "required": [
                "blocks"
              ],
              "properties": {
                "placement": {
                  "enum": [
                    "fixed",
                    "scroll"
                  ]
                },
                "blocks": {
                  "type": "array",
                  "maxItems": 500,
                  "items": {
                    "$ref": "#/$defs/block"
                  }
                }
              },
              "additionalProperties": false
            }
          },
          "additionalProperties": false
        },
        "presentation": {
          "enum": [
            "standard",
            "onboarding",
            "sheet",
            "dialog",
            "menu"
          ]
        },
        "dismissible": {
          "type": "boolean"
        }
      }
    },
    "action": {
      "type": "object",
      "oneOf": [
        {
          "required": [
            "to"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "present"
                ]
              },
              {
                "required": [
                  "dismiss"
                ]
              },
              {
                "required": [
                  "stay"
                ]
              },
              {
                "required": [
                  "routes"
                ]
              },
              {
                "required": [
                  "task"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "present"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "to"
                ]
              },
              {
                "required": [
                  "dismiss"
                ]
              },
              {
                "required": [
                  "stay"
                ]
              },
              {
                "required": [
                  "routes"
                ]
              },
              {
                "required": [
                  "task"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "dismiss"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "to"
                ]
              },
              {
                "required": [
                  "present"
                ]
              },
              {
                "required": [
                  "stay"
                ]
              },
              {
                "required": [
                  "routes"
                ]
              },
              {
                "required": [
                  "task"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "stay"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "to"
                ]
              },
              {
                "required": [
                  "present"
                ]
              },
              {
                "required": [
                  "dismiss"
                ]
              },
              {
                "required": [
                  "routes"
                ]
              },
              {
                "required": [
                  "task"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "routes"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "to"
                ]
              },
              {
                "required": [
                  "present"
                ]
              },
              {
                "required": [
                  "dismiss"
                ]
              },
              {
                "required": [
                  "stay"
                ]
              },
              {
                "required": [
                  "task"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "task"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "to"
                ]
              },
              {
                "required": [
                  "present"
                ]
              },
              {
                "required": [
                  "dismiss"
                ]
              },
              {
                "required": [
                  "stay"
                ]
              },
              {
                "required": [
                  "routes"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "origin"
          ]
        }
      ],
      "properties": {
        "origin": {
          "const": true
        },
        "restoreState": {
          "type": "boolean"
        },
        "fallback": {
          "type": "string"
        },
        "automatic": {
          "type": "boolean"
        },
        "to": {
          "type": "string"
        },
        "task": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "cancelTasks": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "guard": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "effect": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "routes": {
          "type": "array",
          "minItems": 2,
          "items": {
            "$ref": "#/$defs/action"
          }
        },
        "validate": {
          "type": "boolean"
        },
        "present": {
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
        },
        "dismiss": {
          "const": true
        },
        "stay": {
          "const": true
        }
      }
    },
    "condition": {
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "object",
          "required": [
            "all"
          ],
          "properties": {
            "all": {
              "type": "array",
              "minItems": 1,
              "maxItems": 32,
              "items": {
                "$ref": "#/$defs/condition"
              }
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "any"
          ],
          "properties": {
            "any": {
              "type": "array",
              "minItems": 1,
              "maxItems": 32,
              "items": {
                "$ref": "#/$defs/condition"
              }
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "not"
          ],
          "properties": {
            "not": {
              "$ref": "#/$defs/condition"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "object",
          "required": [
            "key"
          ],
          "minProperties": 2,
          "maxProperties": 2,
          "properties": {
            "key": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$"
            },
            "equals": {},
            "notEquals": {},
            "present": {
              "type": "boolean"
            },
            "gt": {
              "type": "number"
            },
            "gte": {
              "type": "number"
            },
            "lt": {
              "type": "number"
            },
            "lte": {
              "type": "number"
            }
          },
          "additionalProperties": false
        }
      ]
    },
    "display": {
      "type": "object",
      "required": [
        "type"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "enum": [
            "phone",
            "tablet",
            "desktop",
            "web"
          ]
        },
        "orientation": {
          "enum": [
            "portrait",
            "landscape"
          ],
          "deprecated": true,
          "description": "仅兼容早期文件；读取时忽略。方向由应用类型固定：手机竖屏，其余横屏。"
        }
      },
      "description": "仅在创建独立项目时确认应用类型；已有项目更新时须保留。"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "manifest": {
            "properties": {
              "adapter": {
                "const": "generic"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "flow": {
            "required": [
              "conditionValues",
              "effectValues",
              "entry"
            ],
            "properties": {
              "defaults": {
                "required": [
                  "state"
                ],
                "properties": {
                  "state": {
                    "type": "object"
                  }
                }
              }
            }
          }
        }
      }
    }
  ]
}
