{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://tango.oslo.no/schema/tango-event-submission.schema.json",
  "title": "Tangokalender event submission",
  "description": "One event, or an array with one object per date (up to 60). Times are Oslo local time. Use null for anything not stated in the source.",
  "definitions": {
    "datetime": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2}))?$"
    },
    "nok": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 0
    },
    "text": {
      "type": [
        "string",
        "null"
      ]
    },
    "url": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^https?://"
    },
    "day": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
    },
    "localtime": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}(:[0-9]{2})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$"
    },
    "event": {
      "type": "object",
      "required": [
        "title",
        "types",
        "start",
        "venue",
        "organizer",
        "link"
      ],
      "additionalProperties": false,
      "properties": {
        "$schema": {
          "type": "string"
        },
        "title": {
          "type": "string",
          "minLength": 1,
          "description": "Event name as written by the organiser."
        },
        "types": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "enum": [
              "milonga",
              "practica",
              "class",
              "workshop",
              "festival",
              "marathon",
              "outdoor",
              "other"
            ]
          },
          "description": "A list with one or more of the following (e.g. [\"class\", \"milonga\"] for a class followed by a milonga): class (class or course), workshop (workshop or seminar), milonga (social dance evening), practica (practice evening), festival (festival or multi-day event with workshops), marathon (multi-day, mostly social dancing), outdoor (open-air / outdoor event (utetango); combine with e.g. milonga), other (anything else)."
        },
        "status": {
          "enum": [
            "scheduled",
            "cancelled",
            null
          ],
          "description": "\"cancelled\" only if the source says the event is cancelled; otherwise omit."
        },
        "start": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}(:[0-9]{2})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$",
          "description": "Oslo local start time, \"YYYY-MM-DDTHH:MM\" (no time zone), or \"YYYY-MM-DD\" if no time is given."
        },
        "end": {
          "description": "Oslo local end time in the same format. If it ends after midnight, use the next day's date. null if not stated.",
          "allOf": [
            {
              "$ref": "#/definitions/localtime"
            }
          ]
        },
        "venue": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "name": {
              "$ref": "#/definitions/text"
            },
            "address": {
              "$ref": "#/definitions/text"
            },
            "city": {
              "$ref": "#/definitions/text"
            }
          },
          "required": [
            "name",
            "address"
          ],
          "description": "Where the event takes place."
        },
        "organizer": {
          "description": "Required. The organising group or person named in the source; if none is named, the page or profile that published the event (e.g. the Facebook event host).",
          "allOf": [
            {
              "$ref": "#/definitions/text"
            }
          ]
        },
        "dj": {
          "description": "DJ name(s) exactly as written in the source, or null.",
          "allOf": [
            {
              "$ref": "#/definitions/text"
            }
          ]
        },
        "teachers": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          },
          "description": "Teachers' names exactly as written in the source; [] if none."
        },
        "music_style": {
          "type": [
            "array",
            "null"
          ],
          "uniqueItems": true,
          "items": {
            "enum": [
              "traditional",
              "alternative",
              "live_orchestra"
            ]
          },
          "description": "Only if the source states it. Any of: alternative (alternative or neo tango), live_orchestra (live orchestra), traditional (traditional / golden-age tango)."
        },
        "price_nok": {
          "description": "Regular entry price in whole Norwegian kroner (integer), or null.",
          "allOf": [
            {
              "$ref": "#/definitions/nok"
            }
          ]
        },
        "student_price_nok": {
          "description": "Student/reduced price in whole NOK, or null.",
          "allOf": [
            {
              "$ref": "#/definitions/nok"
            }
          ]
        },
        "class_price_nok": {
          "description": "Price for the class/course part in whole NOK, or null. A price for a whole course or series of dates goes here (on every date), with the description saying what it covers.",
          "allOf": [
            {
              "$ref": "#/definitions/nok"
            }
          ]
        },
        "description": {
          "description": "1–3 short neutral sentences (level, entry, dress code), in the source's language if that is Norwegian or English, otherwise English. No marketing.",
          "allOf": [
            {
              "$ref": "#/definitions/text"
            }
          ]
        },
        "lang": {
          "enum": [
            "nb",
            "en",
            null
          ],
          "description": "Language of title and description: \"nb\" (Norwegian) or \"en\" (English)."
        },
        "translations": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": false,
          "properties": {
            "nb": {
              "type": "object",
              "additionalProperties": false,
              "minProperties": 1,
              "properties": {
                "title": {
                  "$ref": "#/definitions/text"
                },
                "description": {
                  "$ref": "#/definitions/text"
                }
              }
            },
            "en": {
              "type": "object",
              "additionalProperties": false,
              "minProperties": 1,
              "properties": {
                "title": {
                  "$ref": "#/definitions/text"
                },
                "description": {
                  "$ref": "#/definitions/text"
                }
              }
            },
            "es": {
              "type": "object",
              "additionalProperties": false,
              "minProperties": 1,
              "properties": {
                "title": {
                  "$ref": "#/definitions/text"
                },
                "description": {
                  "$ref": "#/definitions/text"
                }
              }
            }
          },
          "description": "Only if the source itself has the text in two languages: {\"en\": {\"title\", \"description\"}} for a Norwegian event, {\"nb\": …} for an English one. Never translate yourself; otherwise null."
        },
        "flyer_url": {
          "description": "Direct https URL of the event image, only if it appears in the source; otherwise null.",
          "allOf": [
            {
              "$ref": "#/definitions/url"
            }
          ]
        },
        "link": {
          "description": "URL of the event page (e.g. the Facebook event or the organiser's page).",
          "allOf": [
            {
              "$ref": "#/definitions/url"
            }
          ]
        },
        "video_url": {
          "description": "YouTube or Vimeo link from the source, or null.",
          "allOf": [
            {
              "$ref": "#/definitions/url"
            }
          ]
        }
      }
    }
  },
  "oneOf": [
    {
      "$ref": "#/definitions/event"
    },
    {
      "type": "array",
      "minItems": 1,
      "maxItems": 60,
      "items": {
        "$ref": "#/definitions/event"
      }
    }
  ]
}
